PowerShell Direct で VM 展開を自動化してみる


Windows 10 / Windows Server 2016 から、PowerShell Direct という機能が増えています。

これを活用すると、Hyper-V ホストから VM の中に対してファイルをコピーしたり、コマンド実行ができるので、大量の VM を自動で展開できるようになります。例えば、Azure PowerShell のバージョン毎に VM を作るには以下のような感じ。

事前に応答ファイルを差し込んだ sysprep 済みの VHD と、各バージョンの Azure PowerShell を用意しておく必要がありますが、その辺は説明が長くなるので今回は書きません。(わからない人は、応答ファイルとか unattend とか sysprep といったキーワードで検索すればいくらでも情報でるので調べてください。)

# Azure PowerShell のインストーラーを配置したフォルダー
$PowerShellInstallder = Get-ChildItem 'C:\Users\Administrator\Desktop\Azure PowerShell'

# Azure PowerShell のインストーラー分だけ VM を作成
$PowerShellInstallder | foreach{
    # ファイル名 (azure-powershell.1.0.0.msi) からバージョンを抽出
    $Ver = $_.Name -replace 'azure-powershell.', '' -replace '.msi', ''

    # 仮想マシン名の Prefix を定義
    $VMName = 'Win 10 Ent x64 with Azure PowerShell $Ver'

    # sysprep 済みのマスター イメージをコピー
    Copy-Item -Path 'D:\Win 10 Ent x64 with Azure PowerShell Master.vhdx' -Destination 'D:\Win 10 Ent x64 with Azure PowerShell $Ver.vhdx'

    # コピーした VHD をもとに VM を作成
    New-VM -Name $VMName -VHDPath 'D:\Win 10 Ent x64 with Azure PowerShell $Ver.vhdx'

    # VM のコア数、メモリ、NIC などを任意でカスタマイズ
    Set-VMProcessor -VMName $VMName -Count 16
    Set-VMMemory -VMName $VMName -DynamicMemoryEnabled $true
    Set-VMNetworkAdapter -VMName $VMName
    Get-VMNetworkAdapter -VMName $VMName | Connect-VMNetworkAdapter -SwitchName external

    # VM を起動
    Start-VM -Name $VMName
}

上記は空の VM を作っただけなので、続いてインストーラーを VM 内にコピーして実行します。
あわせて、せっかくなので Windows PowerShell の Execution Policy とか、Explorer のレジストリも一緒に設定しています。

$PowerShellInstallder | foreach{
    # 各種変数を設定
    $FullPath = $_.FullName
    $FileName = $_.Name
    $Ver = $_.Name -replace 'azure-powershell.', '' -replace '.msi', ''
    $VMName = 'Win 10 Ent x64 with Azure PowerShell $Ver'
    $InstallerPath = 'C:\Users\Public\Documents\$FileName'

    # 新規セッションを確立
    $Session = New-PSSession -VMName $VMName -Credential $Cred

    # VM 内で実行する処理の定義
    $DeployScript = '
    reg add HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced /v LaunchTo /t REG_DWORD /d 1 /f
    reg add HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer /v ShowRecent /t REG_DWORD /d 0 /f
    reg add HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer /v ShowFrequent /t REG_DWORD /d 0 /f
    reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced /v HideFileExt /t REG_DWORD /d 0 /f
    reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced /v Hidden /t REG_DWORD /d 1 /f
    reg add HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell /v EnableScripts /t REG_DWORD /d 1 /f
    reg add HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\PowerShell /v ExecutionPolicy /t REG_SZ /d RemoteSigned /f
    Start-Process -FilePath $InstallerPath -ArgumentList '/quiet' # Azure PowerShell のサイレント インストール
    '

    # 上記で定義した内容を、一旦ローカルに保存
    Out-File -InputObject $DeployScript -FilePath $env:TEMP\deploy.ps1

    # VM 内に Azure PowrShell のインストーラーをコピー
    Copy-Item -ToSession $Session -Path $FullPath -Destination 'C:\Users\Public\Documents'

    # VM 内でインストール処理を実行
    Invoke-Command -VMName $VMName -Credential $Cred $env:TEMP\deploy.ps1
}

以上で各バージョンがインストールされた VM が大量に生成され、インストールも完了していることが確認できます。
VHD のコピーには結構時間がかかるので、NVMe SSD とかを使うと快適ですね。

vmms

vm


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください