Invoking Hyper-V WMI API methods with reference parameters using WS-Management

Invoking Hyper-V WMI API methods with reference parameters using WS-Management

Hi !

I want to write down my experiences with invoking Hyper-V API methods using WS-Management tools (or wsman for short), such as WinRM, which is part of the Windows Remote Mangement Framework. The goal is, to call the Hyper-V API method GetSummaryInformation for a specific virtual machine and to get only informations, requested during the method call. This post will assume you have Windows Server 2008 R2 with configured and running WinRM. Additionally, WinRM will be used from a second machine as the WS-Management client.

General method invocation using WS-Management

Invocation of methods exposed using WS-Management follows a simple mechanism. The header of the invoke message contains the endpoint reference, were the method has te be invoked, plus the method name. The body contains the parameters for the methods, encoded in a simple [MethodeName]_INPUT block. Here is an example of the header of a method invocation message, with just the relevant header fields.

<s:envelop ...>
 <s:header ...>
 ...
 <ResourceURI s:mustUnderstand="true">http://schemas.microsoft.com/wbem/wsman/1/wmi/root/virtualization/Msvm_VirtualSystemManagementService</w:ResourceURI>
 <a:Action s:mustUnderstand="true">http://schemas.microsoft.com/wbem/wsman/1/wmi/root/virtualization/Msvm_VirtualSystemManagementService/GetSummaryInformation</a:Action>
 <SelectorSet>
  <w:Selector Name="CreationClassName">Msvm_VirtualSystemManagementService</w:Selector>
  <w:Selector Name="Name">vmms</w:Selector><w:Selector Name="SystemCreationClassName">Msvm_ComputerSystem</w:Selector>
  <w:Selector Name="SystemName">HYPERV-1</w:Selector>
 </w:SelectorSet>
 ...
</s:header>
<s:body>
 <p:GetSummaryInformation_INPUT xmlns:p="http://schemasmicrosoftcom/wbem/wsman/1/wmi/root/virtualization/Msvm_VirtualSystemManagementService">
 ...
 </p:GetSummaryInformation_INPUT>
</s:envelop>

Using WinRM, a method invocation is issued by winrm invoke [MethodName] [ResourceURI] -file:[ParameterFile.xml]

We use a xml file for parameter delivery here. because dealing with references introduces large parameter strings, where it is more convenient, to write those things in a file and just use instruct WinRM to use this file for the parameters. Actually, the content of this file is just pasted inside the method invocation message at the right position (inside the body).

Signature of GetSummaryInformation

First we want to look at the signature of GetSummaryInformation. The first input parameter is an array of references of CIM_VirtualSystemSettingData instances, the second input parameter is an array of integers, indicating which informations wanted to be retrieved.

uint32 GetSummaryInformation( [in] CIM_VirtualSystemSettingData REF SettingData[], [in] uint32 RequestedInformation[], [out] Msvm_SummaryInformation SummaryInformation[] ); 

Parameter arrays in WS-Management

First question is, how the encode an array of values. Let’s look at the second parameter array first, because it is more easy. RequestedInformation is an array of uint32. Arrays are encoded by just writing an element multiple times. For example, the have an array RequestedInformation with three elements 1,2 and 4, one would write the following

<p:RequestedInformation>1</p:RequestedInformation>
<p:RequestedInformation>2</p:RequestedInformation>
<p:RequestedInformation>4</p:RequestedInformation>

Easy, huh 🙂

References as parameters

What about that REF parameter array, which indicates, for which virtual machines one would like the get informations. Since the array has to contain references, we need endpoint references (EPRs) pointing to the actual instances of CIM_VirtualSystemSettingData, for which we want to retrieve informations. To get these EPR, enumerate the according instances using WinRM, but with the special command line parameter -ReturnType:EPR

There are two additional parameters of interest. First, the -Shallow parameter permits the listing of instances of child classes. This is a good idea, because we are only interested in instances of exactly this class. Second, since we want to use the given informations to write our parameter xml file, the output of a xml file would be nice, so that we simply can copy and paste the output to our own xml file later on. This can be achieved by -format:pretty.

