PowerShellでWindows Updateのダウンロード日時・再起動要求・インストール完了・成功失敗を標準機能で取得する方法

Windows Updateの運用では「いつダウンロードされたか」「いつ再起動が必要になったか」「再起動後にいつ完了したか」「成功/失敗」を標準機能だけで追いたい場面がよくあります。本記事ではPowerShellで扱えるイベントログ、更新履歴(COM API)、CBS.log、DISMのパッケージ情報を組み合わせ、監査ログとして残す現実解とサンプルをまとめます。

目次

標準機能だけで把握できる情報と、把握しにくい情報

最初に押さえておきたいのは、Windows Updateの記録が1つの場所にまとまっていないことです。更新プログラムは「検出→ダウンロード(BITS/Delivery Optimization)→インストール(Windows Updateクライアント)→コンポーネント適用(CBS/TrustedInstaller)→再起動で確定」という複数の層で動きます。そのため、単一コマンドで4つの情報をすべて厳密に埋めるのは難しく、用途別に情報源を突き合わせるのが現実的です。

特に問題になりやすいのが「再起動待ちだった更新が、再起動後にいつ完了したのか」「どのKBが再起動で完了したのか」です。これはGUIの更新履歴と一致しないこともあり、Get-HotFix(Win32_QuickFixEngineering)のInstalledOnが更新されない・期待したイベントが残らない、といったズレが起きやすい領域です。

情報源の使い分け早見表

まずは、何をどこから取るべきかを表にします。以降の章で、それぞれをPowerShellでどう取るかを具体的に解説します。

知りたいこと第一候補(標準で扱いやすい)保険・補助実務上の注意点
ダウンロード日時WindowsUpdateClient/Operational のイベント(ダウンロード関連)Get-WindowsUpdateLog で生成した WindowsUpdate.log、BITS/Delivery Optimization のログ「完了時刻」が必ず残るとは限らない。関連イベントがローテーションで消えることもある。
再起動が必要になったタイミングWindowsUpdateClient/Operational の「再起動が必要」系イベント再起動保留レジストリキーの監視ログ(自前で記録)、CBS/Servicing のイベント“今再起動が必要か”はレジストリで分かるが、“いつ必要になったか”はログが頼り。
インストール完了日時(特に再起動後)CBS.log(コンポーネント適用の確定ログ)COM API QueryHistory(更新履歴の日時と成否)、DISMのパッケージ InstallTimeGet-HotFix は便利だが、再起動をまたぐ確定時刻や累積更新で弱いことがある。
成功/失敗WindowsUpdateClient/Operational の成功・失敗イベントQueryHistory の ResultCode、CBS.log のエラー行(0x~)“成功(エラーあり)”など中間状態もある。HResult も併記すると調査が速い。

準備:ログが残らない問題を先に潰す

「ログに期待した情報が出ない」原因の多くは、(1) そもそもチャンネルが無効、(2) ログサイズが小さくて上書き、(3) パッチ適用サイクルに対して保持期間が足りない、のいずれかです。まずはOperationalログを有効化し、サイズを増やしておくと後追い調査が楽になります。

WindowsUpdateClient/Operational を有効化する

管理者権限のPowerShellで次を実行します。既に有効なら何も変わりません。

# Windows Update クライアントの Operational ログを有効化
wevtutil sl "Microsoft-Windows-WindowsUpdateClient/Operational" /e:true

# 現在の設定確認(Enabled / MaxSize など)

wevtutil gl "Microsoft-Windows-WindowsUpdateClient/Operational"

ログの最大サイズを増やす

例として最大サイズを64MBに増やします(環境に合わせて調整してください)。更新頻度が高い端末ほど大きめが安心です。

# 最大ログサイズを 64MB(= 67108864 bytes)に設定
wevtutil sl "Microsoft-Windows-WindowsUpdateClient/Operational" /ms:67108864

あわせて、CBS.log(C:\Windows\Logs\CBS\CBS.log)は非常に大きくなりやすいログです。ディスク容量がタイトな環境では、CBSログのローテーションや保持方針も確認しておきましょう。

イベントログで「再起動要求」「成功/失敗」を確実に拾う

PowerShellのGet-WinEventを使うと、WindowsUpdateClient/Operational を時刻で絞って取得できます。まずは「どんなイベントが出ているか」を眺め、次に実運用で必要なフィルタ条件を固める流れがおすすめです。

