前日のイベントログをテキストファイルで取得する

前日のイベントログをテキストファイルで取得するプログラムを作成しました。今回はPowerShellでの作成にチャレンジしました。1行目から説明していきたいと思います。まず、以下は、VBAでいうところのOption Explicitです。変数を定義せず使うとエラーになるようにしています。(これは、特別必要なものでもないと思います。しかし、ちゃんと設定しておくとバグの発生を軽減できます。たとえば、コーディング中に変数名をいろいろ変更してしまうことがあると思います。その際に、変更し忘れの変数にエラーを返してくれます。)

set-PSDebug -strict

次は、イベントログの取得開始・終了時刻の設定です。これは、イベントログを取得する際に「いつ〜いつまでのログを取得する」というような設定を行うためです。注意点としては、「いつ」という指定は「2009/11/29 15:48:25」のような文字列で指定するのではなくdatetimeという.NETのオブジェクトを使うということです。そのため、初めにsystem.datetimeというオブジェクトを宣言しています。時刻の設定はget-dateというPowerShellのコマンドレットを使います。(なんでかはわからないのですがが、コマンドじゃなくてコマンドレットです。) これは戻り値として、現在日時のdatetimeオブジェクトを返してくれます。しかし、今回ほしいのは0時0分0秒と23時59分59秒です。そのため、「-hour "0" -minute "0" -second "0"」というようにオプションで時刻を指定しています。前日日付の設定はget-dateでは出来ないようなので、datetimeオブジェクトのadddaysというメソッドを使います。引数に日数を指定すると、指定した日数を加算したdatetimeオブジェクトを返します。前日日付がほしいので-1を指定します。

# イベントログ取得開始時刻の設定
$start_time_today = [system.datetime]
$start_time_yesterday= [system.datetime]
$start_time_today = get-date -hour "0" -minute "0" -second "0"
$start_time_yesterday = $start_time_today.AddDays(-1)   # 前日の0時0分0秒

# イベントログ取得終了時刻の設定
$end_time_today = [system.datetime]
$end_time_yesterday= [system.datetime]
$end_time_today = get-date -hour "23" -minute "59" -second "59"
$end_time_yesterday = $end_time_today.AddDays(-1)   # 前日の24時59分59秒

次は、出力先フォルダの設定です。今回はC:\logsというフォルダを作ってそこにログを格納することにします。(あらかじめフォルダはつくっておかないとエラーになります。)

# 出力先フォルダを設定する
$dir = [string]
$dir = "C:\logs"  

次は、いよいよ本日のメインディッシュです。(メインです。) foreach でsystem、application、securityでまわしてます。ループごとにtypeという変数に代入しています。(いまさらですけど、変数に$をつけるのでシェルみたいですね。) typeという変数は何に使うかというと、ファイル名の先頭にくっつける&取得するログを決めるのに使います。ファイル名の日付はdatetimeオブジェクトのtostringメソッドを使用しています。これは日付を引数に指定したとおりに整形していくれます。文字列の結合は「+」を使います。ログの取得ではget-eventlogというコマンドレットを使います。オプションの-lognameでログタイプ(system、application、security)を指定します。 -afterで取得開始日時をdatetimeオブジェクトで設定します。(厳密には指定日時よりも後を取得する) -beforeで取得終了日時をdatetimeオブジェクトで設定します。(厳密には指定日時よりも前を取得する) 戻り値として、eventLogEntryというオブジェクトを返します。テキストファイルへの出力はリダイレクトを使用しました。

# system、application、securityのログを出力する
$type = [string]
$name = [string]
$fPath = [string]
$event = [system.diagnostics.eventLogEntry]
foreach ($type in "system","application","security"){
    # 出力先テキストファイルのパスを設定
    $name = $type + "_" + $start_time_yesterday.tostring("yyMMdd") + ".txt" # 出力ファイル名(system)
    $fPath = $dir + "\" + $name
    
    # ログ取得
    $event = get-EventLog -logname $type -after $start_time_yesterday -before $end_time_yesterday 
    
    # テキストファイルに出力
    $event > $fPath
}

最後に、画面に完了メッセージを出力して、
エラーが発生した場合の捕捉処理を入れています。

Write-host "完了しました"

trap{
    Write-host "エラーが発生しました。"
    break
}

以下全体のプログラムです。

#-----------------------------------------------------
# 前日のイベントログをテキストファイルに出力する
# 出力ファイル:"C:\logs\application_091128.txt"
#           "C:\logs\security_091128.txt"
#           "C:\logs\system_091128.txt""
#-----------------------------------------------------

set-PSDebug -strict

# イベントログ取得開始時刻の設定
$start_time_today = [system.datetime]
$start_time_yesterday= [system.datetime]
$start_time_today = get-date -hour "0" -minute "0" -second "0"
$start_time_yesterday = $start_time_today.AddDays(-1)   # 前日の0時0分0秒

# イベントログ取得終了時刻の設定
$end_time_today = [system.datetime]
$end_time_yesterday= [system.datetime]
$end_time_today = get-date -hour "23" -minute "59" -second "59"
$end_time_yesterday = $end_time_today.AddDays(-1)   # 前日の24時59分59秒

# 出力先フォルダを設定する
$dir = [string]
$dir = "C:\logs"    

# system、application、securityのログを出力する
$type = [string]
$name = [string]
$fPath = [string]
$event = [system.diagnostics.eventLogEntry]
foreach ($type in "system","application","security"){
    # 出力先テキストファイルのパスを設定
    $name = $type + "_" + $start_time_yesterday.tostring("yyMMdd") + ".txt" # 出力ファイル名(system)
    $fPath = $dir + "\" + $name
    
    # ログ取得
    $event = get-EventLog -logname $type -after $start_time_yesterday -before $end_time_yesterday 
    
    # テキストファイルに出力
    $event > $fPath
}

Write-host "完了しました"

trap{
    Write-host "エラーが発生しました"
    break
}

実行結果です。

※「Set-ExecutionPolicy remotesigned」で実行ポリシーを変更しています。(実行ポリシーを変更しないと実行できません。)





プログラムを実行する場合はUACを無効化にしなければいけません。(デフォルトで有効になっています)UACを有効化にしていると、セキュリティログの取得の際に引っかかってしまいます。


※設定方法
[コントロールパネル](表示方法:小さいアイコン)→[ユーザーアカウント]→[ユーザーアカウント制限設定の変更]において、バーを通知しないに移動させOKをクリックし、OSを再起動する





参考
http://www.microsoft.com/japan/technet/scriptcenter/topics/winpsh/convert/default.mspx
http://www.microsoft.com/japan/technet/scriptcenter/topics/msh/cmdlets/set-executionpolicy.mspx