ハードなソフトの話

アクセスカウンタ

zoom RSS Windows XP/Vista の稼働時間を調べる(3)〜イベントログファイルから調べる〜

<<   作成日時 : 2009/04/26 20:36   >>

なるほど(納得、参考になった、ヘー) ブログ気持玉 1 / トラックバック 0 / コメント 0

http://hardsoft.at.webry.info/200904/article_16.htmlでは過去の稼働時間について触れたけど、イベントログファイルから過去の稼働時間を調べるにはどうすればいいだろうか?
この場合は、イベントログのシステムログが手掛かりになる。
イベントビューアで調べてみると、Windowsは起動時にイベントログに次のような記録を残す。
ログの名前: System
ソース: EventLog
日付: 2009/04/24 20:24:14
イベント ID: 6009
タスクのカテゴリ: なし
レベル: 情報
キーワード: クラシック
ユーザー: N/A
コンピュータ: <コンピュータ名>
説明:
Microsoft (R) Windows (R) 6.00. 6001 Service Pack 1 Multiprocessor Free.

そして終了時には次のような記録を残す。
ログの名前: System
ソース: EventLog
日付: 2009/04/24 20:23:16
イベント ID: 6006
タスクのカテゴリ: なし
レベル: 情報
キーワード: クラシック
ユーザー: N/A
コンピュータ: <コンピュータ名>
説明:
イベント ログ サービスが停止されました。

終了時のログは、ちょっと違うんじゃないかと思う人がいるかもしれないが、イベントログで記録できる最後のログは「イベント ログ サービスが停止しました」以外にはありえない。
Windows Vistaならカスタムビューで6006と6009のみを表示すればわかりやすい。イベントログファイルは
しかし、Windows XPのとき、そして、そのPCの情報がイベントログしかないときは、Logparser を使う。
Logparserはevtファイルをはじめとする各種ログをSQLを使って条件を指定して抽出できる。
Logparserは下記の場所からダウンロードできる。
http://www.microsoft.com/downloads/details.aspx?FamilyID=890cd06b-abf8-4c25-91b2-f8d975cf8c07&DisplayLang=ja
システムログから起動時間と停止時間を調べるには、次のようコマンドラインで入力する。
logparser "select timegenerated, eventid from system where sourcename='EventLog' and ( eventid=6009 or eventid=6006) "

この例ではFROM句に"system"を指定しているの現在のPCのログを抽出するけれで、イベントファイル名を書くこともできる。また、logparser はいろいろな出力形式を指定できるので、-o tsvなどとオプションを指定すれば、Excelに貼り付けるのも簡単。
とはいっても、これでは、稼働時間帯がわかりにくい。また、不慮の事故で電源が切れた場合も知りたい。
LogparserはコマンドラインだけでなくCOMのサポートもあるので、下記のようなスクリプトを書いてみた。
Option Explicit

' Initilize
Dim vSourceLog: vSourceLog  = "System"
Const cdSourceName = "EventLog"
Const cdBegin     = 6009
Const cdEnd       = 6006

' Command Parse
Dim args
Set args = WScript.Arguments
If args.Count > 0 Then
        vSourceLog = args.item(0)
        Wsh.echo "vSourceLog=",vSourceLog
End If

' get data from LogParser
Dim lq,rs
Set lq = CreateObject("MSUtil.LogQuery")
Set rs = lq.Execute(getSql(vSourceLog))

' Put cooked data
Dim id: id = 0
Dim vBegin,vEnd: vBegin = Null: vEnd = "*END*"
Dim VComputerName
If not rs.atEnd Then
        putHeader
End If
Do Until rs.atEnd
    Dim rec, iRecno, dTimegen, sSourcename, iEventid
        Set rec = rs.getRecord
        iRecno        = rec.getValue(0)
        dTimegen      = rec.getValue(1)
        iEventid      = rec.getValue(2)
        vComputerName = rec.getValue(3)
        Select Case(iEventid)
        Case cdBegin
            vBegin = dTimegen
            If IsNull(vEnd)  Then
                putData vBegin,vEnd,"Abnormal"
                vBegin = Null
            End If
            vEnd = Null
        Case cdEnd
            vEnd = dTimegen
            If IsNull(vBegin) Then 
                putData vBegin,vEnd,"Unknown" 
            Else 
                putData vBegin,vEnd,"Normal"
                        vBegin = Null
            End If
        End Select
        rs.MoveNext
Loop
If not IsNull(vBegin ) Then
        putData vBegin,vEnd,"Executing"
End if

Function getSql(vSourceLog)
        getSql = "select recordnumber, timegenerated, eventid,computername " & _
                 "from " & vSourceLog & " " &_
                 "where sourcename = '" & cdSourceName & "' " & _
                 "and (eventid=" & cdBegin & " or eventid=" & cdEnd & ")"
End Function

Sub putHeader
    Wsh.echo "ID" & vbTab & "Begin" & vbTab & "End" & vbTab & "State" & vbTab & "ComputerName"
End Sub

Sub putData(vBegin,vEnd,sState)
        id = id + 1
    Wsh.echo id & vbTab & vBegin & vbTab & vEnd & vbTab & sState & vbTab & vComputerName
End Sub

このスクリプトをuptimehist.vbsとして保存して次のように入力して実行すると
cscript //nologo uptimehist.vbs

次のような出力になる。
ID      Begin   End     State   ComputerName
1       2009/03/22 16:41:29     2009/03/22 16:45:23     Normal  <コンピュータ名>
2       2009/03/22 16:49:09     2009/03/22 18:08:13     Normal  <コンピュータ名>
3       2009/03/22 18:09:27     2009/03/22 18:15:16     Normal  <コンピュータ名>
...以下省略...

思いっきりカラムがずれていて見ずらいが、いちおうタブ区切り(TSV)で出力して、Excelなどで扱いやすいようにしている。
State列にある Normal は起動時間のイベントと停止時間のイベントの両方が存在することを示す。
起動時間が見つかって停止時間が存在しないときはAbnormalと表示する。
ただし、最新の起動時間の後で停止時間が存在しないのは稼働中なのでExecutingと表示する。
この場合、何らかの理由で電源がオフになっていることが多い。
停止時間が見つかって起動時間が存在しないときはUnknownと表示する。
ほとんどの場合、ログサイズの管理の関係で起動時間のログが削除されていることが多い。

このスクリプトでイベントログファイルを指定したいときは次のように入力する。
cscript //nologo uptimehist.vbs system.evt

しかし、ここで厄介なことに気がついた。その件については、また別な記事で触れる。


テーマ

関連テーマ 一覧


月別リンク

ブログ気持玉

クリックして気持ちを伝えよう!
ログインしてクリックすれば、自分のブログへのリンクが付きます。
→ログインへ
気持玉数 : 1
なるほど(納得、参考になった、ヘー)

トラックバック(0件)

タイトル (本文) ブログ名/日時

トラックバック用URL help


自分のブログにトラックバック記事作成(会員用) help

タイトル
本 文

コメント(0件)

内 容 ニックネーム/日時

コメントする help

ニックネーム
本 文
Windows XP/Vista の稼働時間を調べる(3)〜イベントログファイルから調べる〜 ハードなソフトの話/BIGLOBEウェブリブログ
文字サイズ:       閉じる