直近の更新イベントをざっと確認する

$log = "Microsoft-Windows-WindowsUpdateClient/Operational"

Get-WinEvent -LogName $log -MaxEvents 50 |
Select-Object TimeCreated, Id, LevelDisplayName, Message |
Format-Table -AutoSize

イベントのMessageには更新タイトルが含まれることが多く、累積更新なら「(KBxxxxxxx)」が入っていることもあります。KBが入らない場合でもタイトルやUpdateIDが取れることがあるため、後段でQueryHistoryやDISMと突き合わせる前提で収集しておくのが現実的です。

成功/失敗を抽出する(よく使うイベントID)

環境差はありますが、WindowsUpdateClient/Operational では「成功」「失敗」「再起動が必要」などがイベントとして出ます。まずは代表的なものだけ拾い、足りなければ後から追加する方式が運用しやすいです。

$start = (Get-Date).AddDays(-7)
$log   = "Microsoft-Windows-WindowsUpdateClient/Operational"

# 代表的なイベントID(例)

# 19: インストール成功 / 20: インストール失敗 / 21: 再起動が必要

$ids = 19,20,21

Get-WinEvent -FilterHashtable @{ LogName=$log; StartTime=$start; Id=$ids } |
Select-Object TimeCreated, Id, LevelDisplayName, Message |
Sort-Object TimeCreated

ここでポイントは、イベントだけで完結しようとしないことです。成功・失敗の判定はイベントでかなりの割合をカバーできますが、「再起動後に完了した更新の完了時刻」までイベントだけで追うとハマりやすいので、後述するCBS.logやDISMのInstallTimeで“確定情報”を取りにいきます。

メッセージからKB番号を取り出して整理する

タイトルにKBが含まれる場合は、正規表現で抜き出して表形式にすると追跡が楽です。

$events = Get-WinEvent -FilterHashtable @{ 
  LogName="Microsoft-Windows-WindowsUpdateClient/Operational"
  StartTime=(Get-Date).AddDays(-14)
  Id=@(19,20,21)
}

$events | ForEach-Object {
$kb = [regex]::Match($*.Message, 'KB\d{6,8}').Value
[pscustomobject]@{
TimeCreated = $*.TimeCreated
EventId     = $*.Id
KB          = if ($kb) { $kb } else { "" }
Message     = ($*.Message -replace "\s+", " ").Trim()
}
} | Sort-Object TimeCreated |
Format-Table -AutoSize

KBが空欄になるケースは珍しくありません。その場合は“Title寄りの文字列”としてMessageを残しておき、QueryHistoryやDISM側でKBが取れたタイミングで紐付ける、という設計にすると破綻しにくいです。

再起動が必要になったタイミングを「現在」と「過去」で分けて考える

再起動要求は二つの観点があります。ひとつは今このマシンは再起動待ちか、もうひとつはいつ再起動待ちになったかです。前者はレジストリで即座に判定できますが、後者はイベントログや自前記録が必要になります。

今、再起動が必要かを判定する(レジストリ)

標準機能だけで判定するなら、次の代表的なキーをチェックします。存在する=再起動が必要、という使い方が多いです(複数が立つこともあります)。

用途代表的なキー意味の傾向
Windows Update 由来の再起動待ちHKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired更新の完了に再起動が必要
CBS(コンポーネント適用)由来の再起動待ちHKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPendingコンポーネントの確定に再起動が必要
ファイル置換(汎用)由来の再起動待ちHKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations次回起動時にファイル置換が走る
# 再起動保留(Reboot Pending)を簡易判定する
$keys = @(
  "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired",
  "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending",
  "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager"
)

$result = [ordered]@{}
$result["WU_RebootRequired"] = Test-Path $keys[0]
$result["CBS_RebootPending"] = Test-Path $keys[1]
$result["PendingFileRename"] = (Get-ItemProperty -Path $keys[2] -Name PendingFileRenameOperations -ErrorAction SilentlyContinue) -ne $null

[pscustomobject]$result

この判定は「いま再起動が必要か」を知るには強い一方、「いつ必要になったか」は分かりません。そこで、イベントログで再起動要求イベントの時刻を拾うか、より確実にしたいなら定期実行でキーの出現時刻を自前で記録します。

いつ再起動が必要になったかを取る(イベントログ+自前ログ)

