かつて山市良と呼ばれたおじさんのブログ

セイテクエンジニアのブログ  かつて山市良と呼ばれたおじさんのブログ  vol.240 自動化スクリプト ─ Windows Update|Hyper-V 小技・裏技集

 

 

vol.240 自動化スクリプト ─ Windows Update|Hyper-V 小技・裏技集

2026年10月08日配信
執筆者:山内 和朗

 「Hyper-V小技・裏技集」シリーズでは、Hyper-Vの仮想環境を利用していて、知っていると便利な小技や裏技を紹介します。vol.237では、PowerShell DirectとCopy-VMFileの使いこなしについて説明しました。これらを活用した、VMのゲスト側タスクの自動化例を紹介しています。

 

※ここで紹介するサンプルコードは、PowerShellスクリプト(.ps1)内に記述することを想定しています。-ErrorAction Stopパラメーターは、エラー時にスクリプト全体を停止します。PowerShellウィンドウに入力して実行した場合は、エラーが発生しても以後のスクリプトは停止しないため、別のエラーが発生する可能性があることに注意してください。

 

※9月17日(木)開催、第8回 セイテク・シス管道場のアーカイブビデオが公開されました。
お知らせ. 9月17日(木)開催の第8回 セイテク・シス管道場のアーカイブ視聴が可能になりました [2026.10.06]

 

VMゲストのWindows Updateをホストから完全制御

 

 前回は、Hyper-Vホスト側に用意したテスト用スクリプトをCopy-VMFileを使用してVMのゲストにコピーし、Invok-Commandを使用してリモート実行するという、VMを利用したテストの自動化スクリプトを紹介しました。今回は、同じ方法を利用して、以下の記事で紹介したWindows Update用PowerShellスクリプト「WUA_SearchDownloadInstall.ps1」をリモート実行させ、更新後の再起動までを自動化してみたいと思います。Hyper-Vホストから、Windows VMのWindows Updateを完全制御するスクリプトです。

 

vol.124 WUA_SearchDownloadInstall.vbsのPowerShell化|Windowsトラブル解決[2025年07月24日配信]

 

 WUA_SearchDownloadInstall.ps1は、Microsoftがサンプルとして公開している「WUA_SearchDownloadInstall.vbs」の主要な機能を私がPowerShell化したものです。Windows Updateの更新プログラムの検索からダウンロード、インストールまではWUA_SearchDownloadInstall.ps1の-Automateパラメーターを使用します。WUA_SearchDownloadInstall.ps1には、再起動まで自動化する-CompleteToShutdownパラメーターも存在しますが、WUA_SearchDownloadInstall.ps1では再起動させず、別の方法(レジストリの参照)で再起動を判断しています。

 

 今回作成したPowerShellのコードは、次の一連の作業を自動化します(画面1)。

 

  • ロールバック用にVMのチェックポイントを作成する。

  • VMの統合サービスの「ゲスト サービス インターフェイス」の現在の設定を保存する。

  • VMの統合サービスの「ゲスト サービス インターフェイス」が無効の場合は有効化する。

  • WUA_SearchDownloadInstall.ps1をVMゲストのC:¥にコピーする。

  • VMの統合サービスの「ゲスト サービス インターフェイス」の設定を元に戻す。

  • Invoke-CommandでWUA_SearchDownloadInstall.ps1 -Automateをリモート実行する。

  • レジストリを参照して再起動の必要性を判断する。

  • 再起動が必要な場合は、再起動を開始する。

  • 複数回再起動の可能性を考慮し、VMのHeatbeatが900秒(15分)間連続して“Ok*”であれば、再起動完了と見なす。

  • VMをシャットダウンして停止する。

 

#$cred = Get-Credential
# または
#(事前に Get-Credential | Export-Clixml $HOME\vm01-cred.xml でXMLを作成)
#$cred = Import-Clixml $HOME\vm01-cred.xml
# または
$username = ".\Administrator"
$password = "P@ssw0rd!"
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
$cred = [PSCredential]::new($username, $securePassword)

$vmName = "vm01"
# https://www.say-tech.co.jp/contents/blog/yamanxworld/2025vol124
$updateScriptPath = "E:\Tools\WUA_SearchDownloadInstall.ps1"
$guestTargetPath = "C:\"

$vm = Get-VM -Name $vmName -ErrorAction Stop

# チェックポイントの作成
$vm | CheckPoint-VM -SnapshotName "Pre Update"

# ゲスト サービスの現在の設定の退避と有効化
$guestSvcDefault = (Get-VMIntegrationService -VMName $vm.Name "ゲスト サービス インターフェイス").Enabled
if (!$guestSvcDefault) {
  Enable-VMIntegrationService -VMName $vm.Name "ゲスト サービス インターフェイス"
}

