かつて山市良と呼ばれたおじさんのブログ
セイテクエンジニアのブログ かつて山市良と呼ばれたおじさんのブログ vol.246 Hyper-V ホストの棚卸データの参照|Hyper-V 健康診断
2026年10月29日配信
執筆者:山内 和朗
前回から始まった「Hyper-V健康診断」シリーズでは、PowerShellによるHyper-Vのプラットフォーム側の管理の効率化を目指しています。前回はHyper-Vホストの構成情報を1つのCLIXMLファイル(.xml)として保存する棚卸スクリプト「get-hypervhostinventory.ps1」(プレーンテキストで表示/ダウンロード)とそのデータを参照して概要をレポートする「get-hypervhostsummary.ps1」(プレーンテキストで表示/ダウンロード)を紹介しました。今回はCLIXMLファイル(.xml)の棚卸データの参照方法について説明します。前回指摘したように、「get-hypervhostsummary.ps1」は参照方法の一例です。
前回の棚卸スクリプト「get-hypervhostinventory.ps1」は、コンピューターの基本情報(Get-ComputerInfo、Get-WindowsFeatureなど)、Hyper-Vの設定(Get-VMHost、Get-Clusterなど)、ネットワーク(Get-NetAdapter、Get-VMSwitch、Get-NetIPConfigurationなど)、ストレージ(Get-PhysicalDisk、Get-Volume、Get-ClusterSharedVolumeなど)、イベントログ(Get-WinEvent)の各コマンドレットが返すオブジェクトを、Export-Clixmlを使用して1つのCLIXMLファイル(.xml)に保存します。
CLIXMLファイル(.xml)に保存されたHyper-Vホストの棚卸データは、次のようにImport-Clixmlを使用してPowerShellオブジェクトとして復元することができます。ただし、前回も指摘しましたが、Import-Clixmlで完全に元のオブジェクトを復元できるわけではない点には注意が必要です。読み込んだオブジェクトは、Deserialized.*オブジェクト(元のオブジェクトの状態を保存したコピー、スナップショットのようなもの)となり、メソッドやライブオブジェクトとしての動作は失われます。
| $inventory = Import-Clixml .\HyperVHost-Inventory-コンピューター名-yyyyMMdd-HHmmss.xml |
XML(CLIXML)からインポートしたPowerShellオブジェクト(上記の$inventory)には、次のような階層構造に各種情報が格納されています。
| プロパティ | 内容 |
| CollectedAt | データ取得日時 |
| OSInfo.Computername | コンピューター名 |
| OSInfo.OperatingSystem | オペレーティングシステム名 |
| OSInfo.OSBuild | OSビルド(ビルド番号.UBR) |
| OSInfo.isCluster | クラスター構成かどうか(True/False) |
| OSInfo.ClusterName | クラスター構成の場合はクラスター名(クラスターのみ) |
| OSInfo.Hotfix | Get-Hotfixが返すオブジェクト |
| OSInfo.WindowsFeatures | Get-WindowsFeatureが返すオブジェクト |
| ComputerInfo | Get-ComputerInfoが返すオブジェクト |
| HyperV.Services | Get-Service(Hyper-V関連のサービス)が返すオブジェクト |
| HyperV.VMHost | Get-VMHostが返すオブジェクト |
| HyperV.NumaNodes | Get-NumaNodesが返すオブジェクト |
| HyperV.VMReplicationServer | Get-VMReplicationServerが返すオブジェクト |
| HyperV.VMReplication | Get-HyperV.VMReplicationが返すオブジェクト |
| Network.NetAdapters | Get-NetAdapterが返すオブジェクト |
| Network.VMSwitches | Get-VMSwitchが返すオブジェクト |
| Network.Get-NetNat | Get-NetNatが返すオブジェクト |
| Network.NetNatStaticMappings | Get-NetNatStaticMapping が返すオブジェクト |
| Network.ManagementOSAdapters | Get-VMNetworkAdapter -ManagementOSが返すオブジェクト |
| Network.IPAddresses | Get-NetIPConfigurationが返すオブジェクト |
| Network.FirewallRules |
Get-NetFirewallRule -PolicyStore ActiveStoreが返すオブジェクト |
| Storage.PhysicalDisks | Get-PhysicalDiskが返すオブジェクト |
| Storage.Volumes | Get-Volumeが返すオブジェクト |
| Storage.ClusterSharedVolumes | Get-ClusterSharedVolumeが返すオブジェクト(クラスターのみ) |
| Storage.S2D.StoragePool | Get-StoragePool -FriendlyName 'S2D*'が返すオブジェクト(クラスターのみ) |
| Storage.S2D.PhysicalDisks | Get-StorageSubsystem -FriendlyName 'Cluster*' | Get-PhysicalDiskが返すオブジェクト(クラスターのみ) |
| Storage.S2D.VirtualDisks | Get-VirtualDiskが返すオブジェクト(クラスターのみ) |
| Virtual Machines | Get-VMが返すオブジェクト |
| Virtual Machines.HA |
VMがクラスター化されたVMかどうか(True/False) |
| Virtual Machines.VCPU | VMのGet-VMProcessorが返すオブジェクト |
| Virtual Machines.VRAM | VMのGet-VMMemoryが返すオブジェクト |
| Virtual Machines.VMFirmware | VMのGet-VMFirmwareが返すオブジェクト |
| Virtual Machines.VMSecurity | VMのGet-VMSecurityが返すオブジェクト |
| Virtual Machines.VNIC | VMのGet-VMNetworkAdapterが返すオブジェクト |
| Virtual Machines.VHD | VMのGet-VMHardDiskDriveが返すオブジェクト |
| Virtual Machines.VMSnapshot | VMのGet-VMSnapshotが返すオブジェクト |
| HyperVEvents | Get-WinEventが返すオブジェクト(System、Securiy、Application、およびMicrosoft-Windows-Hyper-V-*の重大/エラー/警告レベルのイベントのみ) |
例えば、ホストのオペレーティングシステム名やOSビルドは、$inventory.osInfo.OperatingSystemや$inventory.osInfo.OSBuildで参照できます。$inventory.VirtualMachinesは、データ取得時点のGet-VMと同じ内容に加えて、クラスター化されているか(.HA)、および各VMに紐づくGet-VMProcessor(.VCPU)、Get-VMMemory(.VRAM)、Get-VMFirmware(.VMFirmware)などの追加情報が格納されていています(画面1)。$inventory.Network.IPAddressesは取得時点のIPアドレス関連設定が、$inventory.HyperVLogsには、取得時点から過去24時間の重大/エラー/警告レベルのログが格納されています(画面2)。