後追い調査なら WindowsUpdateClient/Operational の「再起動が必要」イベントの TimeCreated が候補になります。ただしログが消える可能性があるため、確実性を上げたい場合は、次のように定期タスクで再起動保留キーの有無を監視してファイルに追記する運用が強いです(PowerShellとタスクスケジューラだけで完結します)。

# 例:1時間に1回などで実行し、再起動保留になった瞬間を記録する
$logPath = "$env:ProgramData\WU-Audit\reboot_required_watch.log"
New-Item -ItemType Directory -Path (Split-Path $logPath) -Force | Out-Null

$now = Get-Date
$wuKey  = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired"
$cbsKey = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending"

$flags = [pscustomobject]@{
Time = $now.ToString("s")
WU_RebootRequired = (Test-Path $wuKey)
CBS_RebootPending = (Test-Path $cbsKey)
}

# 変化があった時だけ追記したい場合は、前回状態を別ファイルに保存して差分判定する

$flags | ConvertTo-Json -Compress | Add-Content -Path $logPath -Encoding UTF8

再起動が走った時刻を取る(Systemログ)

「再起動要求」と「実際の再起動」は別物です。再起動要求が出た後、メンテナンスウィンドウでいつ再起動したのかを突き合わせると、再起動で完了した更新を推定しやすくなります。再起動時刻はSystemログから取れます。

$start = (Get-Date).AddDays(-14)

# 再起動/シャットダウンの痕跡(代表例)

# 1074: 再起動/シャットダウンが要求された(誰が/何が)

# 6005: Event Log サービス開始(起動扱いに使える)

# 6006: Event Log サービス停止(停止扱いに使える)

$rebootIds = 1074,6005,6006

Get-WinEvent -FilterHashtable @{ LogName="System"; StartTime=$start; Id=$rebootIds } |
Select-Object TimeCreated, Id, ProviderName, Message |
Sort-Object TimeCreated

1074は「再起動を実行した時刻」を取りやすい一方で、更新KBまで分からないことが多いです。6005(起動)やLastBootUpTimeも組み合わせ、再起動前後の時間窓に入った更新を“再起動で確定した候補”として扱う設計が実務では扱いやすいです。

COM API(QueryHistory)で更新履歴を取る

GUIの「更新の履歴」に相当する情報を、PowerShellから標準のCOM APIで取得できます。外部モジュールを入れられない環境でも使えるのが強みです。ここで取れるのは主に日時(Date)と結果(ResultCode)、タイトル(Title)で、インストール成功・失敗の裏取りに役立ちます。

QueryHistory の基本コード

# Windows Update の更新履歴(インストール/アンインストール履歴)を取得
$session  = New-Object -ComObject "Microsoft.Update.Session"
$searcher = $session.CreateUpdateSearcher()

$count   = $searcher.GetTotalHistoryCount()
$history = $searcher.QueryHistory(0, $count)

# 直近100件だけ見る例

$history | Select-Object -First 100 Date, Title, ResultCode, HResult, Operation

ResultCode の目安

ResultCodeは数値で返るため、表にしておくと読みやすくなります。環境によっては「成功だが追加情報あり」のような中間値が出ることもあります。

ResultCode意味(目安)運用上の扱い
2成功通常はOK。後段のCBS/DISMと突き合わせて完了時刻を確定させる。
3成功(エラーあり)一見成功でも後で問題化することがある。HResultも併記して調査の入口にする。
4失敗イベントログと合わせてエラーコード(0x~)を追う。
5中止メンテナンスウィンドウ外で中断、再試行待ちなどの可能性。

KB番号を抽出して一覧化する

TitleにKBが含まれることが多いので、正規表現で抜き出しておくと後で結合しやすくなります。

$history | Select-Object -First 200 | ForEach-Object {
  $kb = [regex]::Match($_.Title, 'KB\d{6,8}').Value
  [pscustomobject]@{
    Date       = $_.Date
    KB         = if ($kb) { $kb } else { "" }
    Title      = $_.Title
    ResultCode = $_.ResultCode
    HResult    = ("0x{0:X8}" -f ($_.HResult -band 0xffffffff))
    Operation  = $_.Operation
  }
} | Sort-Object Date -Descending |
  Format-Table -AutoSize

QueryHistoryは「更新履歴としての日時」を返します。これが必ずしも“再起動後に確定した瞬間”と一致するとは限りませんが、成功/失敗の裏取りと、KB・タイトルの軸として非常に使えます。

