Windows & Linux · Windows Event Log Analysis Using PowerShell

Windows Event Log Analysis Using PowerShell

Platform: Windows Server 2022 (GUI or Core)

Focus: Security & System logs without Event Viewer

View this project on GitHub

Lab Objective

This lab demonstrates how to enumerate, query, filter, and export Windows Event Logs using PowerShell. A practice that can come in handy in scenarios where you're troubleshooting a server and GUI access is limited or unavailable, and you need to quickly evaluate something.

Lab Environment Setup

Event Log Operations with PowerShell

This lab demonstration is being performed on a Windows Server 2022 Evaluation version installed on a Hyper-V VM instance, with remote access via RDP protocol, to work with some Windows event logs using the Get-WinEvent cmdlet between these two elevated PowerShell sessions.

Get-WinEvent is a PowerShell cmdlet that provides direct, scriptable access to Windows Event Logs, enabling administrators to perform efficient log analysis, troubleshooting, and incident response without relying on the Event Viewer GUI.





1. Enumerating Available Windows Event Logs

Get-WinEvent -ListLog *

This command enumerates every Windows Event Log available on the system, returning high-level metadata about each log rather than indivdual events.

Providing a complete inventory of available Windows Event Logs, allowing administrators to identify where meaningful data exists before querying individual events.





2. Reviewing Recent System Activity

Get-WinEvent -LogName System -MaxEvents 50

This command retrieves the 50 most recent events from the System event log, displaying them directly in the PowerShell console.

Outputting the most recent system-level events, providing immediate visibility into service activity, updates, and core OS behavior.

This output exposes system uptime and time adjustments, helping confirm system stability and maintain accurate timelines during troubleshooting and incident response.





3. Filtering System Events by Time Window (Native Engine)

Get-WinEvent -FilterHashtable @{ LogName = 'System' StartTime = (Get-Date).AddHours(-24) }

This command retrieves only System log events that occurred within the last 24 hours, using PowerShell's native event filtering engine instead of post-processing results.

PowerShell’s native event filtering engine allows administrators to query Windows Event Logs efficiently by filtering events at the source, reducing resource usage and enabling scalable, automation-friendly log analysis.

Here it shows the Windows update service started downloading an update.





4. Detecting Failed Authentication Attempts (Security Event ID 4625)

Get-WinEvent -FilterHashtable @{ LogName = 'Security' Id = 4625 }

This command identifies failed authentication attempts by querying Security Event ID 4625, a key indicator used for detecting unauthorized access and credential misuse.





5. Monitoring Successful Logons (Security Event ID 4624)

Get-WinEvent -FilterHashtable @{ LogName = 'Security' Id = 4624 }

This command queries successful authentication events (Event ID 4624), providing visibility into who and what is actively logging on to the system.





6. Detecting Failed Authentication Attempts (Security Event ID 4625)

Pipeline-Based Event Filtering (Post-Query Analysis)

Get-WinEvent -LogName Security | Where-Object { $_.Id -eq 4625 } | Select-Object TimeCreated, Id, Message

This command demonstrates pipeline-based filtering to isolate failed authentication events (Event ID 4625).





7. Identifying High-Frequency System Events (Event ID Pattern Analysis)

Get-WinEvent -LogName System -MaxEvents 100 | Group-Object Id | Sort-Object Count -Descending | Select-Object -First 10

This command groups recent system events by Event ID and ranks them by frequency, helping identify dominant system behaviors and recurring activity patterns.





8. Reconstructing System Startup and Shutdown History

Get-WinEvent -FilterHashtable @{ LogName = 'System' Id = 6005,6006,6008 StartTime = (Get-Date).AddDays(-14) }

This command reconstructs system startup and shutdown activity by correlating Event IDs 6005, 6006, and 6008 over a defined time window.





9.Validating Service Stability via Crash Event Analysis

Get-WinEvent -FilterHashtable @{ LogName = 'System' Id = 7031,7034 StartTime = (Get-Date).AddDays(-3) }

This command checks the System event log for recent service crashes (Event IDs 7032 and 7034) within the last three days. The absence of results indicates that no services terminated unexpectedly during this period, suggesting stable service operation.





10. Comparing Failed vs Successful Authentication Activity

Get-WinEvent -FilterHashtable @{ LogName = 'Security' Id = 4625 StartTime = (Get-Date).AddHours(-1) }

Get-WinEvent -FilterHashtable @{ LogName = 'Security' Id = 4624 StartTime = (Get-Date).AddHours(-1) }

These commands compare failed and successful authentication events within the last hour. The absence of Event ID 4625 indicates no failed logon attempts during this period, while multiple Event ID 4624 entries confirm normal authentication activity.

This contrast helps validate system security and rule out brute-force or credential misuse attempts.





11. Tracking Privilege Assignment During Authentication

Get-WinEvent -FilterHashtable @{ LogName = 'Security' Id = 4672 StartTime = (Get-Date).AddHours(-1) }

This command retrieves security events indicating when elevated privileges were assigned during a logon. Event ID 4672 is generated when an account logs in with administrative or special rights. Monitoring these events helps identify privileged access, validate administrative activity, and detect potential unauthorized elevation attempts.





12. Validating Service Stability (No Abnormal Terminations Detected)

Get-WinEvent -LogName System | Where-Object { $_.Id -in 7031,7034 } | Select-Object TimeCreated, Id, Message

