Sorting Windows events by UserID is a critical piece of auditing. In the code and examples below, I concentrate on:
$Logs="System","Application","Microsoft-Windows-GroupPolicy/Operational"
purposefully leaving out the Security log. We can create a simple function that allows us to check all events logs on any machine sorted by file size:
function CheckEventLogsBySize
{
get-winevent -listlog * | Sort -desc FileSize |
ft -auto LogName,@{Label="FileLogSize(MB)"; Expression={$_.FileSize/1MB}},@{Label="MaxLogSize(MB)"; Expression={$_.MaximumSizeINBytes/1MB}},LastWriteTime,IsLogFull
}
This gives us a clear view of all log file size, maximum log size, last write time:
We can also sort by 'LastWriteTime'.
function CheckEventLogsByLastWrite
{
get-winevent -listlog * | Sort -desc LastWriteTime |
ft -auto LogName,LastWriteTime,@{Label="FileLogSize(MB)"; Expression={$_.FileSize/1MB}},@{Label="MaxLogSize(MB)"; Expression={$_.MaximumSizeINBytes/1MB}},IsLogFull
}
We can create a 'filterhashtable' array that searches multiple logs for event instances where there is an associated UserID. N.B.: 'ea -0' replaces 'erroraction silentlycontinue' or '$erroractionpreference=silentlycontinue'. '-Max 10000' limits the data collection to the last 10K events.
$Logs="System","Application","Microsoft-Windows-GroupPolicy/Operational"
$a=get-winevent -ea 0 -filterhashtable @{Logname=@($Logs)} -Max 10000
$host.UI.RawUI.BufferSize = new-object System.Management.Automation.Host.Size(500,1000)
$a | where {$_.UserID} | ft TimeCreated,LogName,RecordID,ID,UserID,Message -auto | more
Following from above we can sort for all unique UserIDs:.
$b=$a | Select TimeCreated,LogName,RecordID,ID,UserID,Message | where {$_.UserID}
$c=$b | Select -unique UserID
$c | more
UserId
------
S-1-5-19
S-1-5-18
S-1-5-21-3270194588-3457409491-1468880025-1004
S-1-5-20
Next we create a list of the UserIDs of which we wish to search:
$UserIDs="S-1-5-18","S-1-5-19","S-1-5-20"
$a | where {($_.UserID -eq $UserIDs[0]) -or ($_.UserID -eq $UserIDs[1]) -or ($_.UserID -eq $UserIDs[2])} |ft TimeCreated,LogName,ID,RecordID,UserID,Message -auto | more
We can also create a function (as below) to accomplish the same output:
function UserID-filter
{
$Logs="System","Application","Microsoft-Windows-GroupPolicy/Operational"
$UserIDs="S-1-5-18","S-1-5-19","S-1-5-20"
$Global:Query=get-winevent -ea 0 -filterhashtable @{Logname=@($Logs)} -max 10000
$Query | Select TimeCreated,LogName,ID,RecordID,UserID,Message | where {($_.UserID -eq $UserIDs[0]) -or ($_.UserID -eq $UserIDs[1]) -or ($_.UserID -eq $UserIDs[2])}
}
$Logs="System","Application","Microsoft-Windows-GroupPolicy/Operational"
purposefully leaving out the Security log. We can create a simple function that allows us to check all events logs on any machine sorted by file size:
function CheckEventLogsBySize
{
get-winevent -listlog * | Sort -desc FileSize |
ft -auto LogName,@{Label="FileLogSize(MB)"; Expression={$_.FileSize/1MB}},@{Label="MaxLogSize(MB)"; Expression={$_.MaximumSizeINBytes/1MB}},LastWriteTime,IsLogFull
}
This gives us a clear view of all log file size, maximum log size, last write time:
We can also sort by 'LastWriteTime'.
function CheckEventLogsByLastWrite
{
get-winevent -listlog * | Sort -desc LastWriteTime |
ft -auto LogName,LastWriteTime,@{Label="FileLogSize(MB)"; Expression={$_.FileSize/1MB}},@{Label="MaxLogSize(MB)"; Expression={$_.MaximumSizeINBytes/1MB}},IsLogFull
}
We can create a 'filterhashtable' array that searches multiple logs for event instances where there is an associated UserID. N.B.: 'ea -0' replaces 'erroraction silentlycontinue' or '$erroractionpreference=silentlycontinue'. '-Max 10000' limits the data collection to the last 10K events.
$Logs="System","Application","Microsoft-Windows-GroupPolicy/Operational"
$a=get-winevent -ea 0 -filterhashtable @{Logname=@($Logs)} -Max 10000
$host.UI.RawUI.BufferSize = new-object System.Management.Automation.Host.Size(500,1000)
$a | where {$_.UserID} | ft TimeCreated,LogName,RecordID,ID,UserID,Message -auto | more
Following from above we can sort for all unique UserIDs:.
$b=$a | Select TimeCreated,LogName,RecordID,ID,UserID,Message | where {$_.UserID}
$c=$b | Select -unique UserID
$c | more
UserId
------
S-1-5-19
S-1-5-18
S-1-5-21-3270194588-3457409491-1468880025-1004
S-1-5-20
Next we create a list of the UserIDs of which we wish to search:
$UserIDs="S-1-5-18","S-1-5-19","S-1-5-20"
$a | where {($_.UserID -eq $UserIDs[0]) -or ($_.UserID -eq $UserIDs[1]) -or ($_.UserID -eq $UserIDs[2])} |ft TimeCreated,LogName,ID,RecordID,UserID,Message -auto | more
We can also create a function (as below) to accomplish the same output:
function UserID-filter
{
$Logs="System","Application","Microsoft-Windows-GroupPolicy/Operational"
$UserIDs="S-1-5-18","S-1-5-19","S-1-5-20"
$Global:Query=get-winevent -ea 0 -filterhashtable @{Logname=@($Logs)} -max 10000
$Query | Select TimeCreated,LogName,ID,RecordID,UserID,Message | where {($_.UserID -eq $UserIDs[0]) -or ($_.UserID -eq $UserIDs[1]) -or ($_.UserID -eq $UserIDs[2])}
}