sorta kinda...

主にAWS関連ですが、これに限らずいろいろ勉強したことや思ったことを書いていきます。

PowerShellでWindowsイベントログのエラーを検知する

とある事情でWindowsのイベントログを監視することになり、そのスクリプトを書いてみました。簡単なテストしかできてないので、もうちょっとスマートなやり方があるかもしれませんが、とりあえず動いたのでよしとします。

まず、イベントログは膨大な量なので、必要に応じてフィルタするファイルを置きます。下記は重大、エラー、警告の3種類かつ10分以内のイベントログを探すフィルタです。フィルタXMLは下記ページを参考にしました。(filterxml.xml)

azuread.net

<QueryList>
  <Query Id="0" Path="System">
    <Select Path="System">*[System[(Level=1  or Level=2 or Level=3) and TimeCreated[timediff(@SystemTime) &lt;= 600000]]]</Select>
  </Query>
</QueryList>

次に、イベントログを取りに行くサーバの一覧を指定します。(hostlist.txt)

監視対象ホスト名1
ホスト名2
ホスト名3
...

実際にイベントログを取得するスクリプトです。エラーを検知したら、ロギングかつメール送信します。

$smtpserver = "xx.xx.xx.xx"
$To = "メール宛先アドレス"
$From = "メール送信者アドレス"
$encode = "utf8"

$hostnamelist = Get-Content .\hostlist.txt
$filterxml = [xml](Get-Content -Encoding UTF8 .\filterxml.xml)

# Collect event logs and send email
foreach($hostname in $hostnamelist){
    $EventLog = Get-WinEvent -ea SilentlyContinue -ComputerName $hostname -Filterxml $filterxml
    if($EventLog){
        $emailsubject = "イベントログにてエラー検知($hostname)"
        $mailbody = ($EventLog | Out-String)
        $datetime = Get-Date
        Send-MailMessage -To $To -From $From -Subject $emailsubject -SmtpServer $smtpserver -body $mailbody -encoding $encode
        Write-Output $datetime $mailbody >> detect_eventlog.log
    }else{
        Write-Host $datetime ": $hostname にてエラーログは検知されませんでした。" >> detect_eventlog.log
    }
}

Get-WinEventの出力をそのままテキスト化してメールで投げてるだけですが、見た目がややこしい場合は何らかの形にConvertなんとかできれいにした方がよさそうです。