我一直在研究一个脚本,从事件日志中提取登录/注销历史记录。问题是我找到的几乎每个代码示例都使用"Get-EventLog",它确实有效,但由于在服务器上找到的事件日志比典型工作站大得多,因此处理速度非常慢。因此,我选择了"Get-WinEvent",因为它提供了非常相似的结果,但在几秒钟内返回结果。我遇到的问题是将所述结果的输出操纵成可用的形式。任何帮助将不胜感激!
更新:我能够自己慢慢解决这个问题。有关详细信息,请参阅评论。感谢任何正在研究此:)
的人原始工作代码(获取事件日志 - 慢速输出(
function get-logonhistory{
cls
$Result = @()
Write-Host "Gathering Event Logs, this can take awhile..."
$ELogs = Get-EventLog System -Source Microsoft-Windows-WinLogon
If ($ELogs)
{ Write-Host "Processing..."
ForEach ($Log in $ELogs)
{ If ($Log.InstanceId -eq 7001)
{ $ET = "Logon"
}
ElseIf ($Log.InstanceId -eq 7002)
{ $ET = "Logoff"
}
Else
{ Continue
}
$Result += New-Object PSObject -Property @{
Time = $Log.TimeWritten
'Event Type' = $ET
User = (New-Object System.Security.Principal.SecurityIdentifier $Log.ReplacementStrings[1]).Translate([System.Security.Principal.NTAccount])
}
}
$Result | Select Time,"Event Type",User | Sort Time -Descending | Out-GridView
Write-Host "Done."
}
Else
{ Write-Host "There was a problem reading the logs..."
}
}
get-logonhistory
(Get-WinEvent( - 几乎即时的结果
function get-logonhistory{
cls
$Result = @()
Write-Host "Gathering Event Logs, this can take awhile..."
$ELogs = Get-WinEvent -ea SilentlyContinue ` -ProviderName “Microsoft-Windows-Winlogon”| Where-Object { $_.TimeCreated -le [datetime]::today}
If ($ELogs)
{ Write-Host "Processing..."
ForEach ($Log in $ELogs)
{ If ($Log.Id -eq 7001)
{ $ET = "Logon"
}
ElseIf ($Log.Id -eq 7002)
{ $ET = "Logoff"
}
Else
{ Continue
}
$SID = $Log.Properties.Value.Value
$objSID = New-Object System.Security.Principal.SecurityIdentifier $SID
$objUser = $objSID.Translate( [System.Security.Principal.NTAccount])
$Result += New-Object PSObject -Property @{
Time = $Log.TimeCreated
'Event Type' = $ET
User = $objUser.Value
}
}
$Result | Select Time,"Event Type",User | Sort Time -Descending | Out-GridView
Write-Host "Done."
}
Else
{ Write-Host "There was a problem reading the logs..."
}
}
get-logonhistory
Get-WinEvent 和 Get-EventLog 使用不同的数组来存储事件日志的详细信息。Get-WinEvent 用户"属性"和 Get-EventLog 用户"替换字符串"。通过将每个转换为JSON,您可以查看每个的确切详细信息,并找到所需的数据。在本例中,它是执行事件的帐户的 SID。获得此信息后,我们可以将该 SID 转换为用户名并将其输入到结果中。选择网格视图是为了更好的可用性,因此您可以根据需要过滤结果(即需要特定用户的事件(。下面是最终代码;
function get-logonhistory{
cls
$Result = @()
Write-Host "Gathering Event Logs, this can take awhile..."
$ELogs = Get-WinEvent -ea SilentlyContinue ` -ProviderName “Microsoft-Windows-Winlogon”| Where-Object { $_.TimeCreated -le [datetime]::today}
If ($ELogs)
{ Write-Host "Processing..."
ForEach ($Log in $ELogs)
{ If ($Log.Id -eq 7001)
{ $ET = "Logon"
}
ElseIf ($Log.Id -eq 7002)
{ $ET = "Logoff"
}
Else
{ Continue
}
$SID = $Log.Properties.Value.Value
$objSID = New-Object System.Security.Principal.SecurityIdentifier $SID
$objUser = $objSID.Translate( [System.Security.Principal.NTAccount])
$Result += New-Object PSObject -Property @{
'Date/Time' = $Log.TimeCreated
'Event Type' = $ET
User = $objUser.Value
}
}
$Result | Select "Date/Time","Event Type",User | Sort Time -Descending | Out-GridView -Title "System Logon Events"
Write-Host "Done."
}
Else
{ Write-Host "There was a problem reading the logs..."
}
}
get-logonhistory