引き続き、Hyper-Vホストの構成情報を1つのCLIXMLファイル(.xml)として保存する棚卸スクリプト「get-hypervhostinventory.ps1」(プレーンテキストで表示/ダウンロード)で保存した2つの棚卸データの差分比較を行います。今回の対象はHyper-Vの仮想マシン(VM)です。
棚卸データのVMに関連するデータ構造
棚卸データのVMのデータは、CLIXMLファイル(.xml)からImport-Clixmlで読み込んだオブジェクトのVirtualMachinesプロパティ下に格納されています。ここには、Get-VMの実行結果に加え、VMごとのGet-VMProcessor(VCPUの設定)、Get-VMMemory(動的メモリなどの設定)、Get-VMFirmware(セキュアブート、セキュアブートテンプレート、ブート順など)、Get-VMSecurity(TPMのオン/オフなど)、Get-VMNetworkAdapter(ネットワークアダプターの割り当て)、Get-VMHardDiskDrive(ハードドライブの割り当て)、Get-VMSnapshot(✓位ポイント)の実行結果、およびクラスター化されているかどうかによって棚卸スクリプトでセットしたHAプロパティ(※Get-VMのisClusteredプロパティがあったので追加は不要でした)が、Get-VMのプロパティ直下のプロパティまたはコレクションとして含まれています。Get-VMだけでも大量のプロパティを持つ上に、VMに紐づく他のデータを含めると、そのデータは複雑であり、VM数が多いと巨大なコレクションになります。
| Virtual Machines |
Get-VMが返すオブジェクト |
| Virtual Machines.HA |
VMがクラスター化されたVMかどうか(True/False) ※Get-VMのisClusteredプロパティがあったので追加は不要でした。比較も不要です。
|
| 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が返すオブジェクト(コレクション) |
※棚卸データ全体のデータ構造については、前々回の記事の一覧表を参照してください。
VMの一括比較スクリプト
次のPowerShellスクリプト「Compare-HyperVVMs.ps1」は、棚卸データのVirtualMachinesプロパティの配下をVMごとに突き合わせて比較し、差分を返すスクリプトです。追加されたVMと削除されたVMにも対応しています。
Get-VMの実行結果のすべてのプロパティを突き合わあせて比較すると、ノイズが多いだけでなく、同じ内容に見えても差分(複合プロパティなど)として判断されてしまうことがあります。また、動的に変化する値(Get-VMのStatusやCPUUsage、MemoryAssigned、MemoryDemand、UpTimeなど)のプロパティは比較しても意味がありません。そこで、このスクリプトではまず、前回の「Compare-Properties.ps1」と同様に、文字列(string)、数値(decimal、Int32、Int64、Doubleなど)、真偽値(Boolen)、日時(DateTime)、列挙値(Enum)など、1つの値として比較できる単純値のプロパティだけを対象にすることに加え(Compare-SimpleProperties関数を参照)、動的に変化する値とコレクションを除外しています(Compare-SimpleProperties関数を呼び出す際の-ExcludePropertyを参照)。
その上で除外したコレクションの中で重要なもの(Groups、ComPort1、ComPort2、VMIntegrationService)と、Get-VM以外(Get-VMProcessorなど)で取得したコレクションを個別に処理します。なお、Get-VM(VirtualMachines)のFibreChannelHostBusAdapters、DVDDrives、HardDrives、およびNetworkAdaptersは数だけを比較しています。HDDカテゴリではディスクごとにコントローラー、場所、パスを比較、VNICカテゴリではすべてのネットワークアダプターのMACアドレスで比較しています。
最初は単純値のプロパティを突き合わせて比較するだけのシンプルなスクリプトだったのですが、色々と付け足していくうちに、巨大化、複雑化してしまいました(反省)。でも、私の環境では期待どおりに動いているので良しとします。
[Compare-HyperVVMs.ps1](プレーンテキストで表示/ダウンロード)
param(
[Parameter(Mandatory)]
[AllowNull()]
$oldVMs,
[Parameter(Mandatory)]
[AllowNull()]
$newVMs,
[ValidateSet("VMonly", "All")]
[string]$Category = ""
)
if ($Category -eq "") {
$Category = "All"
if (($oldVms -ne $null) -and ($oldVms.Count -gt 0)) {
$objTypes = $oldVms[0].PSObject.TypeNames
if ($objTypes -contains "Microsoft.HyperV.PowerShell.VirtualMachine") {
$Category = "VMonly"
}
}
if (($newVms -ne $null) -and ($newVms.Count -gt 0)) {
$objTypes = $newVms[0].PSObject.TypeNames
if ($objTypes -contains "Microsoft.HyperV.PowerShell.VirtualMachine") {
$Category = "VMonly"
}
}
}
$result = @()
function Compare-SimpleProperties {
param(
$OldObject,
$NewObject,
[string]$Category,
$VM,
[string[]]$ExcludeProperty = @()
)
if ($null -eq $OldObject -and $null -eq $NewObject) {
return
}
# オブジェクト自体の追加・削除
if ($null -eq $OldObject) {
return [pscustomobject]@{
ChangeType = 'Added'
VMName = $VM.Name
VMId = $VM.VMId
Category = $Category
Property = $null
OldValue = $null
NewValue = $null
}
}
if ($null -eq $NewObject) {
return [pscustomobject]@{
ChangeType = 'Removed'
VMName = $VM.Name
VMId = $VM.VMId
Category = $Category
Property = $null
OldValue = $null
NewValue = $null
}
}
foreach ($prop in $NewObject.PSObject.Properties.Name) {
if ($prop -in $ExcludeProperty) {
continue
}
$oldValue = $OldObject.$prop
$newValue = $NewObject.$prop
# 新旧とも単純値だけを対象にする
$oldSimple =
$null -eq $oldValue -or
$oldValue.GetType().IsPrimitive -or
$oldValue -is [string] -or
$oldValue -is [decimal] -or
$oldValue -is [datetime] -or
$oldValue -is [guid] -or
$oldValue.GetType().IsEnum
$newSimple =
$null -eq $newValue -or
$newValue.GetType().IsPrimitive -or
$newValue -is [string] -or
$newValue -is [decimal] -or
$newValue -is [datetime] -or
$newValue -is [guid] -or
$newValue.GetType().IsEnum
if (-not $oldSimple -or -not $newSimple) {
continue
}
# Deserialized Enumなどの型差を避け、表示上の値で比較
$oldText = if ($null -eq $oldValue) { $null } else { $oldValue.ToString() }
$newText = if ($null -eq $newValue) { $null } else { $newValue.ToString() }
if ($oldText -ne $newText) {
[pscustomobject]@{
ChangeType = 'Changed'
VMName = $VM.Name
VMId = $VM.VMId
Category = $Category
Property = $prop
OldValue = $oldText
NewValue = $newText
}
}
}
}
# 既存VM / 追加VM
foreach ($newVM in $newVMs) {
$oldVM = $oldVMs | Where-Object VMId -eq $newVM.VMId
# 追加されたVM
if (-not $oldVM) {
$result += [pscustomobject]@{
ChangeType = 'Added'
VMName = $newVM.Name
VMId = $newVM.VMId
Category = 'VM'
Property = $null
OldValue = $null
NewValue = $null
}
continue
}
# -----------------------------
# Get-VM 本体
# -----------------------------
$result += Compare-SimpleProperties `
-OldObject $oldVM `
-NewObject $newVM `
-Category 'VM' `
-VM $newVM `
-ExcludeProperty @(
'CPUUsage'
'MemoryAssigned'
'MemoryDemand'
'MemoryStatus'
'NumaAligned'
'NumaNodesCount'
'NumaSocketCount'
'Heartbeat'
'IntegrationServicesState'
'Uptime'
'OperationalStatus'
'PrimaryOperationalStatus'
'SecondaryOperationalStatus'
'StatusDescriptions'
'PrimaryStatusDescription'
'SecondaryStatusDescription'
'Status'
'ReplicationHealth'
'ReplicationState'
'State'
'SizeOfSystemFiles'
'GuestControlledCacheTypes'
'LowMemoryMappedIoSpace'
'HighMemoryMappedIoSpace'
'HighMemoryMappedIoBaseAddress'
'VMIntegrationService'
'HA'
'VCPU'
'VRAM'
'VMFirmware'
'VMSecurity'
'VNIC'
'VHD'
'VMSnapshot'
)
# -----------------------------
# Get-VM のコレクションプロパティの比較
# -----------------------------
# Groups
$oldValue = @($oldVM.Groups) |
ForEach-Object { $_.Name } |
Sort-Object
$newValue = @($newVM.Groups) |
ForEach-Object { $_.Name } |
Sort-Object
if (($oldValue -join ',') -ne ($newValue -join ',')) {
$result += [pscustomobject]@{
ChangeType = 'Changed'
VMName = $newVM.Name
VMId = $newVM.VMId
Category = 'VM'
Property = 'Groups'
OldValue = $oldValue -join ','
NewValue = $newValue -join ','
}
}
# ComPort1 Pathで比較
$oldValue = $oldVM.ComPort1.Path
$newValue = $newVM.ComPort1.Path
if ($oldValue -ne $newValue) {
$result += [pscustomobject]@{
ChangeType = 'Changed'
VMName = $newVM.Name
VMId = $newVM.VMId
Category = 'VM'
Property = 'ComPort1'
OldValue = $oldValue
NewValue = $newValue
}
}
# ComPort2 Pathで比較
$oldValue = $oldVM.ComPort2.Path
$newValue = $newVM.ComPort2.Path
if ($oldValue -ne $newValue) {
$result += [pscustomobject]@{
ChangeType = 'Changed'
VMName = $newVM.Name
VMId = $newVM.VMId
Category = 'VM'
Property = 'ComPort2'
OldValue = $oldValue
NewValue = $newValue
}
}
# FibreChannelHostBusAdapters Countで比較
$oldCount = @($oldVM.FibreChannelHostBusAdapters).Count
$newCount = @($newVM.FibreChannelHostBusAdapters).Count
if ($oldCount -ne $newCount) {
$result += [pscustomobject]@{
ChangeType = 'Changed'
VMName = $newVM.Name
VMId = $newVM.VMId
Category = 'VM'
Property = 'FibreChannelHostBusAdapters.Count'
OldValue = $oldCount
NewValue = $newCount
}
}
# DVDDrives Countで比較
$oldCount = @($oldVM.DVDDrives).Count
$newCount = @($newVM.DVDDrives).Count
if ($oldCount -ne $newCount) {
$result += [pscustomobject]@{
ChangeType = 'Changed'
VMName = $newVM.Name
VMId = $newVM.VMId
Category = 'VM'
Property = 'DVDDrives.Count'
OldValue = $oldCount
NewValue = $newCount
}
}
# HardDrives Countで比較
$oldCount = @($oldVM.HardDrives).Count
$newCount = @($newVM.HardDrives).Count
if ($oldCount -ne $newCount) {
$result += [pscustomobject]@{
ChangeType = 'Changed'
VMName = $newVM.Name
VMId = $newVM.VMId
Category = 'VM'
Property = 'HardDrives.Count'
OldValue = $oldCount
NewValue = $newCount
}
}
# NetworkAdapters Countで比較
$oldCount = @($oldVM.NetworkAdapters).Count
$newCount = @($newVM.NetworkAdapters).Count
if ($oldCount -ne $newCount) {
$result += [pscustomobject]@{
ChangeType = 'Changed'
VMName = $newVM.Name
VMId = $newVM.VMId
Category = 'VM'
Property = 'NetworkAdapters.Count'
OldValue = $oldCount
NewValue = $newCount
}
}
# VMIntegrationService
$oldServices = @($oldVM.VMIntegrationService)
$newServices = @($newVM.VMIntegrationService)
foreach ($newService in $newServices) {
$oldService = $oldServices |
Where-Object Name -eq $newService.Name
if (-not $oldService) {
$result += [pscustomobject]@{
ChangeType = 'Added'
VMName = $newVM.Name
VMId = $newVM.VMId
Category = 'IntegrationService'
Property = $newService.Name
OldValue = $null
NewValue = if ($newService.Enabled) {
'Enabled'
}
else {
'Disabled'
}
}
continue
}
if ($oldService.Enabled -ne $newService.Enabled) {
$result += [pscustomobject]@{
ChangeType = 'Changed'
VMName = $newVM.Name
VMId = $newVM.VMId
Category = 'IntegrationService'
Property = $newService.Name
OldValue = if ($oldService.Enabled) {
'Enabled'
}
else {
'Disabled'
}
NewValue = if ($newService.Enabled) {
'Enabled'
}
else {
'Disabled'
}
}
}
}
foreach ($oldService in $oldServices) {
if ($oldService.Name -notin $newServices.Name) {
$result += [pscustomobject]@{
ChangeType = 'Removed'
VMName = $newVM.Name
VMId = $newVM.VMId
Category = 'IntegrationService'
Property = $oldService.Name
OldValue = if ($oldService.Enabled) {
'Enabled'
}
else {
'Disabled'
}
NewValue = $null
}
}
}
# -----------------------------
# Get-VM 以外の関連プロパティの比較
# -----------------------------
if ($Category -eq 'All') {
# -----------------------------
# HA
# -----------------------------
# VirtualMachines (Get-VM) の .IsClustered と同じなので比較しない
# -----------------------------
# VCPU (Get-VMProcessor)
# -----------------------------
$result += Compare-SimpleProperties `
-OldObject $oldVM.VCPU `
-NewObject $newVM.VCPU `
-Category 'VCPU' `
-VM $newVM `
-ExcludeProperty @(
'Dummy'
)
# -----------------------------
# VRAM (Get-VMMemory)
# -----------------------------
$result += Compare-SimpleProperties `
-OldObject $oldVM.VRAM `
-NewObject $newVM.VRAM `
-Category 'VRAM' `
-VM $newVM `
-ExcludeProperty @(
'MemoryEncryptionEnabled'
)
# -----------------------------
# VMFirmware (Get-VMFirmware)
# -----------------------------
$result += Compare-SimpleProperties `
-OldObject $oldVM.VMFirmware `
-NewObject $newVM.VMFirmware `
-Category 'VMFirmware' `
-VM $newVM `
-ExcludeProperty @(
'Dummy'
)
# BootOrder
$oldBootOrder = @($oldVM.VMFirmware.BootOrder) |
ForEach-Object { $_.FirmwarePath }
$newBootOrder = @($newVM.VMFirmware.BootOrder) |
ForEach-Object { $_.FirmwarePath}
if (($oldBootOrder -join ',') -ne ($newBootOrder -join ',')) {
$oldBootOrder = @($oldVM.VMFirmware.BootOrder) |
ForEach-Object {
if ($null -eq $_.BootType) {
'Unknown'
} else {
$_.BootType.ToString()
}
}
$newBootOrder = @($newVM.VMFirmware.BootOrder) |
ForEach-Object {
if ($null -eq $_.BootType) {
'Unknown'
} else {
$_.BootType.ToString()
}
}
$result += [pscustomobject]@{
ChangeType = 'Changed'
VMName = $newVM.Name
VMId = $newVM.VMId
Category = 'VMFirmware'
Property = 'BootOrder'
OldValue = $oldBootOrder -join ','
NewValue = $newBootOrder -join ','
}
}
# -----------------------------
# VMSecurity (Get-VMSecurity)
# -----------------------------
$result += Compare-SimpleProperties `
-OldObject $oldVM.VMSecurity `
-NewObject $newVM.VMSecurity `
-Category 'VMSecurity' `
-VM $newVM `
-ExcludeProperty @(
'Dummy'
)
# -----------------------------
# VNIC (Get-VMNetworkAdapter)
# -----------------------------
$oldMac = @($oldVM.VNIC.MacAddress) | Sort-Object
$newMac = @($newVM.VNIC.MacAddress) | Sort-Object
if (($oldMac -join ',') -ne ($newMac -join ',')) {
$result += [pscustomobject]@{
ChangeType = 'Changed'
VMName = $newVM.Name
VMId = $newVM.VMId
Category = 'VNIC'
Property = 'MACAddress'
OldValue = $oldMac -join ','
NewValue = $newMac -join ','
}
}
# -----------------------------
# VHD (Get-VMHardDiskDrive)
# -----------------------------
$oldvals = @($oldVM.VHD)
$newvals = @($newVM.VHD)
$oldvals = @($oldvals | Sort-Object | ForEach-Object {
@(
$_.ControllerType
$_.ControllerNumber
$_.ControllerLocation
$_.DiskNumber
$_.Path
) -join '_'
})
$newvals = @($newvals | Sort-Object | ForEach-Object {
@(
$_.ControllerType
$_.ControllerNumber
$_.ControllerLocation
$_.DiskNumber
$_.Path
) -join '_'
})
for ($i = 0; $i -lt [Math]::Max($oldvals.Count, $newvals.Count); $i++) {
$diff = if ($i -ge $oldvals.Count) { "Added" }
elseif ($i -ge $newvals.Count) { "Removed" }
elseif ($oldvals[$i] -eq $newvals[$i]) { "NoChanged" }
else { "Changed" }
if($diff -ne "NoChanged") {
$result += [pscustomobject]@{
ChangeType = $diff
VMName = $newVM.Name
VMId = $newVM.VMId
Category = "VHD"
Property = "Disk$i"
OldValue = $oldvals[$i]
NewValue = $newvals[$i]
}
}
}
# -----------------------------
# VMSnapshot (Get-VMSnapshot)
# -----------------------------
$oldCount = @($oldVM.VMSnapshot).Count
$newCount = @($newVM.VMSnapshot).Count
if ($oldCount -ne $newCount) {
$result += [pscustomobject]@{
ChangeType = 'Changed'
VMName = $newVM.Name
VMId = $newVM.VMId
Category = 'VMSnapshot'
Property = 'Count'
OldValue = $oldCount
NewValue = $newCount
}
}
}
# -----------------------------
# Get-VM 以外の関連プロパティの比較(ここまで)
# -----------------------------
}
# 削除されたVM
foreach ($oldVM in $oldVMs) {
if ($oldVM.VMId -notin $newVMs.VMId) {
$result += [pscustomobject]@{
ChangeType = 'Removed'
VMName = $oldVM.Name
VMId = $oldVM.VMId
Category = 'VM'
Property = $null
OldValue = $null
NewValue = $null
}
}
}
$result
スクリプトの実行例
前回も説明しましたが、棚卸スクリプト「get-hypervhostinventory.ps1」でCLIXMLファイル(.xml)に保存した新旧棚卸データは、次のコマンドラインを実行することで、それぞれ別の変数にオブジェクトとして読み込むことができます。
$oldinv = Import-Clixml .\HyperVHost-Inventory-コンピューター名-XXXXXX-XXXXXX.xml $newinv = Import-Clixml .\HyperVHost-Inventory-コンピューター名-YYYYYY-YYYYYY.xml
|
スクリプトには、Import-Clixmlで読み込んだ新旧オブジェクトのVirtualMachinesプロパティを次のように渡して実行します。なお、@()は省略できますが、@()で囲むことでVM一覧が1台の場合でも配列として扱えるようになります。
$oldVMs = @($oldinv.VirtualMachines) $newVMs = @($newinv.VirtualMachines) .\Compare-HyperVVMs.ps1 $oldVMs $NewVMs |Format-Table -AutoSize
|
差分は次のような形式のオブジェクトとして出力されます。長い文字列の値の影響で画面出力が途切れてしまう場合は、Out-GridVew*1 を利用すると便利です(画面1)。Categoryのカテゴリは、Get-VMに含まれるものがVM(およびHA)、それ以外のコレクションについてはVCPU、VRAM、VMFirmware、VMSecurity、VHD、VMSnapshotになります。また、値に変更がある場合は、ChangeTypeがChangedになりますが、追加/削除されたVMについては、Added/Removedと表示し、Property/OldValue/NewValueは空欄になります。
ChangeType VMName VMId Category Property OldValue NewValue ---------- ------ ---- -------- -------- -------- -------- Changed VM名 XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX カテゴリ プロパティ名 旧い値 新しい値 |

画面1 新旧棚卸データのVMデータを比較して、差分を出力する
*1 ※PowerShell 7.6.6のOut-GridViewには不具合が存在し、応答が返ってこない問題が確認されています(→ OutGridView freezes indefinitely in 7.6.6 #27994|PowerShell Issue GitHub) 。この問題は、PowerShell 7.6.7以降で解消されています。
なお、比較処理と比較結果を簡潔にするため、一部のプロパティについては数や、コレクションのプロパティを連結した値の差異を比較しています。詳細を調べたい場合は、棚卸データの該当箇所を参照してください。例えば、次のように実行すれば、指定したVMのVHDコレクションの新旧を一覧表示できます(画面2)。Compare-HyperVVMs.ps1スクリプトでは、SCSI_0_0__パスのように連結して比較し、差異がある場合は連結値をVHDカテゴリのDisk0、Disk1プロパティの値として出力します。
$targetvm = "VM名またはVMId" foreach($vm in $oldvms) { if(($vm.Name -eq $targetvm) -or ($vm.Vmid -eq $targetvm)) { $vm.VHD |Select ControllerType,ControllerNumber,ControllerLocation,Path | Format-Table -AutoSize } } foreach($vm in $newvms) { if(($vm.Name -eq $targetvm) -or ($vm.Vmid -eq $targetvm)) { $vm.VHD |Select ControllerType,ControllerNumber,ControllerLocation,Path | Format-Table -AutoSize } } |

画面2 ハードドライブの数の差異の詳細を確認する
次の画面3のように、最新の棚卸データ(例えば$newinv)と現在のGet-VMの実行結果をこのスクリプトで比較することもできます。ただし、その場合、比較対象はカテゴリVMとなるため、VCPU、VRAM、VMFirmware、VMSecurity、VNIC、VHD、VMSnapshotのカテゴリは比較されません。その結果、ハードドライブの追加/削除、チェックポイントの作成/適用/削除、ネットワークアダプターの追加/削除、セキュアブート、TPMのオン/オフ、ブート順の変更などは差分として出力されないことに注意してください。*2
*2 VRAMカテゴリ(Get-VMMemory)のDynamicMemoryEnabled、Startup、Maximum、Minimumプロパティは、VMカテゴリ(Get-VM)のDynamicMemoryEnabled、MemoryStartup、MemoryMinimum、MemoryMaximumプロパティの変化として検出されます。

画面3 最新の棚卸データと現在のGet-VMの実行結果を確認する
なお、次のように実行した場合、どうなるでしょうか。
|
$oldvm = @(Get-VM -Name vm01) # vm01 の設定を変更する
$newvm = @(Get-VM -Name vm01) .\Compare-HyperVVMS.ps1 $oldvm $newvm
|
答えは、差分はまったく検出されません。なぜなら、「vol.235 Get-VMで状態を取得する裏技|Hyper-V 小技・裏技集」で説明したように、Microsoft.HyperV.PowerShell.VirtualMachineタイプのオブジェクトのプロパティは動的に最新の情報を反映するからです。次のようにExport-Clixml/Import-Clixmlすることでオブジェクトのメンバーをデシリアライズ化(Deserialized.Microsoft.HyperV.PowerShell.
VirtualMachine)すれば、$newvmsと比較できるようになります。
|
$oldvm = @(Get-VM -Name vm01) $oldvm | Export-Clixml .\oldvm.xml
$oldvm = @(Import-Clixml .\oldvm.xml)
# vm01 の設定を変更する
$newvm = @(Get-VM -Name vm01) .\Compare-HyperVVMS.ps1 $oldvm $newvm
|
今回まで使用してきた棚卸データは、後から構成情報を比較できるよう、できるだけ多くの情報を、可能な限り元の形式(PowerShellオブジェクトの構造と型)を保って保存するという考えに基づいています。これまで、概要の参照や差分の検索に使うスクリプトをいくつか紹介しました。スクリプトが対応していない情報についても、保存されたデータのプロパティを直接参照したり、必要に応じてスクリプトを作成したりすることで活用できます。
次回からは少し視点を変え、資産としてのVMやVHDの管理について検討します。
サーバー設定仕様書の自動生成サービス、SSD-assistanceのご紹介
弊社の主力製品の1つ設定仕様書自動生成サービス「SSD-assistance」は、設定仕様書作成のためのデータ収集やドキュメント作成の手間と時間を省き、高品質で標準化された設定仕様書を自動生成するサービスです。SSD-assistanceは、「Hyper-V ホスト 設定仕様書」の作成に対応している上、「差分比較リスト」で構成の変更差分を視覚的に強調表示させることができます。ここまでの記事でやってきたことと同等のことは、実はSSD-assistanceを利用すれば誰でも、簡単に、すぐに実現することができます。ただこの連載記事では、SSD-assistanceでは手の届かない、Hyper-Vの深くて、細かいところまで手を伸ばせればと考えています。
Hyper-Vホスト設定仕様書のサンプル(クリックで拡大)
|
差分比較リストのサンプル(クリックで拡大)
|
|
リファレンス(Microsoft Learn):
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)|Export-Clixml(PowerShell Utility)|Import-Clixml(PowerShell Utility)
Hyper-V 小技・裏技集 目次|(1) |(2)|(3)|(4)|(5)