Share via


Hyper-V Script: Looking at KVP GuestIntrinsicExchangeItems

You may wonder what that title is about, so let me pause to explain things a little.  One of the Integration Components that gets installed inside the virtual machine with Hyper-V is the "KVP" component - which stands for "Key Value Pair".  This is the component that enables the exchange of basic string data between the parent and child environments.  The KVP data is then broken down into three categories:

  • HostExchangeItems
    • This is information being sent from the parent partition to the guest operating system.
  • GuestExchangeItems
    • This is information being sent from the guest operating system to the parent partition.
  • GuestIntrinsicExchangeItems
    • This is information that is automatically sent from the guest operating system to the parent partition.

Today I want to show you how to get the information from the last category and display it in the parent partition.  The biggest challenge with doing this is handling the fact that this data is returned as an XML blob that you need to parse correctly to display the results.

VBScript

 Option Explicit
  
 Dim HyperVServer
 Dim VMName
 Dim WMIService
 Dim VM
 Dim KVP
 Dim xmlDoc
 Dim DisplayString
 Dim exchangeDataItem 
 Dim xpath
 Dim node
  
 'Prompt for the Hyper-V Server to use
 HyperVServer = InputBox("Specify the Hyper-V Server to use:") 
  
 'Get name for the virtual machine
 VMName = InputBox("Specify the name of the virtual machine:") 
  
 'Get an instance of the WMI Service in the virtualization namespace.
 Set WMIService = GetObject("winmgmts:\\" & HyperVServer & "\root\virtualization")
  
 'Get the VM object that we want
 Set VM = (WMIService.ExecQuery("SELECT * FROM Msvm_ComputerSystem WHERE ElementName='" & VMName & "'")).ItemIndex(0)
  
 'Get the KVP Object for the virtual machine
 Set KVP = (VM.Associators_("Msvm_SystemDevice", "Msvm_KvpExchangeComponent")).ItemIndex(0) 
  
 'Create an XML object to parse the data
 Set xmlDoc = CreateObject("Microsoft.XMLDOM")
 xmlDoc.async = "false"
  
 'Iterate over GuestIntrinsicExchangeItems
 for each exchangeDataItem in KVP.GuestIntrinsicExchangeItems
  
    'Load single exchange data item
    xmlDoc.loadXML(exchangeDataItem) 
  
    'Get the value for node name
    xpath = "/INSTANCE/PROPERTY[@NAME='Name']/VALUE/child:text()"
    set node = xmlDoc.selectSingleNode(xpath)
    DisplayString = DisplayString & node.Text & " : "
  
    'Get the data associated with the VM
    xpath = "/INSTANCE/PROPERTY[@NAME='Data']/VALUE/child:text()"
    set node = xmlDoc.selectSingleNode(xpath)
    DisplayString = DisplayString & node.Text & chr(13)
  
 next
  
 wscript.echo "Guest OS information for " & VMName & chr(10) & chr(10) & DisplayString 

PowerShell

 # Filter for parsing XML data
 filter Import-CimXml 
 { 
    # Create new XML object from input
    $CimXml = [Xml]$_ 
    $CimObj = New-Object -TypeName System.Object 
  
    # Iterate over the data and pull out just the value name and data for each entry
    foreach ($CimProperty in $CimXml.SelectNodes("/INSTANCE/PROPERTY[@NAME='Name']")) 
       { 
          $CimObj | Add-Member -MemberType NoteProperty -Name $CimProperty.NAME -Value $CimProperty.VALUE 
       } 
  
    foreach ($CimProperty in $CimXml.SelectNodes("/INSTANCE/PROPERTY[@NAME='Data']")) 
       { 
          $CimObj | Add-Member -MemberType NoteProperty -Name $CimProperty.NAME -Value $CimProperty.VALUE 
       } 
  
    # Display output
    $CimObj 
 } 
  
 # Prompt for the Hyper-V Server to use
 $HyperVServer = Read-Host "Specify the Hyper-V Server to use (enter '.' for the local computer)"
  
 # Prompt for the virtual machine to use
 $VMName = Read-Host "Specify the name of the virtual machine"
  
 # Get the virtual machine object
 $query = "Select * From Msvm_ComputerSystem Where ElementName='" + $VMName + "'"
 $Vm = gwmi -namespace root\virtualization -query $query -computername $HyperVServer
  
 # Get the KVP Object
 $query = "Associators of {$Vm} Where AssocClass=Msvm_SystemDevice ResultClass=Msvm_KvpExchangeComponent"
 $Kvp = gwmi -namespace root\virtualization -query $query -computername $HyperVServer
  
 Write-Host
 Write-Host "Guest KVP information for" $VMName
  
 # Filter the results
 $Kvp.GuestIntrinsicExchangeItems | Import-CimXml 

This should provide you with output like this:

PowerShell

Cheers,

Ben

Comments

  • Anonymous
    November 26, 2008
    Hi Ben, first thank you for your time and effort. Ben: I copied your script and run it on one of my vm in hyper-v and I got an access denied error when the vm tried to contact the hyper-v server. what rights and /or permission do I need to set on the hyper-v server to be able to run this type of scrip. Thanks Luis.

  • Anonymous
    October 21, 2010
    The comment has been removed

  • Anonymous
    November 15, 2012
    A SCCM query would be nice!

  • Anonymous
    April 12, 2016
    For Server 2012 R2 you need to use root\virtualization\v2