# VMの開始(ゲスト起動まで待機)
$vm | Start-VM -ErrorAction Stop
Write-Host "`r$($vm.Name) is Starting...        " -NoNewLine
While ($vm.Heartbeat -notlike "Ok*") {
   Start-Sleep 1
}
Write-Host "`r$($vm.Name) is Online              " -NoNewLine

# Windows Update Scriptをゲストにコピー
Write-Host "`rStart Windows Update...            " -NoNewLine
Copy-VMFile -Name $vm.Name -SourcePath $updateScriptPath -DestinationPath $guestTargetPath -FileSource Host -Force

# ゲスト サービスを以前の設定に戻す
if (!$guestSvcDefault) {
  Disable-VMIntegrationService -VMName $vm.Name "ゲスト サービス インターフェイス"
}

# Windows Update スクリプトの実行
$updateScript = Join-Path "C:\" (Split-Path $updateScriptPath -Leaf)
Invoke-Command -VMName $vm.Name -Credential $cred -ScriptBlock { & $using:updateScript -Automate }

# 再起動待ち?
$rebootReq = Invoke-Command -VMName $vm.Name -Credential $cred -ScriptBlock {if ((Test-Path "HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired") -or (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending")) { return $true } else { return $false } }

# 再起動待ちなら再起動
if ($rebootReq) {
    Write-Host "`rReboot required to complete update." -NoNewLine
    Invoke-Command -VMName $vm.Name -Credential $cred -ScriptBlock {Restart-Computer -Force}
    # Wait until "NoConnect"
    while ($vm.HeartBeat -like "Ok*") {
        Write-Host "`rConfiguring Windows Update...         " -NoNewLine
        start-sleep 1
    }
    Write-Host "`r$($vm.Name) is Restarting...        " -NoNewLine

    # Wait "Ok*" 900 seconds in a row
    $countdown = 900
    while ($countdown -gt 0) {
        if ($vm.HeartBeat -like "Ok*") {
            Write-Host "`rPlease wait $($countdown) sec...       " -NoNewLine
            $countdown--
        } else {
            Write-Host "`r$($vm.Name) is Restarting...              " -NoNewLine
               if ($countdown -ne 900) {
               $countdown = 900
            }
        }
        start-sleep 1
    }
}

# VMのシャットダウン
Write-Host "`r$($vm.Name) is Stopping...              " -NoNewLine
$vm | Stop-VM -Force -ErrorAction Stop
While ($vm.State -ne "Off") {
    Start-Sleep 1
}
Write-Host "`r$($vm.Name) is Off                      " -NoNewLine

(プレーンテキストでダウンロード/表示)

※ この例のようにスクリプト内に平文パスワードを記述することは推奨されません。平文パスワードを排除する方法については、vol.238の「スクリプトから平文パスワードを排除する簡単な方法」を参照してください。

 

画面1 VMを起動し、Windows Updateを実行して、再起動、シャットダウンまでを自動化するPowerShellスクリプトの実行例(画面のクリックで拡大)
画面1 VMを起動し、Windows Updateを実行して、再起動、シャットダウンまでを自動化するPowerShellスクリプトの実行例(画面のクリックで拡大)

 

 今回、再起動の必要性の判断には次のコードを使用しました。レジストリの2つの場所のいずれかにRebootRequiredキーが存在すれば再起動待ちの状態と判断できます。

 

if ((Test-Path "HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired") -or `
  (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending")) { 
    return $true 
} else {
    return $false
}

 

 Windows Updateを完了させるための再起動は、複数回、再起動が行われることがあり、PowerShellのコードには複数回の再起動を吸収するコードが含まれています。以下に、実際の実行例をビデオにしました。複数回の再起動を待機できていることを確認できるでしょう。

 

ビデオ: PowerShellでVMのゲストのWindows Updateを自動化

 

リファレンス(Microsoft Learn):
Get-VM(Hyper-V)| Start-VM(Hyper-V)| Stop-VM(Hyper-V)| Checkpoint-VM(Hyper-V)| Invoke-Command(PowerShell)| Copy-VMFile(Hyper-V)| Export-Clixml(PowerShell)| Import-Clixml(PowerShell)| Windows Update Agent API(Windows アプリ開発)


Hyper-V 小技・裏技集 (1)|(2)|(3)|(4)|(5)|(6)|(7)|(8)|(9)

blog_yamanxworld_subscribe

blog_yamanxworld_comment

blog_yamanxworld_WP_ws2025

最新記事