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を優先します。

コメント