Here is the command line for enumerating all instances of Msvm_VirtualSystemSettingData (which is a subclass of CIM_VirtualSystemSettingData and in fact what we want), and only instances and generating a nice xml output.

winrm enumerate http://schemas.microsoft.com/wbem/wsman/1/wmi/root/virtualization/Msvm_VirtualSystemSettingData -Shallow -ReturnType:EPR -format:pretty

The output should look similar to this

<a:EndpointReference xml:lang="en-US" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd">
 <a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address>
 <a:ReferenceParameters>
  <w:ResourceURI>http://schemas.microsoft.com/wbem/wsman/1/wmi/root/virtualization/Msvm_VirtualSystemSettingData</w:ResourceURI >
  <w:SelectorSet>
   <w:Selector Name="InstanceID">Microsoft:4DA77B7B-7F11-4735-A18F-46B57D2438C7</w:Selector>
  </w:SelectorSet>
 </a:ReferenceParameters>
</a:EndpointReference>

<a:EndpointReference xml:lang="en-US" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd">
 <a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address>
 <a:ReferenceParameters>
  <w:ResourceURI>http://schemas.microsoft.com/wbem/wsman/1/wmi/root/virtualization/Msvm_VirtualSystemSettingData</w:ResourceURI>
  <w:SelectorSet>
   <w:Selector Name="InstanceID">Microsoft:9221DB03-BC5F-4485-8BDF-0206C093AC58</w:Selector>
  </w:SelectorSet>
 </a:ReferenceParameters>
</a:EndpointReference>

Now, the final question is, how to encode these EPRs into the method parameters. According to the WS-CIM Mapping Specification Version 1.0.1 (DSP0230) chapter 8.2 CIM References

[…] the xs:any element [which is in fact our reference parameter] shall be replaced by the required wsa:EndpointReference child elements defined by Addressing recommendations, as if the property element were of type wsa:EndpointReferenceType. […]

How the EndpointReferenceType actually looks like can be seen in the output of the WinRM output above, which gives the EPRs for the Msvm_VirtualSystemSettingData instances. The DSP0230 stated, the parameter of a method, if it is a reference, should behave as if it is from Type EndpointReferenceType, in fact by having elements as this type has. So our reference parameter would look like this.

<p:SettingData>
 <a:Address xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing">http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address>
 <a:ReferenceParameters xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd">
  <w:ResourceURI>http://schemas.microsoft.com/wbem/wsman/1/wmi/root/virtualization/Msvm_VirtualSystemSettingData</w:ResourceURI>
  <w:SelectorSet>
   <w:Selector Name="InstanceID">Microsoft:4DA77B7B-7F11-4735-A18F-46B57D2438C7</w:Selector>
  </w:SelectorSet>
 </a:ReferenceParameters>
</p:SettingData>

To get an array of this, just write them successive as mentioned before.

Build the parameter input file

Let’s put everything together and build the parameter file to call GetSummaryInformation for two virtual machines. We want to get specific informations from two virtual machines running on a Windows Server 2008 R2 host called HYPERV-1. We got the EPRs for the Msvm_VirtualSystemSettingData instances using WinRM enumerate (look at the section References as parameters). We want to get the following informations from that virtual machines

  • ElementName
  • NumberOfProcessors
  • EnabledState
  • Uptime

These correspond to the uint32 values 1,4,101 and 105. So our parameter input xml file looks as follows.

