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

セイテクエンジニアのブログ  かつて山市良と呼ばれたおじさんのブログ  vol.127 オフラインスキャンの自動化に挑む|どうする!?残る閉域網の更新管理(2)

 

 

vol.127 オフラインスキャンの自動化に挑む|どうする!?残る閉域網の更新管理(2)

2025年08月04日配信
執筆者:山内 和朗

 前回(vol.126)から、「Windows Updateエージェント(WUA) API」を利用して、共有フォルダーを介して更新カタログと更新プログラムをクローズドネットワーク(閉域網)内のデバイスやサーバーに更新プログラムを展開する方法を検討しています。前回は手動で対話的にPowerShellのコマンドラインやスクリプトを実行して、オフラインスキャンを行い、利用可能な更新プログラムを確認しました。この部分をもう少し自動化してみたいと思います。

 

Windows Update エージェント API|Windows アプリ開発(Microsoft Learn)

 

閉域網のための、“手作り”更新管理環境のおさらい

 

 図1に、構想している更新管理環境を示します。クローズドネットワーク(閉域網)内のファイルサーバーの1台に専用の共有フォルダーを設け、ここに更新カタログ(オフラインスキャン用のwsuscn2.cab)と更新プログラムを配置して、利用可能な更新プログラムを確認し、更新プログラムをダウンロードしてインストールするという方法です。

 

図1 共有フォルダーを利用した、クローズドネットワーク(網)内の更新管理環境
図1 共有フォルダーを利用した、クローズドネットワーク(閉域網)内の更新管理環境

 

オフラインスキャンを自動化するスクリプト

 

 前回は、共有フォルダー上の更新カタログファイル(wsusscn2.cab)を手動でコピーして、その後、Microsoft提供のPowerShellスクリプトを実行しました。今回は、この一連の作業を完全に自動化してみたいと思います。 

 

 次のPowerShellスクリプト「wuscanoffline.ps1」は、最更新カタログファイル(wsusscn2.cabが共有フォルダー上に配置されていると仮定して、利用可能な(このサーバーに不足している)更新プログラムを確認し、その結果をCSV(カンマ区切りテキスト)形式でファイル出力します。$logPathと$scancabPath変数に共有フォルダー上のログ出力先のUNCパス(この例ではログファイル名を「wuscan_コンピューター名.csv」にしています)と、更新カタログファイル(wsusscn2.cab)のUNCパスを指定してください。

 

[wuscanoffline.ps1]プレーンテキストで表示)

$logPath = "\\<ファイルサーバー名またはIPアドレス>\<共有名>\logs\wuscan_$(hostname).csv"
$scancabPath = "\\<ファイルサーバー名またはIPアドレス>\<共有名>\wsusscn2.cab"
if (Test-Path $scancabPath) {
  Write-Host "Scanning start using $scancabPath ..."
  Copy-Item $scancabPath "$env:Temp\mywsusscn2.cab" -Force
  $scancabPath = "$env:Temp\mywsusscn2.cab"
  #pause
} else {
  Write-Host $scancabPath "not found. Nothing to do."
  #pause
  exit 1
}
$UpdateSession = New-Object -ComObject Microsoft.Update.Session
$UpdateServiceManager = New-Object -ComObject Microsoft.Update.ServiceManager
$UpdateService = $UpdateServiceManager.AddScanPackageService("Offline Sync Service", $scancabPath)
$UpdateSearcher = $UpdateSession.CreateUpdateSearcher()

Write-Host "Searching for updates..."
$UpdateSearcher.ServerSelection = 3 # ssOthers
$UpdateSearcher.ServiceID = [string] $UpdateService.ServiceID
$SearchResult = $UpdateSearcher.Search("IsInstalled=0")
$Updates = $SearchResult.Updates
Remove-Item $scancabPath
If ($SearchResult.Updates.Count -eq 0) {
  Write-Host "There are no applicable updates."
  #pause
  exit 0
}
Write-Host "List of applicable items on the machine when using wssuscan.cab:"
$results = @()
For ($i = 0; $i -lt $SearchResult.Updates.Count; $i++) {
  $update = $SearchResult.Updates.Item($i)
  Write-Host ($i + 1) "> " $update.Title
  $kbID = ""
  if ($update.Title -match 'KB\d{6,7}') {
    $kbID = $matches[0]
  }
  $results += [PSCustomObject]@{
    Title = $update.Title
    KBid = $kbID
    Support = "https://support.microsoft.com/kb/" + $kbID.Substring(2)
    Catalog = "https://catalog.update.microsoft.com/Search.aspx?q=" + $kbID
  }
}

$results | Export-Csv -Path $logPath -NoTypeInformation -Encoding UTF8
#pause
exit 0

 

 このPowerShellスクリプトを更新対象のサーバーで実行すると、ログファイルの出力先にCSV形式で利用可能な更新プログラムの一覧が出力されます。ログファイルには、更新プログラムのタイトルに加えて、KB番号、Microsoftサポート情報へのリンク、およびMicrosoft Udpateカタログへのリンクが一覧で出力されます(画面1)。 タスクスケジューラで定期的に自動実行するようにしておけば(例えば、毎月の第2および第3水曜日)、完全に自動化することができます(画面2)。その場合、共有フォルダーにパススルー認証など(同名、同パスワードのユーザーによる接続)、パスワード入力なしで接続できる必要があります。資格情報が必要な場合は、接続状態を保存することで対応できます。また、タスクは、ビルトインAdministratorなどの管理者で、ログオンしているかどうかに関係なく実行するように構成します(ネットワーク共有に接続するためSYSTEMは不可)。

 

