読者です 読者をやめる 読者になる 読者になる

kkamegawa's weblog

Visual Studio,TFS,ALM関係のことについていろいろと書いていきます。Google Analyticsで解析を行っています

PowerShellで勤務時間を採取しよう

PowerShell Windows 7

PowerShell Advent Calendar 12/7分です。
PowerShell Advent Calendar 2011 : ATND
毎日のお役に立ちそうなスクリプトを作ってみました。たいていの会社では勤怠を入力していると思います。その日に入力して帰ればいいんですが、忘れちゃう人(私)も多いと思います。そんなとき私はWindowsのイベントログを見ています。外出もほとんどないし、マシンを落とすときはほとんど帰る時なのでこれで実用充分です。
毎回ちまちまイベントログ見るのが面倒だなと思っていたので、ちょうどいい機会ということでAdvent Calendarネタで作ってみました。たぶんVista以降で動きます(私が確認したのはWindows 7です)。

$date = [datetime]::today.adddays(-1)
$events = Get-EventLog -LogName system -before $date | where-object {$_.source.startswith("Microsoft-Windows-Kernel") -eq $true -or $_.source.startswith("Microsoft-Windows-Power") -eq $true} | select-object timegenerated,source,InstanceID

$poweron = $events | where-object {$_.source -eq "Microsoft-Windows-Kernel-General" -and $_.InstanceID -eq 12} 
$shutdown = $events | where-object {$_.source -eq "Microsoft-Windows-Kernel-General" -and $_.InstanceID -eq 13} 
$sleepwakeup = $events | where-object {$_.source -eq "Microsoft-Windows-Power-Troubleshooter" -and $_.InstanceID -eq 1} 
$sleepgo = $events | where-object {$_.source -eq "Microsoft-Windows-Kernel-Power" -and $_.InstanceID -eq 42} 
$workend = $shutdown[0].TimeGenerated 
if($sleepgo -ne $null) {
  if($shutdown[0].TimeGenerated -lt $sleepgo[0].TimeGenerated) {
    $workend = $sleepgo[0].TimeGenerated
  }
}
$workstart = $poweron[0].TimeGenerated

if($sleepwakeup -ne $null) {
  if($sleepwakeup[0].TimeGenerated -lt $poweron[0].TimeGenerated) {
    $workstart = $sleepwakeup[0].TimeGenerated
  }
}
write-host 前日の勤務はたぶん $workstart から $workend です。

簡単に解説しておくと、シャットダウンとスリープのイベントを取って、新しいほうをそれぞれ採用するってだけです。シャットダウンと起動はおそらく必ずありますが、スリープは人によって使う使わないがあるはずですので、その判定が二つのif文になります。
ちなみにハイブリッドスリープ使っているとちょっと判定間違うかもしれませんが、そこらへんは笑って許して(ハイブリッドスリープは一度起動して休止に突入するので、kernel-powerイベントが出るはずです)。
起動、終了がMicrosoft-Windows-Kernel-Generalというイベント、スリープからの復帰がMicrosoft-Windows-Power-Troubleshooterというイベント、スリープ突入がMicrosoft-Windows-Kernel-Powerというイベントのようです。イベントログをなめているので結構時間がかかりますが、まぁこういうスクリプトそこそこ使えるかなと思います。
あ、日をまたいだような勤務はサポートしておりません(^^;日付が変わる前に帰りましょう(^^;;。