私は最近、非常によく似たことをするように求められましたが、起動時間とログオン時間を含め、履歴を参照できるようにする必要があります。したがって、以下のPowerShellスクリプトは次のことを行います。
- いくつかの環境変数を取得
- 4つの異なるイベントログエントリの日時スタンプを取得します。これらの2番目と4番目は正確な測定値ではありませんが、かなり広範囲にわたる調査、トラブルシューティング、およびテストの後、それらは非常に近く、私が見た限りでは最良のオプションです。
- これら4つのイベントの差を計算します
- すべての数値を単純なSQLテーブルに入力します[もちろん、数値を必要なものにパイプするように適応できます]
そのため、SCCMがある場合は、スクリプトはスケジュールされたタスクを介して、または何らかのスケジュールで実行することを意図しています(ログオンを変更しないように、ログオン中ではありません)。PC名を他の名前に変更して自分のPCから実行し、リモートコンピュータからデータを取得して(ユーザー名は自分のものとして表示されます)、トラブルシューティングを行って番号を確認できるのはすばらしいことです。
私は別のステップを踏み、SharePointを使用して(BCSを使用して)外部データのリストを作成したので、フロントエンドのGUIが優れています。以下のスクリプト、私がそれを書いている間に使用したコメント行のほとんどを残しました:
$USER = $env:username.ToUpper()
$COMPUTER = $env:computername.ToUpper()
$Current_Time = Get-Date
$PCname = ''
$addedtime = 0
#1. get event time of last OS load
$filterXML = @'
<QueryList>
<Query Id="0" Path="System">
<Select Path="System">*[System[Provider[@Name='Microsoft-Windows-Kernel-General'] and (Level=4 or Level=0) and (EventID=12)]]</Select>
</Query>
</QueryList>
'@
$OSLoadTime=(Get-WinEvent -ComputerName $PCname -MaxEvents 1 -FilterXml $filterXML).timecreated
#Write-Host $PCname
#Write-Host "1. Last System Boot @ " $OSLoadTime
#2. Get event time of Time-Service [pre-Ctrl+Alt-Del] after latest OS load
$filterXML = @'
<QueryList>
<Query Id="0" Path="System">
<Select Path="System">*[System[Provider[@Name='Microsoft-Windows-Time-Service'] and (Level=4 or Level=0) and (EventID=35)]]</Select>
</Query>
</QueryList>
'@
$CtrlAltDelTime=(Get-WinEvent -ComputerName $PCname -MaxEvents 1 -FilterXml $filterXML).timecreated
#Write-Host "2. Time-sync after Boot @ " $CtrlAltDelTime
#get minutes (rounded to 1 decimal) between OS load time and 1st load of GPOs
$BootDuration = "{0:N1}" -f ((($CtrlAltDelTime - $OSLoadTime).TotalSeconds + $addedtime)/60)
#3. get event time of 1st successful logon
$filterXML = @'
<QueryList>
<Query Id="0" Path="System">
<Select Path="System">*[System[Provider[@Name='Microsoft-Windows-Winlogon'] and (Level=4 or Level=0) and (EventID=7001)]]</Select>
</Query>
</QueryList>
'@
$LogonDateTime=(Get-WinEvent -ComputerName $PCname -MaxEvents 1 -FilterXml $filterXML -ErrorAction SilentlyContinue).timecreated
If ($LogonDateTime) {
#Write-Host "3. Successful Logon @ " $LogonDateTime
}
Else {
#Write-Host "Duration of Bootup = " $BootDuration "minutes" -foregroundcolor blue -BackgroundColor white
#Write-Host $PCname "has not logged back in." -foregroundcolor red -BackgroundColor white
Exit
}
#Write-Host "Duration of Bootup = " $BootDuration "minutes" -foregroundcolor blue -BackgroundColor white
#4. Get Win License validated after logon (about same time as explorer loads)
$filterXML = @'
<QueryList>
<Query Id="0" Path="Application">
<Select Path="Application">*[System[Provider[@Name='Microsoft-Windows-Winlogon'] and (Level=4 or Level=0) and (EventID=4101)]]</Select>
</Query>
</QueryList>
'@
$DesktopTime=(Get-WinEvent -ComputerName $PCname -MaxEvents 1 -FilterXml $filterXML).timecreated
$LogonDuration = "{0:N1}" -f ((($DesktopTime - $LogonDateTime).TotalSeconds + $addedtime)/60)
#Write-Host "4. WinLicVal after Logon @ " $DesktopTime
#Write-Host "Duration of Logon = " $LogonDuration "minutes" -foregroundcolor blue -BackgroundColor white
#START SQL Injection Section
[void][reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")
$sqlServer = "SQLserver01"
$dbName = "BootUpTimes"
$tbl = "tblBootUpTimes"
#$srv = New-Object Microsoft.SqlServer.Management.Smo.Server $sqlServer
#$db = $srv.databases[$dbName]
#$conn = New-Object System.Data.SqlClient.SqlConnection("Data Source=$sqlServer;Initial Catalog=$dbName; Integrated Security=SSPI")
$conn = New-Object System.Data.SqlClient.SqlConnection("server=$sqlServer;database=$dbName;Password=plaintext;User Id=BootUpTimes")
$conn.Open()
$cmd = $conn.CreateCommand()
$cmd.CommandText = "INSERT INTO $tbl VALUES ('$Current_Time','$USER','$COMPUTER','$OSLoadTime','$CtrlAltDelTime','$BootDuration','$LogonDateTime','$DesktopTime','$LogonDuration')"
Try
{
$null = $cmd.ExecuteNonQuery()
}
Catch
{
}
$conn.Close()
この最後のSQLセクションには、プレーンテキストのパスワードを必要とせずにSQLに入力する別の方法(セキュリティベース)を提供するコメントアウトされた数行があります。