Powershell - Login/Logoff Events - Get-WinEvent vs Get-EventLog

4.7k Views Asked by At

I've been working on a script to pull logon/logoff history out of the Event logs. The issue is that almost every code example I found uses "Get-EventLog" which does work, but is extremely slow processing due to the event logs found on a server being a lot larger then a typical workstation. So instead I opted for "Get-WinEvent", as it provides very similar results but returns the results within a few seconds. The issue I am having though is manipulating the output of said results into a usable form.Any assistance is GREATLY appreciated!

Update: I was able to slowly work through the issue on my own. See comments for details. Thanks for anyone who was looking into this :)

Original Working Code (Get-EventLog - Slow Output)

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) - Almost Instant Results

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
1

There are 1 best solutions below

0
On

Get-WinEvent and Get-EventLog use different arrays to store the details of an event log. Get-WinEvent users "Properties" and Get-EventLog Users "ReplacementStrings". By converting each to JSON your able to see the exact details of each, and locate the data your looking for. In this case it's the SID of the account that performed the event. Once this is obtain we can translate that SID into a Username and feed it into the results. Grid-View was opted for better usablity so you can filter the results if needed (i.e. wanting events for a specific user). Below is the final code;

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