This command searches the System event log for service crash and abnormal termination events (7031 and 7034). The absence of output indicates that no services have failed or exited unexpectedly, helping confirm system stability during routine health checks.





13. Reconstructing Recent Authentication Activity

Get-WinEvent -LogName Security | Where-Object { $_.TimeCreated -gt (Get-Date).Date.AddHours(-8) } | Select-Object TimeCreated, Id, Message

This command builds a chronological view of recent security activity by filtering Security event logs to the last eight hours. By displaying logon (4624), privilege assignment (4672), and logoff (4634) events together, it helps reconstruct user and system authentication activity and validate normal administrative behavior.





14. Using Negative Evidence to Validate Authentication Security

Get-WinEvent -FilterHashtable @{ LogName = 'Security' Id = 4625 StartTime = (Get-Date).AddDays(-1) } | Export-Csv FailedLogons.csv -NoTypeInformation

This command attempts to export failed authentication events (Event ID 4625) from the Security log over the last 24 hours into a CSV file for reporting or investigation. In this case, no events were found, indicating no failed logon attempts occurred during the selected timeframe. This confirms a healthy authentication state and demonstrates how PowerShell can be used to generate audit-ready evidence—even when no issues are present.







Troubleshooting & Incident Scenarios


1. System Startup & Shutdown Timeline Reconstruction

Get-WinEvent -FilterHashtable @{ LogName = 'System' Id = 6005,6006,6008 StartTime = (Get-Date).AddDays(-7) }

This command queries the System event log for startup, shutdown, and unexpected shutdown events over the past 7 days. By correlating Event IDs 6005, 6006, and 6008, administrators can quickly reconstruct system reboot timelines and distinguish between clean shutdowns and abnormal terminations.





2. Investigating Recent System Activity During Live Troubleshooting

Get-WinEvent -LogName System | Where-Object { $_.TimeCreated -lt (Get-Date) -and $_.TimeCreated -gt (Get-Date).AddMinutes(-15) }

This command filters the System event log to display only events generated within the last 15 minutes. By focusing on a narrow time window, administrators can quickly identify recent service state changes and system activity during live troubleshooting or incident investigation.





3. Ruling Out Service-Level Crashes as a Root Cause

Get-WinEvent -FilterHashtable @{ LogName = 'System' Id = 7031,7034 StartTime = (Get-Date).AddDays(-3) }

This command queries the System event log for service crash and abnormal termination events (7031 and 7034) over the past three days. The absence of results confirms that no services failed unexpectedly during this period, indicating system stability and ruling out service-level crashes as a root cause.





4. Reviewing Authentication Activity Outside Normal Business Hours

Get-WinEvent -LogName Security | Where-Object { $_.TimeCreated.Hour -lt 6 -or $_.TimeCreated.Hour -gt 20 }

This query filters the Windows Security event log to identify authentication and privilege-related activity occurring outside of normal business hours. By focusing on late-night and early-morning events, this approach highlights off-hours logons and privileged sessions that may warrant closer review during incident investigations or audit scenarios.





5. Reviewing Scheduled Task Activity Over the Last 24 Hours

Get-WinEvent -FilterHashtable @{ LogName = 'Microsoft-Windows-TaskScheduler/Operational' StartTime = (Get-Date).AddDays(-1) }

This query examines the Task Scheduler Operational log to identify scheduled task activity over the last 24 hours. It provides visibility into task execution, completion, failures, and updates, including the processes launched and the security context under which they ran. Task Scheduler is a common mechanism for both legitimate automation and malicious persistence, making this log a valuable source for behavioral analysis and incident investigations.





6. Detecting System Instability Through Error and Critical Events

Get-WinEvent -LogName System | Where-Object { $_.LevelDisplayName -in 'Error','Critical' } | Select TimeCreated, Id, Message

This query filters the System event log to surface only Error and Critical events, providing a focused view of serious operating system issues. It highlights unexpected shutdowns, reboot anomalies, service failures, time synchronization events, and firmware-related security messages. This type of analysis is useful for diagnosing system instability, identifying power or hardware issues, and validating system health during incident response or troubleshooting.





7. Detecting Noisy and Recurring System Events

Get-WinEvent -LogName System | Group-Object Id | Sort Count -Descending | Select -First 10

This command summarizes the System event log by grouping events based on Event ID and ranking them by frequency. It provides a high-level view of the most common system activities, allowing administrators to identify normal operational patterns, noisy events, and frequently occurring service state changes. This technique is useful for establishing a system baseline and prioritizing which event types deserve closer investigation.





8. Validating Administrative Logon Activity

Get-WinEvent -FilterHashtable @{ LogName = 'Security' Id = 4672 StartTime = (Get-Date).AddDays(-1) }

This query retrieves Security log events where special privileges were assigned during logon. Event ID 4672 indicates that a user or process received elevated rights such as administrative or system-level privileges. Monitoring this event is critical for detecting privileged access, validating administrative activity, and identifying potential privilege escalation during security investigations.





9. Collecting System Error Events for Troubleshooting

Get-WinEvent -LogName System | Where-Object { $_.LevelDisplayName -eq 'Error' } | Export-Csv SystemErrors.csv -NoTypeInformation

This command filters the System event log to extract only Error-level events and exports the results to a CSV file. This approach allows administrators to create a structured report of system failures for documentation, troubleshooting, and trend analysis. Exporting logs in this format supports incident response workflows and enables easy sharing with stakeholders.

Back to Home