PCの起動時刻の取得  出退勤管理用

#はじめに
会社によっては出退勤がPCの起動時刻で管理されてる場合がある。サービス残業を取り締まるなどいろいろ目的があるのだろうが、下手に時間過ぎてしまうとめんどくさいので、PCを落とす時間には結構気を使わなければいけない。時刻を管理するシステムがその日の起動時刻を教えてくれれば良いのだが、当日には見られないようなシステムの場合、いつPCをつけたかわからず困るときがある。

#windowsイベントビューア
そんな時はWindowsのイベントビューアでログを見れば確認することができる。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/201397/dd6698d0-3ecf-664c-4534-2ca67be3b7d1.png)

左のリストからwindowsログのシステムを選ぶと様々なイベントログが表示される。
ここでPCの起動に関するログを抜き出すため，右の操作から現在のログをフィルターをクリックする。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/201397/3e880de3-51cd-cc07-c804-4229b46a462f.png)

＜すべてのイベントID＞の欄に抜き出すイベントIDを入力してOKを押せば良い。

windows7までは，6005と6006でPCの起動終了のログを取得できたみたいだが，windows10ではPCを完全にシャットダウンしないようになっているため，うまく取れなくなっている。
そこで7001と7002を代わりに使用する。
7001で取得するログは
「カスタマー エクスペリエンス向上プログラムのユーザー ログオン通知」
「カスタマー エクスペリエンス向上プログラムのユーザー ログオフ通知」
である。
これでPCにログイン，ログアウトした時間の代わりとすることができる。

過去1週間の期間を指定し，7001でフィルタリングした結果がこちら。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/201397/1127e86c-261d-ae4c-3527-bee387a6c1ad.png)

このようにログインした時刻を知ることができる。

#コマンドプロンプトからのイベントログの取得
しかし、このイベントビューアは起動するのにやたら時間がかかる場合がある。
これは，ログがいっぱいあると表示が重くなってしまうからのようだ。
仕事終わりの帰り際に，ちんたら待たされると若干いらっとする。

このイベントログはwevtutilコマンドを用いることでコマンドプロンプトからも取得することができる。
この時引数でイベントIDや期間を指定してフィルタリングをかけた結果のみを抽出することができ，このようにすると一瞬でログを得ることができる。

wevtutil export-log [イベントログの種類] [エクスポート先ファイルパス]
このような書式をコマンドプロンプトに打ち込めばよく，「/q: Query」という引数でフィルタリングすることができる。
http://quatrefromage.hatenablog.jp/entry/2016/08/06/164436

例えば，ログイン時刻を取得するには次のようにする。
wevtutil export-log system LoginTime.evtx /q:"*[System[EventID = 7001]]"

これによって作成されるevtxファイルを開くとイベントビューアが起動し，抜き出したログが表示される。

さらに，テキスト出力することもできる。

wevtutil qe System /f:Text /q:"*[System[(EventID=7001)]]" > LoginTime.txt

以下のようなテキストが出力される。

```
Event[0]:
  Log Name: System
  Source: Microsoft-Windows-Winlogon
  Date: 2018-04-29T10:01:49.908
  Event ID: 7001
  Task: N/A
  Level: 情報
  Opcode: 情報
  Keyword: N/A
  User: S-1-5-18
  User Name: NT AUTHORITY\SYSTEM
  Computer: TOMOTAKA990B
  Description: 
カスタマー エクスペリエンス向上プログラムのユーザー ログオン通知
```

期間の指定は
wevtutil qe System /f:Text /q:"*[System[(EventID=7001) and TimeCreated[@SystemTime>='2018-01-01T15:00:00.000Z' and @SystemTime<='2018-01-02T14:59:59.999Z']]]" > LoginTime.txt

のように書けばよい。
ここで時刻は，日本の標準時 (JST) ではなくグリニッジ標準時 (GMT) にする必要がある。

