以前PowerShell: ◆最近何時に帰ったか調べる(shutdownイベントを拾う)で終了時刻を表示するのはやったことがあるのだが、ふとしたところで起動時間も一緒に表示したいと要望されて作ってみた。
終了時刻が表示できているので起動時刻を表示するのも特に問題は無い。
それぞれを別に表示するのであれば「イベントID」を変えて実行するだけ。
しかし、通常は「起動」と「終了」を同一行に表示させたいというのが人情だろう。
まぁそれも特に問題は無いだろうと思ったのだが意外と簡単な方法が浮かばない。
片方に「日付と起動時間」、もう片方に「日付と終了時間」があり、これを一行に纏める。
数十年前の遠い昔によくやったバッチ処理のような問題だ。
実際にこれがバッチ処理なら何も迷うことは無い典型的なパターン。
それぞれを日付でソートしてマッチングしてくっつけながら出力していけば良い。
しかし、PowerShellではどうすればスマートなんでしょうね・・・。
とりあえず私は「Group-Object」を使ってグルーピングしてやるケースが多い。
こんな感じ。
001 002 003 004 005 006 007 008 009 010 011 012 013 | $startID = 2147489653;$endID = 2147489654 Get-EventLog system -InstanceId $startID,$endID ` -After ((Get-Date).AddMonths(-1)) | select timewritten,InstanceId | group {($_.TimeWritten).ToString("yyyyMMdd")} | sort name | %{ $obj = New-Object PsObject -Property @{日付=$_.name;起動="";終了=""} $_ | select -ExpandProperty group | %{ if($_.InstanceId -eq $startID){ $obj.起動 = $_.TimeWritten.ToString("HH:mm:ss")} if($_.InstanceId -eq $endID){ $obj.終了 = $_.TimeWritten.ToString("HH:mm:ss")} } $obj | select 日付,起動,終了 } |
一日に複数回起動することを考慮しなければこれで良いのだが、通常はPCを再起動することもあるだろう。
その場合は、起動のイベントと終了のイベントをそれぞれ再度グルーピングして最も早いものと最も遅いものを抽出する必要がある。
ちょっとネストが深くなって気乗りがしない・・・。
処理時間がシビアな場合は仕方がないがもう少し簡単に行きたい。
というわけでPowerShell: ◆最近何時に帰ったか調べる(shutdownイベントを拾う)と同じロジックで起動時間を取得しそれぞれをくっつけることにした。
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 | $startID = 2147489653;$endID = 2147489654 $log = Get-EventLog system -InstanceId $startID,$endID ` -After ((Get-Date).AddMonths(-1)) $StartObj = $log | ?{$_.InstanceId -eq $startID} | select timewritten | sort timewritten | group {($_.TimeWritten).day} | %{ $startTime = (@($_.group)[0]).TimeWritten New-Object PsObject -Property @{日付=$startTime.ToString("yyyyMMdd") 起動=$startTime.ToString("HH:mm:ss")} } $EndObj = $log | ?{$_.InstanceId -eq $endID} | select timewritten | sort timewritten | group {($_.TimeWritten).day} | %{ $endTime = (@($_.group)[-1]).TimeWritten New-Object PsObject -Property @{日付=$endTime.ToString("yyyyMMdd") 終了=$endTime.ToString("HH:mm:ss")} } $list = $StartObj+$EndObj | sort 日付 | group 日付 | %{ $outObj = 1 | select 日付,起動,終了 $outObj.日付 = $_.name $_ | select -ExpandProperty group | %{ if($_.起動){$outObj.起動 = $_.起動} if($_.終了){$outObj.終了 = $_.終了} } $outObj } $list | ft -AutoSize Read-Host please Enter |
Shutdownイベントを拾うのが実質1行で済んでいたのと比べるとなんか大きくなりすぎている感じはするが・・・。
あれ、今日と1か月前と日付がぶつかっているのかな。
5行目と11行目は「Day」プロパティではなく「ToShortDateString()」メソッドですかね。
0 件のコメント:
コメントを投稿