AD環境でログオン/ログオフ時間を収集
よくある話かとは思いますが、Active Directory 環境で、各パソコンのログオン・ログオフ時間を収集したいというリクエストがありました。
当初は、ADサーバーにイベント情報を転送する形式で作ってみたものの、テストではうまくいくのに、いざ運用に乗せてみると、転送されている情報とされていないものにがあり、その原因がわからず困惑、、、、
やっとわかった原因は、
・今回の環境は、ドメインコントローラーが複数台ある
・イベントが転送される先は、ログイン時の認証に使った(?)ドメインコントローラーで、どれかのドメインコントローラーには転送されている
ということでした。
どれかに転送されていて漏れがないのであればよいような気はするものの、あとからデータを調べたいときに、どこにデータがあるのか探すのが大変。。。
ということで、以下のような対応に変更しました。
・ログオンスクリプトで各パソコン内のイベント情報からログオン・ログオフの情報を抽出し、共有フォルダにCSV出力する
・CSVファイルにはコンピューター名を付与することで、競合を回避する
・前回出力時からの差分情報を追記していくようにする
その時作成したPower Shellのスクリプトはこんな感じ
$CSVFile = "Logon_info_" + $env:USERNAME + "_" + $env:COMPUTERNAME + ".csv"
$CSVPath = "\\隠し共有フォルダ\Logon_info"
$CSVFileName = Join-Path $CSVPath $CSVFile
$EventSource = "Microsoft-Windows-Winlogon"
##前回の処理結果を取得する
$CSVExist = (Test-Path $CSVFileName)
if ($CSVExist) {
#CSVファイルが既に存在する場合は最終行を取得
$LastExec = (Get-Content -Path $CSVFileName -Tail 1 ) -split ","
try {
$LastExecDT = (Get-Date $LastExec[3] -Format "yyyy/MM/dd hh:mm:ss")
} catch {
$LastExecDT = (Get-Date).AddMonths(-1)
}
} else {
#CSVファイルが存在しない場合は1ヵ月前を設定する
$LastExecDT = (Get-Date).AddMonths(-1)
}
##イベントログを取得
$EventLog = (Get-EventLog -LogName "System" -Source $EventSource -After $LastExecDT |
Select-Object -Property TimeGenerated,EventID |
Sort-Object -Property TimeGenerated
)
##イベントログをCSVファイルに出力
$CSVRecord = @()
foreach ($EventRecord in $EventLog) {
switch ($EventRecord.EventID) {
"7001" { $EventName = "Logon" }
"7002" { $EventName = "Logoff" }
Default { continue }
}
$CSVArray = @()
$CSVArray += $env:USERNAME
$CSVArray += $env:COMPUTERNAME
$CSVArray += $EventName
$CSVArray += $EventRecord.TimeGenerated
$CSVRecord += $CSVArray -join ","
}
if ($CSVRecord.Count -gt 0) {
# CSV出力
Write-Output $CSVRecord | Out-File -FilePath $CSVFileName -Encoding Default -append
}
ただ、これでもまだ問題があり、ログオン時に社内ネットワークにつながっておらず、キャッシュログオンだった場合にログオンスクリプトが実行されない問題が見つかったため、その改善策は次回以降に書いてみたいと思います。


