【Hyper-V】統合サービスの「データ交換」ってなに? その2
前回の投稿はこちら
では実際に、データ交換 機能を介して、ゲストOSの情報を取得してみましょう。
まずは以下の図をご覧ください。これは、ゲストOS上のレジストリエントリです。
ご覧いただくとお分かりのように、HKLM\Software\Microsoft\Virtual Machine\Auto 配下のエントリが表示されています。IPアドレスやOSのビルド番号、コンピュータ名などの基本的なOSの情報が格納されていることがわかります。
実は、ここに表示されているエントリは、ゲストOSにインストールされている「Hyper-V Data Exchange Service」によって生成されています。
統合サービスがインストールされたゲストOSのサービス。ちなみに、赤で囲んだサービスが、それぞれの統合サービス機能に対応している。
Hyper-V Data Exchange Service が起動するときに、OSの基本情報を収集し、このレジストリキー配下に書き込んでくれます。言い換えれば、このレジストリエントリをでたらめに書き換えても、Hyper-V Data Exchange Service を再起動すれば正しい値に戻すことが出来ます。
ホストOSを経由し、ゲストOSの「データ交換」を介して収集できる情報の1つが、ここに羅列されているレジストリエントリです。
以下の図はここまでの話をまとめたものです。
実際にAutoキー配下の値を取得するには、以下のようなコマンドを使用します(今回は PowerShellを使用しますが、WMI なので VBS を使用することもできます)。
まずはゲストOSの名前を使用して、以下のコマンドを実行します。これにより、Hyper-V上のゲストOSのインスタンスを取得できます($VM)。ここで使用しているのが、Msvm_ComputerSystem クラスであす。このクラスは通常使用する root\CIMV2 ネームスペースではなく、root\virtualication ネームスペースに定義されていることに注意してください。
PS C:\>$VM = Get-WmiObject -Namespace root\virtualization -Query "Select * From Msvm_ComputerSystem Where ElementName='ゲストOSの名前' " -ComputerName ホストコンピュータ名 -Credential administrator |
ちなみに、上のコマンドでは、別ドメインのサーバーを操作しているため –Credential でHyper-Vサーバーに接続する際のユーザー名を指定しています。これによって、以下のようなダイアログボックスが表示され、パスワードを入力することができます。
次に、以下のコマンドを入力します。
PS C:\> $Kvp = Get-WmiObject -Namespace root\virtualization -Query "Associators of {$Vm} Where AssocClass=Msvm_SystemDevice ResultClass=Msvm_KvpExchangeComponent" -ComputerName ホストコンピュータ名 -Credential administrator |
{$VM} は前回のコマンドで取得したゲストOSのインスタンスです。注意していただきたいのは、「Associators of」というクエリーを使用しているところです。Associators of により、{$VM} に関連付けられている全てのインスタンスを収集することができます。その中には、ゲストOSの設定や、スナップショット情報、仮想ネットワーク情報などありとあらゆる情報が含まれています。
それらは有用な場合もあるのですが、今回行いたいのはゲストOSとの「データ交換」です。よって、Where句でデータ交換に関するインスタンスのみを取得するように指示します。それが、AssocClass=Msvm_SystemDevice とResultClass=Msvm_KvpExchangeComponent です。
これで必要な情報は取得できたはずです。以下のようにして、「GuestIntrinsicExchangeItems」を参照してみてください。
PS C:\> $kvp.GuestIntrinsicExchangeItems |
以下のように、KVPデータがずらずらっと表示されたはずです。
これだと判読しづらいので、以下のスクリプトをPowerShell プロンプトにコピペしちゃってください。難しいことは考えなくてよいです(説明が面倒なんだろうって?いえいえ、そうではなく…笑)。
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 } |
これによって、Import-CimXml という名前のフィルタが作成されました。
今度は、フィルタも指定して、以下のように入力してみてください。
PS C:\> $kvp.GuestIntrinsicExchangeItems | Import-CimXml |
以下のように表示されればOKです。
ゲストOSのレジストリの値と、PowerShellプロンプト上の表示を見比べてみてください。同じ値が表示されているはずです。
ためしに、ゲストOS上のレジストリエントリを修正し、再度 $KVPの取得を行っていただければ、修正後のレジストリの値を参照することができるでしょう。
修正したレジストリの値を元に戻すには、手で修正してもよいですが、Hyper-V Data Exchange Service を再起動したほうが間違いがありません。
今回は、データ交換によってゲストOSから情報を取得しました。
次回は、データ交換機能によって、ゲストOSのレジストリ上にデータを書き込む方法について解説します。
次回はゲストOSのサービスの状態をホストOSから取得する方法について解説します。
参考サイト
MSDN - Virtual PC Guy’s Weblog : Hyper-V Scripting
https://blogs.msdn.com/b/taylorb/archive/2008/05/06/hyper-v-wmi-using-powershell-scripts-part-3-kvp-s-guest-os-version.aspx https://blogs.msdn.com/b/taylorb/archive/2008/07/06/hyper-v-wmi-kvp-exchange-aka-data-exchange-adding-new-items-from-parent-host.aspx