DISMのパッケージ情報でインストール完了日時を補完する

Get-HotFixで追いにくい更新でも、コンポーネントベースの“パッケージ”として入っている場合は、DISMの情報からインストール時刻を取れることがあります。PowerShellでは標準のDISMモジュールのGet-WindowsPackage -Onlineが使える環境が多く、GUIやCBSログだけに頼らずに時刻を引けるのがメリットです。

KBを含むパッケージのInstallTimeを取得する

# すべてのパッケージを列挙(件数が多いので注意)
$pkgs = Get-WindowsPackage -Online

# KBを含む Installed のものを抽出し、InstallTime を表示

$pkgs |
Where-Object { $*.PackageName -match 'KB\d{6,8}' -and $*.PackageState -eq 'Installed' } |
ForEach-Object {
$kb = [regex]::Match($*.PackageName, 'KB\d{6,8}').Value
[pscustomobject]@{
KB          = $kb
InstallTime = $*.InstallTime
PackageName = $_.PackageName
}
} |
Sort-Object InstallTime -Descending |
Select-Object -First 50

この方法は“インストール済みのパッケージ”を基準にできるため、再起動をまたいで確定した更新の時刻を拾えるケースがあります。一方で、累積更新は複数パッケージに分かれたり、KBがPackageNameに出ないものもあります。そこで、QueryHistoryのTitle(ユーザー向け名称)とDISMのPackageName(内部名称)をKBで結合し、足りない分をCBS.logで補う、という役割分担がきれいです。

CBS.logで「再起動後に完了した更新」を確定させる

CBS.log(Component Based Servicing)は、更新適用の“確定に近い情報”が残りやすいログです。特に再起動中に進む処理はWindows Updateクライアント側のイベントよりCBS側に詳細が出ることがあり、再起動後に完了した更新を追う最重要の保険になります。

CBS.log からKBを含む行を拾う

まずは直近部分を見て、KBが出てくるパターンを掴みます。CBS.logは巨大なので、最初はTailで十分です。

# 直近2000行からKBを含む行だけ抽出
Get-Content "C:\Windows\Logs\CBS\CBS.log" -Tail 2000 |
  Select-String -Pattern "KB" |
  Select-Object -First 50

CBS.logは英語ログが混在することもあり、KB以外に Package_for_KB の形で出ることもあります。KBだけで拾えない場合は、次のようにPackage_for_KBで検索するとヒット率が上がります。

Get-Content "C:\Windows\Logs\CBS\CBS.log" -Tail 8000 |
  Select-String -Pattern "Package_for_KB" |
  Select-Object -First 50

期間を絞って「完了っぽい行」を探すコツ

再起動前後の時間が分かっているなら、その前後数十分に絞って検索するのが最短です。CBS.logは行頭に日時が付くため、文字列検索でもかなり戦えます。完了を示す表現は一つではありませんが、次のようなキーワードは手がかりになりやすいです。

  • completed / complete
  • Commit / Committing
  • Install / Installed
  • Reboot required
  • 0x で始まるエラーコード

ただしCBS.logは“機械的に100%正しくパースする”のが難しいログでもあります。運用上は、KB・時刻・成功/失敗のヒントが取れれば十分と割り切り、最終的な整合はQueryHistory(履歴)やDISM(状態)で確認するのが現実的です。

CBS.log がローテーションしている場合

調査対象期間が長いと、CBS.logがローテーションして CbsPersist_*.cab に退避されていることがあります。CABの展開は環境により手段が異なりますが、標準の expand.exe を使って取り出してから検索する方法が手堅いです。

# 例:CbsPersist を作業フォルダへ展開して検索する(管理者で実行)
$src = "C:\Windows\Logs\CBS"
$dst = "$env:TEMP\CBS_Persist"
New-Item -ItemType Directory -Path $dst -Force | Out-Null

Get-ChildItem $src -Filter "CbsPersist_*.cab" |
Sort-Object LastWriteTime -Descending |
Select-Object -First 3 |
ForEach-Object {
$cab = $_.FullName
& expand.exe $cab -F:* $dst | Out-Null
}

Select-String -Path (Join-Path $dst "*.log") -Pattern "Package_for_KB" -SimpleMatch |
Select-Object -First 50

