特定event IDのWindows log監視は短い一行でも扱えますが、入力の種類や版を確認しないまま本番へ使うと誤判定を招きます。この記事の結論は「過去logはGet-WinEventのFilterHashtableで期間・log・IDを絞り、継続監視は定期queryまたはWindows Event Forwardingなど管理基盤へ渡します。Get-EventLog全件をWhere-Objectで後filterする旧例は避けます。」。event IDだけでなくLogNameとProviderNameを固定し、Security logは必要権限と取扱規程を守る場合を対象に、確認結果から次の行動を選べる形で解説します。
channel・provider・ID・時間窓を固定する
event queryのchannel・provider・IDは実値へ固定し、曖昧なwildcardをcursor処理へ残しません。Get-WinEventがshell builtin、cmdlet、外部programのどれかも確認し、別実装のoptionを混在させません。
- Get-WinEvent -ListLogでlog名とenabled状態を確認する
- 対象IDのProviderName、level、意味を公式event資料で確認する
- baseline件数と監視window、重複除外用RecordIdを決める
- Security logの閲覧権限と保存先ACLを確認する
FilterHashtableで取得前に絞り込む
直近一時間をserver-side filter
$start=(Get-Date).AddHours(-1)
Get-WinEvent -FilterHashtable @{LogName='System';Id=7036;StartTime=$start} -MaxEvents 200 |
Select-Object TimeCreated,RecordId,Id,ProviderName,LevelDisplayName,Message
ID 7036はSystem logのService Control Manager例です。IDだけを別providerへ一般化しません。
providerも固定
Get-WinEvent -FilterHashtable @{LogName='System';ProviderName='Service Control Manager';Id=7036;StartTime=(Get-Date).AddMinutes(-15)}
ProviderNameを組にすると同番号別eventの混入を防ぎます。
最後に処理したRecordIdを記録
$events=Get-WinEvent -FilterHashtable @{LogName='System';Id=7036} -MaxEvents 20
$events | Sort-Object RecordId | Select-Object TimeCreated,RecordId,Message
定期pollでは前回最大RecordIdと時刻をcheckpointにします。log clearやwrapで連続性が失われる条件も監視します。
event XMLのdata名を確認
$e=Get-WinEvent -FilterHashtable @{LogName='System';Id=7036} -MaxEvents 1
[xml]$xml=$e.ToXml()
$xml.Event.EventData.Data | Select-Object Name,'#text'
message文字列の位置splitより、XMLのnamed dataを使えるか確認します。schemaはproviderごとに異なります。
少量をCLIXMLへ保存
$events | Export-Clixml -LiteralPath '.\event-7036-sample.xml'
Messageにはsystem情報が含まれます。限定ACL、新規file、保持期限を設定します。
RecordId cursorはchannelごとに保持する
- Get-EventLog全件後filter
- event IDだけで意味を断定する
- poll境界で重複を数える
- Message文言を固定splitする
- 調査中にlogをclearする
event XMLから名前付きdataを読む
監視はevent発生と同時に原因確定するものではありません。同じIDが正常遷移でも出るか、短時間に連続したか、関連eventが前後にあるかを見ます。TimeCreated、RecordId、ProviderNameを組にし、poll windowの境界で重複または欠損しない設計にします。Event Viewer表示languageに依存するMessage解析は避けます。
CLIXMLでobject構造を保存する
log取得は読み取りですが、Security logにはaccount、host、network情報が含まれます。広い共有先や平文mailへ出さず、collection serviceの権限と保持policyに従います。logをclear、disable、size縮小して監視を軽くしません。監視scriptにcredentialを埋め込まず、失敗時はcheckpointを勝手に進めず再取得範囲をreviewします。
log clear・wrap・取得gapを検出する
Event Viewerの同一RecordIdを照合し、既知eventをtest環境で一件発生させて検知遅延と重複を確認します。query失敗、0件、access denied、log wrapを別statusへ記録します。定期監視は終了code、最終成功時刻、checkpointを監視対象に含めます。
時刻順・件数・最大RecordIdを検収する
FilterHashtableでlog/provider/ID/期間を絞り、RecordId、TimeCreated、Level、event XMLのnamed Dataを保持します。Messageは表示用とし、増分cursorはhost・logごとのRecordIdで管理して重複と取りこぼしを検出します。
System 7036を上限付きで増分取得する
$e=@(Get-WinEvent -FilterHashtable @{LogName='System';ProviderName='Service Control Manager';Id=7036;StartTime=(Get-Date).AddHours(-1)} -MaxEvents 200 -ErrorAction Stop)
$e | Sort-Object RecordId | Select-Object TimeCreated,RecordId,Id,ProviderName
cursor進行とchannel障害をRecordIdで追う
- 増分eventあり:filter条件に一致するeventをRecordId順に取得し、XML Data名から必要fieldを読める
- 新規eventなし:0件はcursorを勝手に進めず、query期間と最終RecordIdを保持する
- channel・query error:log clearでRecordIdが戻る、channel unavailable、権限不足、malformed queryは別alertにする
MaxEventsだけで期間を省略すると高頻度時に調査範囲が変わります。Message regexはlanguage差で壊れるため、ProviderName/Id/XML fieldを使い、CLIXMLを無制限に保存しません。
RecordId gapと同時刻eventを試す
$one=Get-WinEvent -FilterHashtable @{LogName='System';Id=7036} -MaxEvents 1
[xml]$xml=$one.ToXml(); $xml.Event.EventData.Data | Select-Object Name,'#text'
0件、同時刻複数event、log clear、provider名違い、access deniedをtestします。host/log、query、最小/最大RecordId、件数、XML schema、取得時間を保存します。
RecordIdは全log共通の連番ではありません。channel名と最後のRecordIdを一組で保存し、log clearやretentionによる巻き戻りを検出した場合は増分処理を止めて再baselineします。

コメント