かつて山市良と呼ばれたおじさんのブログ
セイテクエンジニアのブログ かつて山市良と呼ばれたおじさんのブログ vol.168 知ってる? 使ってる? Hyper-VのKVP|Windows Server 2016 EOSまであと364日
2026年01月13日配信
執筆者:山内 和朗
Windows Server 2016の製品ライフサイクルとサポート終了日(End of LifeCycle《EOL》、End of Support《EOS》)である2027年1月12日まで、とうとう1年を切りました。この連載のシーズン1では、Windows Server 2016とWindows Server 2025の違いや、Hyper-Vホストやドメインコントローラーのインプレースアップグレード、最新Hyper-Vへの仮想化など取り上げましたが、今回から始まるシーズン2では、Azureへの移行やオンプレミスとクラウドのハイブリッド環境を中心にEOL/EOS対策を取り上げていきたいと予定しています。
シーズン2の最初はAzureとは関係ありませんが、私が昔作成したスクリプトを見直していた中で気がづいた、Windows 10/Windows Server 2016前後に行われた、Hyper-Vホスト-ゲスト間のデータ交換サービス(KVP)に関連する重要な変更点について紹介します。
Hyper-V仮想マシン(VM)の統合サービスの1つ「データ交換(Data Exchange)」サービスは、キー値ペア(Key Value Pair《KVP》)とも呼ばれ、VMのゲストとホストに関するキー値ペアを自動生成し、相互に相手の情報(ホストからゲスト、ゲストからホスト)を取得できるようににするサービスです。また、カスタムデータを作成し、KVPのキー値ペアとして格納することもできます。このキー値ペアは、Hyper-VホストとVM間のVMバスを介して転送されるため、Hyper-VホストやVMのネットワーク接続を使用せずに情報を取得できるという特徴があります。
データ交換: キーと値のペアを使用して、Hyper-V のホストとゲストの間で情報を共有する|Windows Server(Microsoft Learn)
例えば、「Hyper-Vマネージャー」のVMの「ネットワーク」タブに表示されるIPアドレスの情報は、KVPを使用してVMのゲストから取得されています。そのため、VMの設定で統合サービスの「データ交換」サービスをオフにして無効化すると、「ネットワーク」タブにIPアドレスは表示されなくなります。次に示す「get-kvpdata.ps1」は、Hyper-Vホストから指定したVMのKVPデータを取得するPowerShellスクリプトです。このスクリプトも、「データ交換」サービスをオフにして無効化すると、何も情報を返しません(画面1、画面2)。
[get-kvpdata.ps1](プレーンテキストで表示)
param(
[Parameter(Mandatory)]
[string]$VMName
)
$ns = 'root\virtualization\v2'
$vm = Get-CimInstance -Namespace $ns -ClassName Msvm_ComputerSystem -Filter "ElementName = '$VMName'"
if (-not $vm) { throw "VM '$VMName' not found." }
$kvp = Get-CimAssociatedInstance -InputObject $vm -Association Msvm_SystemDevice |
Where-Object CimClass -match 'Msvm_KvpExchangeComponent'
# Intrinsic (Basic) Data
$intrinsic = @()
if ($kvp.GuestIntrinsicExchangeItems) {
foreach ($xml in $kvp.GuestIntrinsicExchangeItems) {
$x = [xml]$xml
$intrinsic += [pscustomobject]@{
Name = $x.INSTANCE.PROPERTY | Where-Object { $_.Name -eq 'Name' } | Select-Object -Expand Value
Data = $x.INSTANCE.PROPERTY | Where-Object { $_.Name -eq 'Data' } | Select-Object -Expand Value
Source= 'Intrinsic'
}
}
}
# Exchange Data
$exchange = @()
if ($kvp.GuestExchangeItems) {
foreach ($xml in $kvp.GuestExchangeItems) {
$x = [xml]$xml
$exchange += [pscustomobject]@{
Name = $x.INSTANCE.PROPERTY | Where-Object { $_.Name -eq 'Name' } | Select-Object -Expand Value
Data = $x.INSTANCE.PROPERTY | Where-Object { $_.Name -eq 'Data' } | Select-Object -Expand Value
Source= 'Exchange'
}
}
}
$all = $intrinsic + $exchange
$all

画面1 Hyper-VホストからVMのゲストの情報をKVPを介して取得するスクリプトの実行例。「Hyper-Vマネージャー」に表示されるIPアドレス情報もKVPを介して取得している

