Hyper-V仮想マシンの作成と削除をできる限りコマンド一発で行いたい

# 経緯
Intuneの検証のためにHyper-VでWin10/11のVMを頻繁に作成するのですが、長年GUIでポチポチと律儀に作成しておりましたが、今回PowerShellである程度簡易化できましたので共有させて頂きます。

# VM作成スクリプト
・対話型で名前・CPUコア数・メモリ・VHDXサイズを指定します。
・作成後、結果を表示します。
・VMConnect（仮想マシン接続アプリ）を自動で立ち上げます。
・1～3行目を変更して下さい。

```CreateVM.ps1
$VMName = Read-Host "VMName"
$VHDPath = "D:\Hyper-V\$VMName.vhdx"
$InstallMediaPath = "D:\Hyper-V\ISO\Win11_23H2_Japanese_x64.iso"
$CPUCores = Read-Host "CPU cores"
$Memory = Read-Host "Memory Size"
$MemoryBytes = [int]$Memory * 1GB
$DiskSize = Read-Host "VHDX Size"
$DiskSizeBytes = [int]$DiskSize * 1GB
$VHDXType = Read-Host -Prompt "VHDX Type: D for Dynamic, F for Fixed"
while ($VHDXType -ne "D" -and $VHDXType -ne "d" -and $VHDXType -ne "F" -and $VHDXType -ne "f") {
    Write-Host "Invalid input"
    $VHDXType = Read-Host -Prompt "VHDX Type: D for Dynamic, F for Fixed"
}
if ($VHDXType -eq "D" -or $VHDXType -eq "d") {
    $VHDXType = "Dynamic"
} else {
    $VHDXType = "Fixed"
}

New-VM -Name $VMName -MemoryStartupBytes $MemoryBytes -NewVHDPath $VHDPath -NewVHDSizeBytes $DiskSizeBytes -Generation 2
Set-VMProcessor $VMName -Count $CPUCores
Set-VMKeyProtector -VMName $VMName -NewLocalKeyProtector
Set-VMMemory -VMName $VMName -DynamicMemoryEnabled $true -MinimumBytes 512MB -StartupBytes $MemoryBytes -MaximumBytes $MemoryBytes
Enable-VMTPM -VMName $VMName
Add-VMDvdDrive -VMName $VMName -Path $InstallMediaPath
$DVD = Get-VMDvdDrive -VMName $VMName
Set-VMFirmware $VMName -FirstBootDevice $DVD
Start-VM -Name $VMName

$VMInfo = Get-VM $VMName | Select-Object Name, State, @{Name="CPU"; Expression={$_.ProcessorCount}}, @{Name="MemoryGB"; Expression={[math]::Round($_.MemoryAssigned / 1GB, 2)}}, Version | Format-Table -AutoSize | Out-String
Write-Host "VM Information:"
Write-Host $VMInfo

$VHDXInfo = Get-VHD $VHDPath | Select-Object Path, @{Name="SizeGB"; Expression={[math]::Round(($_.Size / 1GB), 2)}}, VhdType | Format-Table -AutoSize | Out-String
Write-Host "VHDX Information:"
Write-Host $VHDXInfo

vmconnect $env:COMPUTERNAME $VMName
Pause
```
3/23追記：
・動的メモリ設定を追加しました。
・TPM設定を追加しました。
・VHDXタイプの動的・静的の選択を追加しました。

# 実行イメージ

・対話型で名前・CPUコア数・メモリ・VHDXサイズを指定します。
・作成後、結果を表示します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/9c37906b-5190-bdce-f9b5-83d193265e03.png)


・VMConnect（仮想マシン接続アプリ）を自動で立ち上げます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/a238b4f9-9f02-a3f4-f0fd-771b4d280897.png)

・GUIでも正常に起動しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/a0b2618b-41cb-3445-ef7b-44a86a28218f.png)


# VM削除スクリプト
・入力を受け付ける形にして誤削除を避けます。
・同様にVHDXは削除しないようにしています。

```StopDeleteVM.ps1
$VMName = Read-Host "VMName"; `
Stop-VM -Name $VMName; `
Remove-VM -Name $VMName; `
Pause
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/2ddedc5d-2121-6bd6-8aca-50d655848284.png)

# まとめ
・GUIだとVMの作成に数分はかかっていましたが、時間というより面倒さがありました。
・PowerShellにしたことでその心理的ハードルが低くなるのは良かったと思います。

# 補足
・仮想マシンをクローンではなく新規作成になりますので、EntraやIntuneでマシン情報（SID）が重複せずにすみます。
・Sysprep直後にシャットダウンした状態のVHDXをバックアップしておき、今回のスクリプトで作ったVMごとに上書きして付け替えるという方法もおすすめです。
・最近SSDやCPUの進化がすごく、クライアントHyper-Vで十分にVMを運用できるようになってきました。
・もうProxmoxじゃなくてHyper-Vでいいのでは・・・？