#出社時刻を取得し退社時間を表示
コマンドプロンプトからイベントログが取得できるためバッチファイルにして，より簡単に使用することが出来る。下記のバッチファイルでは，出社時刻を取得し，設定した就業時間後の退社時刻と残り時間を表示するスクリプトである。
適当なテキストファイルにコピペし，拡張子を.batに変更すれば，ファイルをダブルクリックするだけでコマンドが実行される。
タスクバーにでもおいておけば便利そうである。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/201397/89cc259c-cdf7-b265-12fa-dc7144eb2dbf.png)


```worktime.bat
@echo off

::就業時間（滞在時間）を設定
::時間
set wthh=8
::分
set wtmm=30


::今日の日付を取得
set yy=%date:~0,4%
set mm=%date:~5,2%
set dd=%date:~8,2%
  
set date1=%yy%-%mm%-%dd%
 
::1日前の日付を計算する（GMTになおすため）
set /a dd=%dd%-1
set dd=00%dd%
set dd=%dd:~-2%
set /a ymod=%yy% %% 4
if %dd%==00 (
if %mm%==01 (set mm=12&& set dd=31&& set /a yy=%yy%-1)
if %mm%==02 (set mm=01&& set dd=31)
if %mm%==03 (set mm=02&& set dd=28&& if %ymod%==0 (set dd=29))
if %mm%==04 (set mm=03&& set dd=31)
if %mm%==05 (set mm=04&& set dd=30)
if %mm%==06 (set mm=05&& set dd=31)
if %mm%==07 (set mm=06&& set dd=30)
if %mm%==08 (set mm=07&& set dd=31)
if %mm%==09 (set mm=08&& set dd=31)
if %mm%==10 (set mm=09&& set dd=30)
if %mm%==11 (set mm=10&& set dd=31)
if %mm%==12 (set mm=11&& set dd=30)
)
 
set date2=%yy%-%mm%-%dd%
 
::ログイン情報を取得
wevtutil qe System /f:Text /q:"*[System[(EventID=7001) and TimeCreated[@SystemTime>='%date2%T15:00:00.000Z' and @SystemTime<='%date1%T14:59:59.999Z']]]" > LoginTime.txt
 
echo;
echo 今日のPCログイン時刻一覧
echo;
::時刻情報を検索して表示
findstr "Date:" LoginTime.txt
del LoginTime.txt
 
::最初のログイン情報を取得
wevtutil qe System /c:1 /f:Text /q:"*[System[(EventID=7001) and TimeCreated[@SystemTime>='%date2%T15:00:00.000Z' and @SystemTime<='%date1%T14:59:59.999Z']]]" > LoginTime.txt
 
::ログイン時刻をstrに代入
for /f "usebackq tokens=*" %%i IN (`findstr "Date:" LoginTime.txt`) DO @set str=%%i
del LoginTime.txt
 
if "%str%" =="" (echo ログイン情報がありません && timeout /t 60 > nul && exit /B)
 
set hh=%str:~-12,2%
set mm=%str:~-9,2%
set ss=%str:~-6,2%
 
echo;
echo 出社時刻
echo %hh%時%mm%分

echo;
echo 就業時間
echo %wthh%時間%wtmm%分

::退社時刻計算
set /a hh = 1%hh% - 100
set /a mm = 1%mm% - 100
set /a hh=%hh%+%wthh%
set /a mm=%mm%+%wtmm%
if %mm% geq 60 (set /a mm=%mm%-60 && set /a hh=%hh%+1)
 
echo;
echo 退社時刻
echo %hh%時%mm%分
 
set str=%time%
set chh=%str:~0,2%
set cmm=%str:~3,2%
echo;
echo 現在時刻
echo %chh%時%cmm%分

::残り時間計算
set /a chh = 1%chh% - 100
set /a cmm = 1%cmm% - 100
set /a hh=%hh%-%chh%
if %mm% lss %cmm% (set /a mm=%mm%+60 && set /a hh=%hh%-1)
set /a mm=%mm%-%cmm%
 
echo;
echo 残り時間
if %hh% lss 0 (echo 0時間0分) else (echo %hh%時間%mm%分)

timeout /t 60 > nul

```