画面1 Import-ClixmlでデータをPowerShellオブジェクトとして読み込めば、データ取得時点の各種オブジェクトの内容を参照できる

画面2 データ取得時過去24時間の重大/エラーレベルのシステム、アプリケーション、セキュリティ、Hyper-V関連イベントの表示
次のように、異なるタイミングで取得した棚卸データをImport-Clixmlで読み込んで、それぞれオブジェクト変数に格納すれば、オブジェクトのプロパティの変更点を調査することができます(画面3)。
| $oldinv = Import-Clixml .\HyperVHost-Inventory-コンピューター名-XXXXXX-XXXXXX.xml $newinv = Import-Clixml .\HyperVHost-Inventory-コンピューター名-YYYYYY-YYYYYY.xml |

画面3 新旧棚卸データを読み込んでGet-VMHostの違いを比較
棚卸データと現在の最新値を比較することもできます。例えば、棚卸データのGet-VMと、現在のGet-VMの結果を比較するには、次のようにそれぞれをオブジェクト変数に格納して比較します(画面4)。
| $oldinv = Import-Clixml .\HyperVHost-Inventory-コンピューター名-XXXXXX-XXXXXX.xml $oldVMs = $oldinv.VirtualMachines $curVMs = Get-VM |

画面4 棚卸データから読み込んだ過去のGet-VMの結果と、最新(現在)のGet-VMの結果を比較する
比較対象が明確な場合、新旧データのオブジェクトのプロパティを突き合わせて調べればよいわけですが、膨大なプロパティの値をすべて調べるのは少し厄介です。PowerShellにはCompare-Objectというオブジェクトを比較するコマンドレットがありますが、例えば深いレベルを持つオブジェクトのルートで比較しても、オブジェクト内部のプロパティを再帰的に比較してくれるわけではありません。少なくとも、比較対象のプロパティを-Propertiesパラメーターで指定する必要があります。また、CLIXMLから読み込んだ複雑なオブジェクトでは、内部の設定値に違いがあっても差分として検出されないことがあります。
実際の比較では、VMやホストなどの比較対象を取り出し、比較するプロパティを指定して新旧の値を比較する必要があります(画面2のスクリプトの例)。また、Get-VMHostやGet-VMなどの最新の実行結果と比較する場合は、オブジェクトの型の違いにも配慮する必要があります(例、Get-VMHostが返すMicrosoft.HyperV.PowerShell.VMHostオブジェクトに対して、棚卸データのHyperV.VMHostに格納されているのはDeserialized.Microsoft.HyperV.PowerShell.VMHostオブジェクト)。また、比較の際には、データ取得時の状態によって変化するプロパティ(Get-ComputerInfoのOsFreePhysicalMemory、OsLocalDateTime、Get-VMのStatus、CPUUsageなど)を比較対象から除外するなどの考慮も必要です。さらに、配列や複合オブジェクトを含むプロパティは、CLIXMLから読み込んだオブジェクトと現在のコマンドレットが返すオブジェクトで型や内部構造が異なる場合があり、単純な比較では不要な差分が検出されることがあります。そのため、棚卸データの比較では、構成変更として意味のあるプロパティを選んで比較することが重要です。
そこで次回は、2つの棚卸データ間、または棚卸データと現在値の差分をレポートするスクリプトを作成して紹介します。
棚卸スクリプトは棚卸データをPowerShellで扱うためExport-Clixmlを使用しましたが、外部のツールと連携するためにJSON形式に変換して保存したり、JSON形式から読み込んだりすることもできます。それには、次のように実行します。なお、JSONへの変換では注意が必要なデータ型もあります。例えばEnum(列挙型)の値は、ConvertTo-Jsonで既定では数値として出力される場合があります。そのため、画面上では「Running」などと表示されていた値が、JSONでは対応する数値として保存されることがあります。PowerShell 6/7のConvertTo-JSONを使用する場合、-EnumsAsStringsパラメーターを使用すると、すべてのEnumを数値ではなく文字列として出力させることができます。また、棚卸データは深いオブジェクトを持ちますが、-Depth 15で十分であるかどうかは未確認です(超えた深さは切り捨てられます)。一方で、展開の深さの指定が大きすぎるとメモリ不足や例外エラーが発生することがあるので注意してください。
| $inventory = Import-Clixml .\HyperVHost-Inventory-コンピューター名-yyyyMMdd-HHmmss.xml # JSON形式で保存 if ((Get-Process -Id $PID).ProcessName -eq "powershell") { #Windows PowerShell 5.1の場合 $inventory | ConvertTo-Json -Depth 15 | Set-Content .\inventory.json -Encoding UTF8 } else { #PowerShellの場合 $inventory | ConvertTo-Json -Depth 15 -EnumsAsStrings | Set-Content .\inventory.json -Encoding UTF8 } # JSON形式を読み取り $inventory = Get-Content .\inventory.json -Raw | ConvertFrom-Json |
サーバー設定仕様書の自動生成サービス、SSD-assistanceのご紹介弊社の主力製品の1つ設定仕様書自動生成サービス「SSD-assistance」は、設定仕様書作成のためのデータ収集やドキュメント作成の手間と時間を省き、高品質で標準化された設定仕様書を自動生成するサービスです。SSD-assistanceは、「Hyper-V ホスト 設定仕様書」の作成に対応している上、「差分比較リスト」で構成の変更差分を視覚的に強調表示させることができます。これまで、そして次回以降の記事でやろうとしていることと同等のことは、実はSSD-assistanceを利用すれば誰でも、簡単に、すぐに実現することができます。ただこの連載記事では、SSD-assistanceでは手の届かない、Hyper-Vの深くて、細かいところまで手を伸ばせればと考えています。 |
リファレンス(Microsoft Learn):
Get-ComputerInfo(PowerShell Management)|Get-Service(PowerShell Management)|Get-HotFix(PowerShell Management)|Get-VMHost(Hyper-V)|Get-VMHostNumaNode(Hyper-V)|Get-VM(Hyper-V)|Get-VMProcessor(Hyper-V)|Get-VMMemory(Hyper-V)|Get-VMFirmware(Hyper-V)|Get-VMSecurity(Hyper-V)|Get-VMNetworkAdapter(Hyper-V)|Get-VMHardDiskDrive(Hyper-V)|Get-VMSnapshot(Hyper-V)|Get-VMReplicationServer(Hyper-V)|Get-VMReplication(Hyper-V)|Get-VMSwitch(Hyper-V)|Get-Cluster(FailoverClusters)|Get-ClusterGroup(FailoverClusters)|Get-ClusterSharedVolume(FailoverClusters)|Get-NetAdapter(NetAdapter)|Get-PhysicalDisk(Storage)|Get-Volume(Storage)|Get-WinEvent(PowerShell Dignostics)|Export-Clixml(PowerShell Utility)|Import-Clixml(PowerShell Utility)|ConvertTo-JSON(PowerShell Utility)|ConvertFrom-JSON(PowerShell Utility)|Compare-Object(PowerShell Utility)
Hyper-V 小技・裏技集 目次|(1) |(2)|(3)