Perform comprehensive forensic analysis by correlating Event ID 4624 with related security events for incident investigation.
Correlate with logoff events (4634) to track session duration:
# Find matching logon/logoff pairs
$LogonEvents = Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4624} -MaxEvents 100
$LogoffEvents = Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4634} -MaxEvents 100
$SessionAnalysis = foreach ($logon in $LogonEvents) {
$logonXml = [xml]$logon.ToXml()
$logonData = $logonXml.Event.EventData.Data
$logonId = ($logonData | Where-Object {$_.Name -eq 'TargetLogonId'}).'#text'
$userName = ($logonData | Where-Object {$_.Name -eq 'TargetUserName'}).'#text'
$matchingLogoff = $LogoffEvents | Where-Object {
$logoffXml = [xml]$_.ToXml()
$logoffData = $logoffXml.Event.EventData.Data
$logoffId = ($logoffData | Where-Object {$_.Name -eq 'TargetLogonId'}).'#text'
$logoffId -eq $logonId
} | Select-Object -First 1
[PSCustomObject]@{
User = $userName
LogonTime = $logon.TimeCreated
LogoffTime = if ($matchingLogoff) { $matchingLogoff.TimeCreated } else { 'Still Active' }
SessionDuration = if ($matchingLogoff) {
New-TimeSpan -Start $logon.TimeCreated -End $matchingLogoff.TimeCreated
} else { 'Ongoing' }
LogonId = $logonId
}
}
$SessionAnalysis | Format-Table -AutoSize
Analyze authentication patterns and detect anomalies:
# Detect unusual logon times or frequencies
$TimeWindow = (Get-Date).AddDays(-7)
$RecentLogons = Get-WinEvent -FilterHashtable @{
LogName='Security'
Id=4624
StartTime=$TimeWindow
}
# Group by user and analyze patterns
$UserPatterns = $RecentLogons | ForEach-Object {
$xml = [xml]$_.ToXml()
$eventData = $xml.Event.EventData.Data
[PSCustomObject]@{
User = ($eventData | Where-Object {$_.Name -eq 'TargetUserName'}).'#text'
Time = $_.TimeCreated
Hour = $_.TimeCreated.Hour
DayOfWeek = $_.TimeCreated.DayOfWeek
LogonType = ($eventData | Where-Object {$_.Name -eq 'LogonType'}).'#text'
SourceIP = ($eventData | Where-Object {$_.Name -eq 'IpAddress'}).'#text'
}
} | Group-Object User
# Identify users with unusual patterns
foreach ($userGroup in $UserPatterns) {
$user = $userGroup.Name
$logons = $userGroup.Group
# Check for off-hours activity (before 6 AM or after 10 PM)
$offHoursLogons = $logons | Where-Object {$_.Hour -lt 6 -or $_.Hour -gt 22}
if ($offHoursLogons) {
Write-Host "ALERT: User $user has off-hours logons:" -ForegroundColor Red
$offHoursLogons | Format-Table Time, LogonType, SourceIP
}
}
Export comprehensive forensic report:
# Generate detailed forensic report
$ForensicReport = Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4624} -MaxEvents 1000 |
ForEach-Object {
$xml = [xml]$_.ToXml()
$eventData = $xml.Event.EventData.Data
[PSCustomObject]@{
EventTime = $_.TimeCreated
EventID = $_.Id
SubjectUserName = ($eventData | Where-Object {$_.Name -eq 'SubjectUserName'}).'#text'
TargetUserName = ($eventData | Where-Object {$_.Name -eq 'TargetUserName'}).'#text'
LogonType = ($eventData | Where-Object {$_.Name -eq 'LogonType'}).'#text'
LogonProcessName = ($eventData | Where-Object {$_.Name -eq 'LogonProcessName'}).'#text'
AuthenticationPackageName = ($eventData | Where-Object {$_.Name -eq 'AuthenticationPackageName'}).'#text'
WorkstationName = ($eventData | Where-Object {$_.Name -eq 'WorkstationName'}).'#text'
SourceNetworkAddress = ($eventData | Where-Object {$_.Name -eq 'IpAddress'}).'#text'
SourcePort = ($eventData | Where-Object {$_.Name -eq 'IpPort'}).'#text'
}
}
$ForensicReport | Export-Csv -Path "C:\Forensics\Logon_Analysis_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv" -NoTypeInformation
Warning: Large-scale forensic analysis can consume significant system resources. Run during maintenance windows when possible.