基本的な内容については Windows 8 / Windows Server 2012 では 「自動インストール」 の動作が変更されております/ Windows Update 処理を厳密に制御したい を確認していただければ。
こちらの投稿は私の備忘録となります。
最初に紹介させていただいた記事に書かれている通りなのですが、Windows Server 2012 / 2012 R2 では Windows Update の自動インストールの動作が変更されており、自動メンテナンスにより Windows Update の実行が行われるようになっています。
そのため、更新プログラムの適用については、「更新プログラムはメンテナンス中に自動的にインストールされます。」となっており、GPO で特定の時間に適用をするように設定しても、2012 / 2012 R2 では、時刻が固定されない設定となっています。
自動メンテナンスですが、予定時刻としては 2:00 が設定されており、この設定はタスクスケジューラーからも確認することができます。
タスクスケジューラーとしては、「\Microsoft\Windows\TaskScheduler」の「Regular Maintenance」のタスクとなるようです。
# アクションセンターからメンテナンスを手動で実行した場合は「Manual Maintenance」が実行されるようです。
このタスクを表示した状態で F5 で最新の情報に更新すると、次回の実行時刻が変化していきますので、厳密な時間設定はできないんだなということがわかるかと。
特定の曜日 / 時間にインストールを実行したい場合は、「更新プログラムを確認するが、ダウンロードとインストールを行うかどうかは選択する」を指定して、タスクスケジューラー等で定期的にバッチを実行することで実装する形になるようです。
バッチのサンプルは、SCE / WSUS :今すぐに更新ファイルやソフトウェアをインストールしたい その2 検索編 / Searching, Downloading, and Installing Updates / Invoke-WindowsUpdate を参考にすると作れるかと。
WSH を使う理由もないかと思いますので、PowerShell ベースの Invoke-WindowsUpdate を参考にするとよいかなと思います。
単純な適用でしたら以下のようなスクリプトを定期的に実行すればよい感じでしょうか。
# ざっくり動作するぐらいの確認しかしていませんが。
ギャラリーのものはオプションもインストールするようになっていますが、以下のスクリプトでは除外しています。
フィルターの条件は IUpdateSearcher::Search method から確認できます。
$ErrorActionPreference = "Stop" $AutoRestart = $true $AutoRestartIfPending = $true $LogPath = Split-Path $MyInvocation.MyCommand.Path -Parent $LogFile = "WindowsUpdateShell.log" function Write-WindowsUpdateLog ($Message) { $Output = "{0} {1}" -f (Get-Date), $Message Write-Output $Output $output | Out-File (Join-Path $LogPath -ChildPath $LogFile) -Append -Encoding utf8 } try{ Write-WindowsUpdateLog "Checking for available updates Start" #Checking for available updates $updateSession = new-object -com "Microsoft.Update.Session" $criteria="IsInstalled=0 and Type='Software' and BrowseOnly = 0" $updates=$updateSession.CreateupdateSearcher().Search($criteria).Updates $downloader = $updateSession.CreateUpdateDownloader() $downloader.Updates = $Updates Write-WindowsUpdateLog "Checking for available updates End" #If no updates available, do nothing if ($downloader.Updates.Count -ne "0") { #If updates are available, download and install Write-WindowsUpdateLog "Downloading $($downloader.Updates.count) updates" $resultcode= @{0="Not Started"; 1="In Progress"; 2="Succeeded"; 3="Succeeded With Errors"; 4="Failed" ; 5="Aborted" } $Result= $downloader.Download() if (($Result.Hresult -eq 0) -and (($result.resultCode -eq 2) -or ($result.resultCode -eq 3)) ) { $updatesToInstall = New-object -com "Microsoft.Update.UpdateColl" foreach ($Update in $Updates | where {$_.isdownloaded} ){ $updatesToInstall.Add($Update) | out-null Write-WindowsUpdateLog $Update.Title } $installer = $updateSession.CreateUpdateInstaller() $installer.Updates = $updatesToInstall Write-WindowsUpdateLog "Update Install Start" $installationResult = $installer.Install() Write-WindowsUpdateLog "Update Install End" #Reboot if autorestart is enabled and one or more updates are requiring a reboot if ($autoRestart -and $installationResult.rebootRequired) { Write-WindowsUpdateLog "Status is Reboot Required. Reboot Start" Restart-Computer -Force Exit } } } if (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired"){ if ($AutoRestartIfPending) { Write-WindowsUpdateLog "Status is Auto Restart Pending. Reboot Start" Restart-Computer -Force } } }catch{ Write-WindowsUpdateLog $_ Write-WindowsUpdateLog "Windows Update Error" }
2012 / 2012 R2 でも、標準機能で曜日と時間指定してインストールできてもいいじゃないと思う気持ちが無きにしも非ず。