<p:GetSummaryInformation_INPUT xmlns:p="http://schemas.microsoft.com/wbem/wsman/1/wmi/root/virtualization/Msvm_VirtualSystemManagementService">

 <p:SettingData>
  <a:Address xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing">http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address>
  <a:ReferenceParameters xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd">
   <w:ResourceURI>http://schemas.microsoft.com/wbem/wsman/1/wmi/root/virtualization/Msvm_VirtualSystemSettingData</w:ResourceURI>
   <w:SelectorSet>
    <w:Selector Name="InstanceID">Microsoft:4DA77B7B-7F11-4735-A18F-46B57D2438C7</w:Selector>
   </w:SelectorSet>
  </a:ReferenceParameters>
 </p:SettingData>

 <p:SettingData>
  <a:Address xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing">http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address>
  <a:ReferenceParameters xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd">
   <w:ResourceURI>http://schemas.microsoft.com/wbem/wsman/1/wmi/root/virtualization/Msvm_VirtualSystemSettingData</w:ResourceURI>
   <w:SelectorSet>
    <w:Selector Name="InstanceID">Microsoft:9221DB03-BC5F-4485-8BDF-0206C093AC58</w:Selector>
   </w:SelectorSet>
  </a:ReferenceParameters>
 </p:SettingData>

 <p:RequestedInformation>1</p:RequestedInformation>
 <p:RequestedInformation>4</p:RequestedInformation>
 <p:RequestedInformation>101</p:RequestedInformation>
 <p:RequestedInformation>105</p:RequestedInformation>

</p:GetSummaryInformation_INPUT>

Let’s get the job done

First we need an instance of the Msvm_VirtualSystemManagementService on which to invoke the method on. To get this, just enumerate all instances (there should only be one) and grab the EPR. If you don’t know how to get the EPR, please look at the section References as parameters, or for the lazy ones, here is the appropriate WinRM command line

winrm enumerate http://schemas.microsoft.com/wbem/wsman/1/wmi/root/virtualization/Msvm_VirtualSystemManagementService -ReturnType:EPR

This should give something like this.

EndpointReference
 Address = http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
 ReferenceParameters
  ResourceURI = http://schemas.microsoft.com/wbem/wsman/1/wmi/root/virtualization/Msvm_VirtualSystemManagementService
  SelectorSet
   Selector: CreationClassName = Msvm_VirtualSystemManagementService, Name = vmms, SystemCreationClassName = Msvm_ComputerSystem, SystemName = HYPERV-1

If you compare this output to that of -format:pretty, we get plain text, instead of xml. Due to the fact, that we have to build the resource URI in a way, xml would not help, it is irrelevant at this point, how the output is formated.

Now we need to build the mentioned resource URI, which is in fact just the EPR of the instance of the Msvm_VirtualSystemManagementService class in another notation, which corresponds to parameter encoding in URIs, but with a “+” as a seperator instead of a “&” as known from parameters for scripts on websites. So, the complete EPR encoded as an URI is

http://schemas.microsoft.com/wbem/wsman/1/wmi/root/virtualization/Msvm_VirtualSystemManagementService?CreationClassName=Msvm_VirtualSystemManagementService+Name=vmms+SystemCreationClassName=Msvm_ComputerSystem+SystemName=HYPERV-1

The complete command line to invoke GetSummaryInformations (from a different host, by using basic authentication, which has to be enabled first) is

winrm invoke GetSummaryInformation http://schemas.microsoft.com/wbem/wsman/1/wmi/root/virtualization/Msvm_VirtualSystemManagementService?CreationClassName=Msvm_VirtualSystemManagementService+Name=vmms+SystemCreationClassName=Msvm_ComputerSystem+SystemName=HYPERV-1 -file:input.xml -r:ip_or_hostname:port -a:Basic -u:Administrator -p:your_password

This should lead to an output similar to this

GetSummaryInformation_OUTPUT
 SummaryInformation
  CreationTime = null
  ElementName = Fedora11-1
  EnabledState = null
  GuestOperatingSystem = null
  HealthState = null
  Heartbeat = null
  MemoryUsage = null
  Name = null
  Notes = null
  NumberOfProcessors = 1
  ProcessorLoad = 0
  UpTime = 45639247
 SummaryInformation
  CreationTime = null
  ElementName = Debian-1
  EnabledState = null
  GuestOperatingSystem = null
  HealthState = null
  Heartbeat = null
  MemoryUsage = null
  Name = null
  Notes = null
  NumberOfProcessors = 1
  ProcessorLoad = null
  UpTime = 0
  ReturnValue = 0

Appendix A — The complete invocation message for GetSummaryInformation

