Сценарии PowerShell для Hyper-V WMI. Использование службы интеграции обмена Парами ключ-значение (KVP Exchange Integration Service). Часть 3 — заключительная. Добавление новых элементов из гостевой ОС
В прошлый раз (как давно это было! ;-)) мы рассмотрели Добавление новых элементов из родительского раздела с использованием Службы интеграции обмена Парами ключ-значение (KVP Exchange integration component). С помощью KVP мы из родительского раздела записали ключи в реестр гостевой ОС.
Теперь давайте получим в родительском разделе ключи, переданные из гостевого раздела.
Шаг 1. Добавим ключ реестра в гостевую ОС
Это можно сделать с помощью reg.exe или powershell. Например.
reg.exe add "HKLM\SOFTWARE\Microsoft\Virtual Machine\Guest" /v test /t REG_SZ /d testing
New-ItemProperty -path "HKLM:\SOFTWARE\Microsoft\Virtual Machine\Guest" -name test2 -value testing
Шаг 2. Запросим записанный ключ в родительском разделе
Это похоже на пример из первой части статей про KVP Exchange (изменилась только последняя строка :-)). Используем следующий сценарий.
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 root\virtualization -Query "Select * From Msvm_ComputerSystem Where ElementName='vista'"
$Kvp = Get-WmiObject -Namespace root\virtualization -Query "Associators of {$Vm} Where AssocClass=Msvm_SystemDevice ResultClass=Msvm_KvpExchangeComponent"
$Kvp.GuestExchangeItems | Import-CimXml
Пример вывода сценария.
Caption :
Data : testing
Description :
ElementName :
Name : test
Source : 1
Caption :
Data : testing
Description :
ElementName :
Name : test2
Source : 1
В результате выполнения сценария мы получили в родительском разделе ключи, переданные из гостевого раздела. Теперь для полноты картины попробуем получить ранее добавленные ключи родительского раздела и изменить эти их. Вот так реализуется получение предварительно добавленных ключей.
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 root\virtualization -Query "Select * From Msvm_ComputerSystem Where ElementName='vista'"
$Kvp = Get-WmiObject -Namespace root\virtualization -Query "Associators of {$Vm} Where AssocClass=Msvm_SystemDevice ResultClass=Msvm_KvpExchangeComponent"
$GuestKvp = Get-WmiObject -Namespace root\virtualization -Query "Associators of {$Kvp} Where AssocClass=Msvm_ElementSettingData ResultClass=Msvm_KvpExchangeComponentSettingData"
$GuestKvp.HostExchangeItems | Import-CimXml
А вот так — изменение значений предварительно добавленных ключей. Это почти идентично сценарию добавления KVP — за исключением того, что нам надо указать имя существующего KVP и вызвать метод ModifyKvpItems.
$ComputerName = "localhost"
$VMManagementService = Get-WmiObject -class "Msvm_VirtualSystemManagementService" -namespace "root\virtualization" -ComputerName $ComputerName
$Vm = Get-WmiObject -Namespace root\virtualization -ComputerName $ComputerName -Query "Select * From Msvm_ComputerSystem Where ElementName='Vista'"
$Kvp = Get-WmiObject -Namespace root\virtualization -ComputerName $ComputerName -Query "Associators of {$Vm} Where AssocClass=Msvm_SystemDevice ResultClass=Msvm_KvpExchangeComponent"
$Msvm_KvpExchangeDataItemPath = "\\$ComputerName\root\virtualization:Msvm_KvpExchangeDataItem"
$Msvm_KvpExchangeDateItem = ([WmiClass]$Msvm_KvpExchangeDataItemPath).CreateInstance()
$Msvm_KvpExchangeDateItem.Name = <Previous Key Name>
$Msvm_KvpExchangeDateItem.Data = "Foo"
$Msvm_KvpExchangeDateItem.Source = 0
$VMManagementService.ModifyKvpItems($Vm, $Msvm_KvpExchangeDateItem.PSBase.GetText(1))