Platform: Windows Server 2022 (GUI or Core)
Focus: Security & System logs without Event Viewer
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.
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.

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.

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.

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.

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.

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.

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).

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.

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.

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.

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.

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.

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.

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.

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.

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.

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.

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.

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.

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.

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.

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.

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.

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.