<s:Envelope xmlns:s="http://wwww3org/2003/05/soap-envelope"
            xmlns:a="http://schemas.xmlsoaporg/ws/2004/08/addressing"
            xmlns:w="http://schemas.dmtforg/wbem/wsman/1/wsmanxsd"
            xmlns:p="http://schemas.microsoftcom/wbem/wsman/1/wsmanxsd">
 <s:Header>
  <a:To>http://192.168.1.7:5985/wsman</a:To>
  <w:ResourceURI s:mustUnderstand="true">http://schemas.microsoft.com/wbem/wsman/1/wmi/root/virtualization/Msvm_VirtualSystemManagementService</w:ResourceURI>
  <a:ReplyTo>
   <a:Address s:mustUnderstand="true">http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address>
  </a:ReplyTo>
  <a:Action s:mustUnderstand="true">http://schemas.microsoft.com/wbem/wsman/1/wmi/root/virtualization/Msvm_VirtualSystemManagementService/GetSummaryInformation</a:Action>
  <w:MaxEnvelopeSize s:mustUnderstand="true">153600</w:MaxEnvelopeSize>
  <a:MessageID>uuid:C574798F-0160-4956-B00C-85EED13CF0B7</a:MessageID>
  <w:Locale xml:lang="en-US" s:mustUnderstand="false" />
  <p:DataLocale xml:lang="en-US" s:mustUnderstand="false" />
  <w:SelectorSet>
   <w:Selector Name="CreationClassName">Msvm_VirtualSystemManagementService</w:Selector>
   <w:Selector Name="Name">vmms</w:Selector><w:Selector Name="SystemCreationClassName">Msvm_ComputerSystem</w:Selector>
   <w:Selector Name="SystemName">HYPERV-1</w:Selector>
  </w:SelectorSet>
  <w:OperationTimeout>PT60000S</w:OperationTimeout>
 </s:Header>
 <s:Body>
  <p:GetSummaryInformation_INPUT xmlns:p="http://schemasmicrosoftcom/wbem/wsman/1/wmi/root/virtualization/Msvm_VirtualSystemManagementService">
   <p:SettingData xmlns:a="http://schemasxmlsoaporg/ws/2004/08/addressing" xmlns:w="http://schemasdmtforg/wbem/wsman/1/wsmanxsd">
    <a:Address>http://schemasxmlsoaporg/ws/2004/08/addressing/role/anonymous</a:Address>
    <a:ReferenceParameters>
     <w:ResourceURI>http://schemasmicrosoftcom/wbem/wsman/1/wmi/root/virtualization/Msvm_VirtualSystemSettingData</w:ResourceURI>
     <w:SelectorSet>
      <w:Selector Name="InstanceID">Microsoft:4DA77B7B-7F11-4735-A18F-46B57D2438C7</w:Selector>
     </w:SelectorSet>
    </a:ReferenceParameters>
   </p:SettingData>
   <p:SettingData xmlns:a="http://schemasxmlsoaporg/ws/2004/08/addressing" xmlns:w="http://schemasdmtforg/wbem/wsman/1/wsmanxsd">
    <a:Address>http://schemasxmlsoaporg/ws/2004/08/addressing/role/anonymous</a:Address>
    <a:ReferenceParameters>
     <w:ResourceURI>http://schemasmicrosoftcom/wbem/wsman/1/wmi/root/virtualization/Msvm_VirtualSystemSettingData</w:ResourceURI>
     <w:SelectorSet>
      <w:Selector Name="InstanceID">Microsoft:9221DB03-BC5F-4485-8BDF-0206C093AC58</w:Selector>
     </w:SelectorSet>
    </a:ReferenceParameters>
   </p:SettingData>
   <p:RequestedInformation>1</p:RequestedInformation>
   <p:RequestedInformation>4</p:RequestedInformation>
   <p:RequestedInformation>101</p:RequestedInformation>
   <p:RequestedInformation>105</p:RequestedInformation>
  </p:GetSummaryInformation_INPUT>
 </s:Body>
</s:Envelope>

Links

[1] MSDN reference for GetSummaryInformation — http://msdn.microsoft.com/en-us/library/cc160706%28VS.85%29.aspx

[2] WS-CIM Mapping Specification (DSP0230) — http://www.dmtf.org/standards/wsman

Invoking Hyper-V WMI API methods with reference parameters using WS-Management