画面1 PowerShellスクリプト「wuscanoffline.ps1」を実行すると、共有フォルダー上の更新カタログファイル(wsusscn2.cab)を使用して利用可能な更新プログラムを検索し、CSVでその結果(Microsoft Updateカタログへのリンクを含む)を出力する

画面1 PowerShellスクリプト「wuscanoffline.ps1」を実行すると、共有フォルダー上の更新カタログファイル(wsusscn2.cab)を使用して利用可能な更新プログラムを検索し、CSVでその結果(Microsoft Updateカタログへのリンクを含む)を出力する

 

画面2 タスクスケジューラーに「powershell.exe」、引数「<パス>¥wuscanoffline.ps1」を定期的に実行するタスクを登録する

画面2 タスクスケジューラに「powershell.exe」、引数「<パス>¥wuscanoffline.ps1」を定期的に実行するタスクを登録する

 

 後は、CSVファイルを参照して、インターネットアクセスが可能なデバイスからMicrosoft Updateカタログにアクセスし、更新プログラムのインストーラー(MSU)をダウンロードし、共有フォルダーのサブフォルダー(この例ではWS2022MSU、※マシンごとまたはWindowsのバージョンごとに分けることをお勧めします)に配置しておきます。インストールの自動化については、次回紹介します。

 

画面3 インターネットアクセスが可能なデバイスで更新プログラムをダウンロードし、共有フォルダーに配置しておく

画面3 インターネットアクセスが可能なデバイスで更新プログラムをダウンロードし、共有フォルダーに配置しておく

 

更新カタログファイル(wsusscn2.cab)を自動更新するスクリプト

 

 更新カタログファイル(wsusscn2.cab)は通常、米国時間の第2火曜日に最新版がリリースされますが、1日程度遅れることもあります。次のPowerShellスクリプト「getscancab.ps1」は、更新カタログファイル(wsusscn2.cab)をダウンロードし、現在の更新カタログファイルとファイルサイズが一致しない場合に、更新版であると判断して、新しい更新カタログファイルに入れ替えます。

 

 インターネットアクセス可能なサブネットと閉域網のサブネットの両方に接続されたマルチホームなファイルサーバーの場合は、この方法で自動的に最新の更新カタログファイルを共有フォルダーに配置できます(画面4)。このスクリプトを利用するには、$logPathと$scancabCurrent変数の設定が必要です。このスクリプトは、共有フォルダーをホストする(インターネットアクセスが可能な)ファイルサーバーのタスクスケジューラで定期的に自動実行するようにタスクを登録します。

 

[getscancab.ps1]プレーンテキストで表示)

function Write-Log {
param (
[string]$Message,
[string]$LogPath = "$env:TEMP\getscancab.log"
)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$entry = "[$timestamp] $Message"
Add-Content -Path $LogPath -Value $entry
}
$LogPath = "<ログの保存先パス>\getscancab.log"

Write-Log -Message "Check the latest wsusscn2.cab." -LogPath $LogPath

$scancabCurrent = "<更新カタログファイルの保存先パス>\wsusscn2.cab"
$scancabTemp = "$env:TEMP\wsusscn2.cab"

#https://go.microsoft.com/fwlink/?LinkID=74689
# -> https://catalog.s.download.windowsupdate.com/microsoftupdate/v6/wsusscan/wsusscn2.cab
Invoke-WebRequest -uri https://go.microsoft.com/fwlink/?LinkID=74689 -outfile $scancabTemp -UseBasicParsing

if (Test-Path $scancabCurrent) {
if ((Get-Item $scancabTemp).Length -eq (Get-Item $scancabCurrent).Length) {
Remove-Item $scancabTemp -Force
Write-Log -Message "Current wsusscn2.cab is up-to-date." -LogPath $LogPath
} else {
Remove-Item $scancabCurrent -Force
Move-Item -Path $scancabTemp -Destination $scancabCurrent
Write-Log -Message "Updated to the latest wsusscn2.cab." -LogPath $LogPath
}

} else {
Move-Item -Path $scancabTemp -Destination $scancabCurrent
Write-Log -Message "Downloaded to the latest wsusscn2.cab." -LogPath $LogPath
}

 

画面4 定期的に更新カタログファイル(wsusscn2.cab)をダウンロードし、変更があれば差し替えるスクリプト

画面4 定期的に更新カタログファイル(wsusscn2.cab)をダウンロードし、変更があれば差し替えるスクリプト

 

 次回は、Microsoft Updateカタログからダウンロードして共有フォルダーに配置した更新プログラムを、対象のサーバーに自動インストールすることに挑戦します。

 

どうする!?残る閉域網の更新管理(1)|(2)

blog_yamanxworld_subscribe

blog_yamanxworld_comment

blog_yamanxworld_WP_ws2025

最新記事