4つの情報を1枚にまとめる設計(タイムライン化)

ここまでの情報源を、実運用で扱いやすい“監査ログ”に落とすには、次のようなデータモデルにすると運用が回ります。

列名(例)意味主な取得元
KBKB番号(取れない場合は空)QueryHistory/イベント/DISM/CBS のいずれか
Title更新タイトルQueryHistory、イベントログ
DownloadTimeダウンロード開始/完了の目安WindowsUpdateClient/Operational、WindowsUpdate.log
RebootRequiredTime再起動が必要になった時刻WindowsUpdateClient/Operational、(自前監視ログ)
InstallTimeインストール完了の目安(確定寄り)DISM InstallTime、CBS.log
Result成功/失敗/成功(エラーあり)などイベントログ、QueryHistory
RebootTime実際に再起動した時刻Systemログ、LastBootUpTime

すべての列を毎回埋めるのではなく、取れるものだけ埋めて突き合わせるのがポイントです。例えばダウンロード日時は欠けやすいので「取れたらラッキー」扱いにし、再起動要求と成功/失敗、インストール完了は確実に残す、という優先順位を付けると実装が安定します。

サンプル:標準機能だけで更新監査ログをCSVに残す

以下は、QueryHistory(履歴)とWindowsUpdateClient/Operational(イベント)を軸に、KBを抽出してCSVに残すサンプルです。CBS.logやDISMのInstallTimeまで完全統合すると長くなるため、まずは“回る最小構成”として提示します。運用に合わせて、後段でDISM/CBSの列を足してください。

# --- 設定 ---
$OutDir = "$env:ProgramData\WU-Audit"
$OutCsv = Join-Path $OutDir "wu_audit.csv"
$Since  = (Get-Date).AddDays(-14)

New-Item -ItemType Directory -Path $OutDir -Force | Out-Null

function Get-WUHistory {
param([datetime]$StartTime)

$session  = New-Object -ComObject "Microsoft.Update.Session"
$searcher = $session.CreateUpdateSearcher()
$count    = $searcher.GetTotalHistoryCount()
if ($count -le 0) { return @() }

$history  = $searcher.QueryHistory(0, $count)

$history |
Where-Object { $*.Date -ge $StartTime } |
ForEach-Object {
$kb = [regex]::Match($*.Title, 'KB\d{6,8}').Value
[pscustomobject]@{
Source     = "QueryHistory"
Time       = $*.Date
KB         = if ($kb) { $kb } else { "" }
Title      = $*.Title
EventId    = ""
ResultCode = $*.ResultCode
HResult    = ("0x{0:X8}" -f ($*.HResult -band 0xffffffff))
Message    = ""
}
}
}

function Get-WUClientEvents {
param([datetime]$StartTime)

$log = "Microsoft-Windows-WindowsUpdateClient/Operational"
$ids = 19,20,21   # 代表例(必要に応じて追加)
$events = Get-WinEvent -FilterHashtable @{ LogName=$log; StartTime=$StartTime; Id=$ids } -ErrorAction SilentlyContinue

$events | ForEach-Object {
$kb = [regex]::Match($*.Message, 'KB\d{6,8}').Value
[pscustomobject]@{
Source     = "WUClientEvent"
Time       = $*.TimeCreated
KB         = if ($kb) { $kb } else { "" }
Title      = ""
EventId    = $*.Id
ResultCode = ""
HResult    = ""
Message    = ($*.Message -replace "\s+", " ").Trim()
}
}
}

$rows = @()
$rows += Get-WUHistory      -StartTime $Since
$rows += Get-WUClientEvents -StartTime $Since

# 並び替えてCSVに出力

$rows |
Sort-Object Time |
Export-Csv -Path $OutCsv -NoTypeInformation -Encoding UTF8

$OutCsv

このCSVを“日次で上書き”ではなく“追記”にしたい場合は、既存CSVを読み込んで重複排除してから書き戻す、または日付入りファイル名にする、といった運用が向いています。特にパッチ適用直後はイベントが多いので、追記・差分管理の方が調査しやすいです。

ダウンロード日時をどう扱うか(割り切りと精度の上げ方)

「更新がいつダウンロードされたか」は、4項目の中で最も取りにくいことが多いです。理由は、ダウンロードがBITS/Delivery Optimizationなど別コンポーネントで行われ、更新単位(KB)と1対1で結び付けにくいこと、そしてログが環境設定や保持期間に左右されることです。

