Windows Updateの深淵を覗く:Microsoft.Update.Sessionによる「未適用KB」自動診断の極意
現場のエンジニア諸君、今日もレガシーな環境での運用保守にお疲れ様だ。
「Windows Updateの適用状況を管理したいが、数百台の端末をイチイチ確認するのは現実的ではない」。そんな相談を受けたとき、多くのエンジニアはGUIのポチポチ作業か、あるいは不安定なPowerShellスクリプトを書き散らす。だが、我々が扱うべきはWSH(Windows Script Host)の心臓部だ。
今回は、`Microsoft.Update.Session`を直接叩き、端末の「真の姿」を浮き彫りにする、堅牢かつ即戦力なVBScriptの設計術を伝授する。
—
1. なぜ「WUA API」を選択するのか
PowerShellの`Get-WindowsUpdate`などのモジュールは便利だが、環境によって実行ポリシーや依存関係でコケるリスクがある。対して、WUA (Windows Update Agent) APIはWindows OSの基幹コンポーネントであり、OSのバージョンに左右されにくい「枯れた」技術だ。
VBScriptでこれを扱う際の最大の敵は「タイムアウト」と「COMオブジェクトの解放」だ。これらを甘く見ると、WSHプロセスがメモリを食いつぶし、CPU使用率を跳ね上げる「ゾンビスクリプト」と化す。
—
2. 堅牢な診断スクリプト:プロダクションコード
このスクリプトは、単に更新プログラムをリストアップするだけではない。エラーハンドリングを徹底し、ログファイルへ即座に吐き出す設計にしている。
‘ — WUA_Diagnostic.vbs —
Option Explicit
Dim objSession, objSearcher, objResult, objUpdate
Dim strLogPath, objFSO, objFile
‘ ログファイルの設定
strLogPath = “C:\Temp\UpdateStatus_” & Replace(Date, “/”, “”) & “.log”
Set objFSO = CreateObject(“Scripting.FileSystemObject”)
Set objFile = objFSO.OpenTextFile(strLogPath, 8, True) ‘ 追記モード
On Error Resume Next
‘ セッションの確立
Set objSession = CreateObject(“Microsoft.Update.Session”)
If Err.Number <> 0 Then
objFile.WriteLine “Error: WUA APIの初期化に失敗しました。”
WScript.Quit
End If
‘ 検索オブジェクトの生成
Set objSearcher = objSession.CreateUpdateSearcher()
objFile.WriteLine “診断開始: ” & Now
‘ 「インストールされていない」かつ「隠されていない」更新プログラムを検索
‘ 検索クエリはSQLライクな構文を使用
Set objResult = objSearcher.Search(“IsInstalled=0 and Type=’Software'”)
If objResult.Updates.Count = 0 Then
objFile.WriteLine “未適用の更新プログラムはありません。”
Else
objFile.WriteLine “未適用KB一覧:”
For Each objUpdate In objResult.Updates
objFile.WriteLine “KB: ” & objUpdate.KBArticleIDs(0) & ” | Title: ” & objUpdate.Title
Next
End If
objFile.WriteLine “診断終了: ” & Now
objFile.Close
‘ オブジェクト解放(ライフサイクル管理)
Set objResult = Nothing
Set objSearcher = Nothing
Set objSession = Nothing
Set objFSO = Nothing
On Error GoTo 0
—
3. 実務で「ハマる」ポイントと回避策
① 検索のタイムアウト問題
ネットワーク環境が悪い場合、`objSearcher.Search`はハングアップしたように見えることがある。本番環境で運用する場合は、WMI経由でプロセスを監視し、一定時間経過したら`Terminate`をかけるラッパースクリプトを外側に用意するのが定石だ。
② ファイルロックの回避
今回のコードでは`OpenTextFile(…, 8, True)`を使用している。これは「追記モード」であり、ファイルが存在しなければ作成する。複数台で同時に実行し、ネットワーク共有フォルダにログを吐かせる場合は、ファイル名にホスト名(`CreateObject(“WScript.Network”).ComputerName`)を必ず含めること。さもなくば、排他制御でスクリプトがクラッシュする。
③ 権限の壁
WUA APIの操作には「管理者権限」が必須だ。一般ユーザー権限で実行しても検索結果が空(あるいはエラー)になる。配布時は、タスクスケジューラにて「最上位特権で実行」を有効にすることを忘れてはならない。
—
4. チーフアーキテクトからの助言
「自動化」とは、単にコードを書くことではない。「失敗したときに、なぜ失敗したかが即座にわかること」こそが、真の自動化だ。
今回のスクリプトをベースに、さらに上を目指すなら以下を実装せよ。
1. DB連携: CSVに出力するだけでなく、ADOを用いてSQL Server等へ直接Insertする。
2. 緊急度判定: `objUpdate.MsrcSeverity` プロパティを活用し、”Critical” なものだけを管理者にメール通知するロジックを追加する。
VBScriptは古い言語かもしれないが、OSの深淵を操るためのツールとしては、依然として超一流だ。使いこなせば、君は現場の誰よりも早く、正確に、システムの健康状態を掌握できる。
健闘を祈る。何かあれば、またコードの向こう側で会おう。
