Enumerating parent KVP data
As I mentioned on Tuesday, when you send data to a virtual machine using KVPs they are then stored in a collection on the parent side to be pushed into the virtual machine whenever it starts up. After sending a KVP you can then enumerate the KVPs to see what data is being sent into the virtual machine.
Note that what you are doing here is listing the KVPs that are stored on the parent - not what is currently in the virtual machine (KVPs may have been deleted in the virtual machine, or if the virtual machine has not been started yet they may not have been pushed in).
VBScript:
Option Explicit
Dim HyperVServer
Dim VMName
Dim WMIService
Dim VM
Dim KVP
Dim KVPSettingData
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)
Set KVPSettingData = (KVP.Associators_("Msvm_ElementSettingData", "Msvm_KvpExchangeComponentSettingData")).ItemIndex(0)
'Create an XML object to parse the data
Set xmlDoc = CreateObject("Microsoft.XMLDOM")
xmlDoc.async = "false"
'Iterate over HostExchangeItems
for each exchangeDataItem in KVPSettingData.HostExchangeItems
'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 "Parent OS KVPs 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
$query = "Associators of {$Kvp} Where AssocClass=Msvm_ElementSettingData ResultClass=Msvm_KvpExchangeComponentSettingData"
$KvpSettingData = gwmi -namespace root\virtualization -query $query -computername $HyperVServer
Write-Host
Write-Host "Parent KVP information for" $VMName
# Filter the results
$KvpSettingData.HostExchangeItems | Import-CimXml
Cheers,
Ben