それでも実務で必要になる場合は、次の優先度で考えると破綻しにくいです。

  • 更新KBに結び付く痕跡が取れるなら、WindowsUpdateClient/Operational のダウンロード関連イベントを採用する
  • 更新KBに紐付かなくても「その端末が更新を取りに行った時刻」が分かれば十分なら、Get-WindowsUpdateLog の WindowsUpdate.log で補完する
  • “正確なダウンロード完了時刻を必須”にすると運用が難しくなるため、監査要件として本当に必要かを見直す

WindowsUpdate.log を生成して調査に使う

最近のWindowsではWindowsUpdate.logがETW(.etl)からオンデマンド生成になります。PowerShellの標準コマンドで生成し、ダウンロードの痕跡を検索します。

# WindowsUpdate.log を生成(既定ではデスクトップに出力されることが多い)
Get-WindowsUpdateLog

# 生成したログからキーワード検索(パスは環境に合わせて変更)

Select-String -Path "$env:USERPROFILE\Desktop\WindowsUpdate.log" -Pattern "Download" |
Select-Object -First 50

WindowsUpdate.logは調査向きですが、機械的にKBごとのダウンロード完了時刻を確定する用途には向きません。監査ログとしては「いつ更新処理が動き始めたか」の補助情報、として使うのが現実的です。

Get-HotFix の日付が更新されない/当てにならないときの考え方

Get-HotFix(Win32_QuickFixEngineering)は軽量で便利ですが、更新の種類によっては表示が揺れます。代表例として、累積更新やコンポーネントベースの更新では、ホットフィックスとして1件で見えない・InstalledOnが空/固定になる、といったことが起こりえます。

この状況では、次のように役割分担すると迷いが減ります。

  • 「インストール済みの一覧」をざっくり出したい:Get-HotFix
  • 「Windows Updateとして成功したか/失敗したか」を追いたい:WindowsUpdateClient/Operational + QueryHistory
  • 「再起動後にいつ完了したか」「パッケージとして確定した時刻」を追いたい:CBS.log + DISM InstallTime

実運用で失敗しないためのコツ

パッチ適用日の前にログ保持を強化しておく

イベントログは上書きされます。パッチ適用頻度が高い端末ほど、事後調査で必要な期間を過ぎてログが消えがちです。Operationalログの最大サイズを増やす、Windows Event Forwardingで別サーバーへ転送する、といった“ログを残す仕組み”を先に用意すると、後追いの苦労が大きく減ります。

「起動時に1回」もログ収集に入れる

再起動で完了する更新を追いたいなら、シャットダウン前だけでなく起動直後(スタートアップ)にも収集を回すのが有効です。起動直後にQueryHistoryとCBS.logの直近を拾うだけでも、「再起動後に完了した」更新を取りこぼしにくくなります。

失敗時はHResultとCBSのエラー行をセットで残す

成功/失敗だけでは原因究明まで辿り着けません。QueryHistoryのHResult(0x形式)や、CBS.logの0xエラー行を同じ案件ログに残すと、二次調査が短縮できます。

よくあるつまずきと対処

症状原因の候補対処
WindowsUpdateClient/Operational が見つからない/空チャンネル無効、ログサイズ不足、保持期間不足wevtutilで有効化し、/msでサイズ増。パッチ適用前に設定しておく。
KBがイベントMessageに出ないタイトル表記の揺れ、更新種別Messageはそのまま保存し、QueryHistoryのTitle/KBと後で突き合わせる。
再起動後に完了した更新の“完了時刻”が取れないイベントログだけで追っているCBS.log、DISM InstallTime、QueryHistoryを併用して確定情報を取る。
Get-HotFix の InstalledOn が変わらないQFEとして扱われない更新、WMI表示の制限DISMパッケージやCBSログ、更新履歴で確認する。

まとめ

Windows Updateの「ダウンロード日時/再起動要求/インストール完了日時/成否」を標準機能だけで追跡するには、情報源を用途別に使い分けて突き合わせるのが最短です。イベントログは“発生の痕跡”、QueryHistoryは“履歴としての結果”、CBS.logとDISMは“再起動後に確定した事実”を補完します。運用ではログ保持(サイズ・期間)と、起動後の収集も組み合わせ、再起動をまたぐ更新を取りこぼさない設計にすると安定します。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次