'22/11/14更新:下図のように取得したい開始日の入力を促すコードの追記しました。さらに、日付を跨いでログインもしくはログオフしたことによって、各日のログオンもしくはログオフの片方が存在しない場合はnanを挿入する仕様にした。

本記事では、下図のようにログオン、ログオフした日時を取得してcsvファイルに保存するPythonの雛形コードを載せました。また、右端の列「operating_time」には、ログオン時刻とログオフ時刻の差分を算出します。これは、勤務時間に置き換えることもできるかと思います。

ちなみに、日中にシャットダウンが複数回あったとしても、それはカウントしません。あくまで各日のログオン最初の時刻とログオフの最後の時刻を取得する仕様です。
■本プログラム
Windowsにて、PCの起動とシャットダウンの情報を得るには、Windowsコマンド「wevtutil」によるイベントログで、Windows10の場合は「7001」,「7002」を指定します。これらは、Pythonのsubprocessモジュールで実行することでテキストファイルとして取得できます。あとは、Pythonで、よしなにデータを加工して所望の書式csvにします。
import os
import subprocess
import pandas as pd
import numpy as np
import datetime
start_day_str_list = input("開始日を入力下さい。 例) 2022 11 1 \n").split()
start_day = list(map(int, start_day_str_list))
print('start day ->', start_day)
now = datetime.datetime.now()
end_day_str_list = now.strftime("%Y %m %d").split()
end_day = list(map(int, end_day_str_list))
print('end_day ->', end_day)
save_dir = os.path.join(os.environ["USERPROFILE"], "Desktop")
print(save_dir)
logtxt_path = os.path.join(save_dir, 'log.txt')
print(logtxt_path)
logcsv_path = os.path.join(save_dir, 'log.csv')
save_csv_path = os.path.join(save_dir, 'logon_off.csv')
cmd = f'wevtutil qe system /f:text /rd:true /q:"*[*[EventID=7001 or EventID=7002]]" > {logtxt_path}'
print(cmd)
subprocess.call(cmd, shell = True)
with open(logtxt_path, 'r') as f1:
with open(logcsv_path, 'w') as f2:
f2.write('row_No,Date,Time,Event ID,Description\n')
flag_Description = False
for i, row in enumerate(f1, start = 1):
if 'Date' in row:
buf_date = row.strip()[6:]
_date = buf_date[:10]
_time = buf_date[11:19]
f2.writelines([str(i), ',', _date, ',', _time, ','])
elif 'Event ID' in row:
f2.writelines([row.strip()[10:], ','])
elif 'Description' in row:
flag_Description = True
elif flag_Description:
f2.write(row.strip() + '\n')
flag_Description = False
df0 = pd.read_csv(logcsv_path, encoding = 'Shift-JIS')
print(df0)
target_list = [
'カスタマー エクスペリエンス向上プログラムのユーザー ログオン通知',
'カスタマー エクスペリエンス向上プログラムのユーザー ログオフ通知',
]
df = df0.query('Description in @target_list')
print(df)
df.to_csv(logcsv_path, index = False, encoding = 'Shift-JIS')
df['Date'] = pd.to_datetime(df['Date'])
print(df.dtypes)
df = df[df['Date'] >= datetime.datetime(*start_day)]
df = df[df['Date'] <= datetime.datetime(*end_day)]
print(df)
date_list = list(df.groupby('Date').groups.keys())
print('\n', date_list, '\n')
with open(save_csv_path, 'w') as f:
print('date', 'logon', 'logoff', 'operating_time')
col_list = ['date', 'logon', 'logoff', 'operating_time']
col_str = ','.join(map(str, col_list))
f.write(col_str + '\n')
for _date in date_list:
_df = df.groupby("Date").get_group(_date)
try:
_logon_df = _df[_df['Event ID'] == 7001]
_t_min = _logon_df['Time'].min()
except:
_t_min = np.nan
try:
_logoff_df = _df[_df['Event ID'] == 7002]
_t_max = _logoff_df['Time'].max()
except:
_t_max = np.nan
try:
_t_time = datetime.datetime.strptime(_t_max, '%H:%M:%S') \
- datetime.datetime.strptime(_t_min, '%H:%M:%S')
_date_list = [_date.date().strftime('%Y/%m/%d'), _t_min, _t_max, _t_time]
except:
_date_list = [_date.date().strftime('%Y/%m/%d'), _t_min, _t_max, np.nan]
_date_list = list(map(str, _date_list))
_date_str = ','.join(map(str, _date_list))
f.write(_date_str + '\n')
print(*_date_list)
os.remove(logtxt_path)
os.remove(logcsv_path)
以上
<広告>
リンク
リンク