PowerShellを使ってイベントビューアのエラーログを効率的にフィルタリングする方法

PowerShellを使ってイベントビューアのエラーログを効率的にフィルタリングする方法は「Get-WinEvent -FilterHashtableでLevel=2、StartTime、LogNameを指定し、必要に応じProviderNameとIDを加えます。全件取得後Where-ObjectでError文字列を絞る旧手順は大規模logで非効率です。」と理解すると迷いません。取得元でLogName、Level、時間、Provider、IDを絞り、LevelDisplayNameのlanguage文字列に依存しない点が適用条件です。

目次

対象log・Level・期間を先に固定する

イベントビューアーのエラー抽出では、LogName、ProviderName、ID、Level、開始時刻をFilterHashtableへ渡し、読み込み後の全件フィルターを避けます。RecordIdとTimeCreatedを保持し、該当0件は正常な検索結果、ログ不存在や権限不足は取得エラーとして分けます。XML条件を使う場合は少数件で結果を照合します。

  • Get-WinEvent -ListLogでlog名とRecordCountを確認する
  • error level数値とproviderを確認する
  • 調査期間のtimezoneと境界を決める
  • export先とmessageの機密性を確認する

FilterHashtableでerrorをserver側抽出する

LevelDisplayNameは表示languageに依存し、数値Levelを自動判定に使います。errorが多いproviderを根本原因と断定せず、時間順、related warning、service/application状態を確認します。FilterHashtableはOR/ANDの組合せに制約があり、複雑な条件はXPathまたは小さい結果への後filterを検討します。

providerとevent IDで原因候補を絞る

  • Get-WinEvent -LogNameと存在しない-Level組合せを思い込む
  • 全件後Where-Object
  • LevelDisplayName文字列に依存する
  • IDだけで意味を決める
  • logをclearして軽くする

ProviderNameとIdの組で件数を集計する

System errorを一日分

Get-WinEvent -FilterHashtable @{LogName='System';Level=2;StartTime=(Get-Date).AddDays(-1)} -MaxEvents 500 | Select-Object TimeCreated,RecordId,Id,ProviderName,Message

Level 2はErrorです。MaxEventsで初回上限を置きます。

複数logをfilter

Get-WinEvent -FilterHashtable @{LogName='System','Application';Level=2;StartTime=(Get-Date).AddHours(-6)} | Select-Object LogName,TimeCreated,Id,ProviderName

LogName列を残し混在を識別します。

providerとIDを追加

Get-WinEvent -FilterHashtable @{LogName='Application';ProviderName='Application Error';Id=1000;StartTime=(Get-Date).AddDays(-7)}

同ID別providerを除きます。

件数を分類

$events=Get-WinEvent -FilterHashtable @{LogName='System';Level=2;StartTime=(Get-Date).AddDays(-1)} -ErrorAction SilentlyContinue
$events | Group-Object ProviderName,Id | Sort-Object Count -Descending | Select-Object Count,Name

頻度は原因重要度と同義ではありません。

CLIXMLへ保存

$events | Export-Clixml '.\system-errors.xml'

object propertyを保持します。限定ACLと保持期限を設定します。

CLIXMLへ原objectを保存する

読取は変更しません。event messageにはaccount、path、IP等が含まれます。必要列だけexportし、Security logはさらに厳格に扱います。Clear-EventLogやlog無効化、size縮小を調査中に行いません。取得timeout時は期間を分割し、security設定を弱めません。

表示messageだけの文字列検索を避ける

Event Viewer custom viewで同条件を作り、RecordIdと件数をsample照合します。期間境界、0件、access denied、log disabledを別結果にします。exportを読み戻し、TimeCreated、Id、ProviderNameが保持されているか確認します。

時刻範囲・件数・最大RecordIdを検収する

Get-WinEvent -FilterHashtableでLogName、Level=2、StartTime、必要ならProviderName/Idを絞ります。件数上限とRecordIdを持ち、0件・query error・log access errorを別状態で返します。

System errorを一日・500件以内で取得する

$start=(Get-Date).AddDays(-1)
$events=@(Get-WinEvent -FilterHashtable @{LogName='System';Level=2;StartTime=$start} -MaxEvents 500 -ErrorAction Stop)
[pscustomobject]@{Count=$events.Count;First=($events|Sort-Object TimeCreated|Select-Object -First 1).TimeCreated;Last=($events|Sort-Object TimeCreated|Select-Object -Last 1).TimeCreated;MaxRecordId=($events.RecordId|Measure-Object -Maximum).Maximum}

event 0件とquery失敗をErrorRecordで判断する

  • error event取得:期間内error eventが指定log/provider/IDと一致し、RecordId付きで取得される
  • 期間内0件:正常0件はNoMatchingEventsとして期間とfilterを記録する
  • channel・query error:log不存在、provider mismatch、access denied、query limit超過はFilterError/Truncatedにする

Level 2だけでは重大度や原因が同じとは限りません。Message文字列だけで重複排除せず、host/log/RecordIdをkeyにします。SystemとApplicationのeventを時刻だけで無条件に同一incidentへ束ねません。

複数logと同一RecordIdを試す

$events | Group-Object ProviderName,Id | Sort-Object Count -Descending | Select-Object -First 10 Count,Name

0件、500件超、複数log、provider/ID追加、access deniedをtestします。query、期間、取得/推定total、RecordId範囲、truncated flagを保存します。

Level 2はerrorですが、原因や重大度を自動確定しません。provider、ID、RecordId、時刻を残し、Messageの表示言語へ依存しないfilterを優先します。

公式情報・参考資料

この記事を書いた人

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

コメント

コメントする

目次