First published on TECHNET on May 06, 2008
In part 1 we went over basic scripts and tools for gathering some generic information about virtual machines and in part 2 we went over VHD creation and WMI job’s. In part 3 I am going to cover getting more detailed information about a guest operating system by using the KVP Exchange integration component. KVP stands for Key Value Pair this is a service that runs in the guest operating system and allows some limited information to be passed from the guest to the host or parent and vice-verse. For now we are going to focus only on the intrinsic KVP’s these are provided by default on virtual machines that have the integration components installed. The intrinsic KVP’s include: FullyQualifiedDomainName, OsName, OsVersion, CSDVersion, OsMajorVersion, OsMinorVersion, OsBuildNumber, OsPlatformID, ServicePackMajor, SuiteMask, ProductType, ProcessorArhitecture.
I’ll start with the PowerShell script and results and then explain how to decipher each of the KVP’s values but first I want to thank Ed one of our top notch developers that provided me this script...
In the gray box is the body of the script, it’s a bit different then what we have seen in the past primarily because is what looks like a function at the top. This function looking thing is a PowerShell filter, what the filter does is take a bunch of XML known in WMI as an “embedded instance" and converts it into objects. If you want to see the XML in it’s raw form remove the "|Import-CimXml” from the last line of the script and you’ll see how handy this little filter is.
So what’s happening in this script? I will ignore the filter for a moment so the first line is the the $Vm = Get-Wmi… So the first line should look pretty common now, we are getting a Msvm_ComputerSystem WMI object for a given virtual machine “Server 2008 – Test1". The second line is new, we are running an Association query to get a Msvm_KvpExchangeCompoents WMI object for this VM, associations are an optimization in WMI you can think of them like a SQL join statement “Please give me all of the X that corresponds to Y”. The third line is just taking the GuestIntrinsicExchangeItems property of the Msvm_KvpExchangeCompoents and piping or sending it (that’s the | character) to the Import-CimXml filter that’s written above. Now for the filter, so all this filter is doing is using an XML xpath query to go over each “Instance/Property” node and adding it’s name and value to this CimObj object and then returning that object…
WMIKVP.ps1 PowerShell Script
filter Import-CimXml
{
$CimXml = [Xml]$_
$CimObj = New-Object -TypeName System.Object
foreach ($CimProperty in $CimXml.SelectNodes("/INSTANCE/PROPERTY"))
{
$CimObj | Add-Member -MemberType NoteProperty -Name $CimProperty.NAME -Value $CimProperty.VALUE
}
$CimObj
}
$Vm = Get-WmiObject -Namespace rootvirtualization -Query "Select * From Msvm_ComputerSystem Where ElementName='Server 2008 - Test1'"
$Kvp = Get-WmiObject -Namespace rootvirtualization -Query "Associators of {$Vm} Where AssocClass=Msvm_SystemDevice ResultClass=Msvm_KvpExchangeComponent"
$Kvp.GuestIntrinsicExchangeItems | Import-CimXml
|
Output of the WMIKVP.ps1 Script
PS C:> . 'D:BlogsDemopowerShellDemoWMIKVP.ps1'
Caption :
Data : AUTOBVT-M02LJSS
Description :
ElementName :
Name : FullyQualifiedDomainName
Source : 2
Caption :
Data : Windows Server (R) 2008 Enterprise
Description :
ElementName :
Name : OSName
Source : 2
Caption :
Data : 6.0.6001
Description :
ElementName :
Name : OSVersion
Source : 2
Caption :
Data : Service Pack 1
Description :
ElementName :
Name : CSDVersion
Source : 2
Caption :
Data : 6
Description :
ElementName :
Name : OSMajorVersion
Source : 2
Caption :
Data : 0
Description :
ElementName :
Name : OSMinorVersion
Source : 2
Caption :
Data : 6001
Description :
ElementName :
Name : OSBuildNumber
Source : 2
Caption :
Data : 2
Description :
ElementName :
Name : OSPlatformId
Source : 2
Caption :
Data : 1
Description :
ElementName :
Name : ServicePackMajor
Source : 2
Caption :
Data : 0
Description :
ElementName :
Name : ServicePackMinor
Source : 2
Caption :
Data : 274
Description :
ElementName :
Name : SuiteMask
Source : 2
Caption :
Data : 3
Description :
ElementName :
Name : ProductType
Source : 2
Caption :
Data : 9
Description :
ElementName :
Name : ProcessorArchitecture
Source : 2
|
Ok now how do you decipher all of these values like SuiteMask? All of this data except the fully qualified domain name come from a Windows API
GetVersionEx
but what you really want to look at is the
OSVERSIONINFOEX
structure. That documents each of these values, for example SuiteMask has a value of 274 above that's 0x112 and according to the documents that means this guest has: Remote Desktop support, Terminal Services is installed, and it's running an Enterprise SKU of Windows...
There's a lot more you can do with the KVP's such as pushing custom data into the guest from the parent partition/host or providing data from the guest so that the parent partition/host can query it. I can provide samples for this in a future post
but only if you want me to - so tell me, actually tell me what posts you want maybe networking or offline vhd servicing or maybe import/export?
--Taylor Brown
--Hyper-V test team
sc_project=3725534; sc_invisible=1; sc_partition=45; sc_security="9a688012";