画面2 VMの設定で統合サービスの「データ交換」サービスをオフにすると、KVPからデータを取得できない。「Hyper-Vマネージャー」にもIPアドレスが表示されなくなる
ゲストOSのKVPデータは、Windows VMの場合、ゲストOSのレジストリの「HKEY_LOCAL_MACHINE¥SOFTWARE¥Microsoft¥Virtual Machine¥Auto」の下に、Linux VMの場合、格納先はバイナリファイル「/var/lib/hyperv/.kvp_pool_2」ですが、問い合わせ時に自動生成されるためファイルサイズは常にゼロです。「get-kvpdata.ps1」はゲストOSで自動生成されたキー値ペアをキーの名前(Name)と値のデータ(Data)として出力します。また、ゲストOSはHyper-Vホストの情報を、レジストリキー「・・・¥Virtual Machine¥Guest¥Parameters」またはバイナリファイル「/var/lib/hyperv/.kvp_pool_3」から取得できます。
Windows VMの場合はゲストで次のPowerShellコマンドを実行することでHyper-Vホストのコンピューター名(PhysicalHostName)やハイパーバイザー(ホストOS)のビルド番号(HypervisorBuildNumber)とリビジョン番号(HypervisorServiceNumber)、自身のVM名(VirtualMachineName)とVMID(VirtualMachineId)などの情報を取得できます(画面3)。
| Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Virtual Machine\Guest\Parameters" | Format-List |
※Guest¥ParametersをAutoに変更すれば、Hyper-Vホストから取得できるキー値ペアの一覧になります。

画面3 自動生成されレジストリに格納されるKVPデータを利用すると、VMのゲストOSからHyper-Vホストと自身のVMの情報を取得できる
Linuxの場合はバイナリデータですが、可読性は悪い(改行がないように見えるなど)ですがcatコマンドで内容を確認することができます。次のコマンドラインを実行すれば、可読性を高めることができます(画面4)。
| tr '\0' '\n' < /var/lib/hyperv/.kvp_pool_3 | awk 'length($0){ if(!k){ k=$0 } else { print k " = " $0; k="" } }' |
※注: データがマルチバイトデータとしてawkに認識されると、そのデータは正しく処理できません。

画面4 LinuxゲストでKVPからHyper-Vホストの情報を取得する
参考:
データ交換: キーと値のペアを使用して、Hyper-V のホストとゲストの間で情報を共有する|Windows Server(Microsoft Learn)
KVPの通信チャネルは、Hyper-VホストからVMのIPアドレスを設定する静的IPインジェクション(Static IP Injection)機能にも利用されています。静的IPインジェクションは、Hyper-Vレプリカ(フェールオーバーのTCP/IP)やAzure Site Recoveryのフェールオーバーに伴うIPアドレスの書き換えに利用されています。KVPのデータを活用しているHyper-V管理者は少ないかもしれませんが、Hyper-Vの初期から存在する機能です。Hyper-VホストからVMゲストの情報を、VMゲストからHyper-Vホストの情報を取得する方法を知っていれば、運用管理に役に立つことがあるかもしれません。また、KVPはオンプレミスのHyper-V環境だけでなく、Azure上のVMの両方で重要なサービスでもあります。例えば、Hyper-VレプリカやAzure Site Recoveryでフェールオーバー後にネットワーク接続ができないというトラブルがあった場合、その原因の1つとしてKVPが考えられます(Linuxゲストにhv_kvp_daemonがインストールされていないなど*1)。そういうこともあって、古くから存在するのにあまり触れられることがないKVPについて、時間をとって説明しておこうと思いました。
*1 参考: メモ. Hyper-V上のLinuxゲストの最適化
最初の画面1は、あえてレガシなWindowsバージョン(Windows Server 2012 R2)を実行するVMからKVP経由でデータを取得しました。なぜレガシバージョンにしたのかと言えば、Windows 10およびWindows Server 2016以降は一部のデータ(NetworkAddressIPv4やNetworkAddressIPv6などのネットワーク情報)が非推奨になり、取得できなくなったからです(画面5)。LinuxはWindowsよりもキー値ペアの数は少なくなりますが、ネットワーク情報が取得できないということはないようです。

画面5 Windows 10/Windows Server 2016以降は、ネットワーク関連のデータが非推奨に
シーズン1目次|Windows Server 2016 EOSまであとX日 シーズン2(1)