Get-WinEvent — how to investigate errors and crashes on Windows

Get-WinEvent — how to investigate errors and crashes on Windows

The PC rebooted on its own at three in the morning. You open Windows Event Viewer and find 40,000 unfiltered entries. Ten minutes later you're still scrolling. With the Get-WinEvent cmdlet in PowerShell, you get to the cause in under a minute — and you can automate the sweep to run every week.

Why Get-WinEvent instead of Event Viewer?

Event Viewer is fine for casual exploration. When you know what you're looking for — a crash, a service that stopped, errors in the middle of the night — the graphical interface becomes an obstacle. Get-WinEvent filters server-side: only the events matching your criteria reach PowerShell, without loading the entire log into memory.

Another differentiator: Get-WinEvent works remotely out of the box. With a -ComputerName parameter, you query the log of any machine on the network that accepts WinRM — no agent to install, no RDP, no opening the GUI on the server. For anyone administering more than one PC, that saves considerable time.

If you're just getting started with PowerShell, the PowerShell for beginners guide covers the pipeline and Select-Object concepts that will make the examples below much easier to follow.

Prerequisite: run as Administrator

Most system logs require elevated privileges. Without them, Get-WinEvent silently returns an access error — you see the message, but not the critical events. To open PowerShell as admin: Win + X → Terminal (Admin), or right-click the PowerShell icon → Run as administrator.

Viewing the latest system errors

The System log records events from Windows itself: a driver failed, a service didn't start, hardware reported a problem. To list the 50 most recent error events (Level 2 = Error):

Get-WinEvent -FilterHashtable @{LogName='System'; Level=2} -MaxEvents 50 |
    Select-Object TimeCreated, Id, ProviderName, Message |
    Format-Table -AutoSize -Wrap

The ProviderName column identifies what generated the event — a driver, a service or a Windows component. The Id column is the event number: a universal identifier you can paste straight into Google or Microsoft Learn to understand what that code means.

For critical events (Level 1), change the value:

Get-WinEvent -FilterHashtable @{LogName='System'; Level=1} |
    Select-Object TimeCreated, Id, ProviderName, Message |
    Format-Table -AutoSize -Wrap

How to find out why Windows rebooted on its own

Which event records unexpected restarts on Windows?

Event ID 41 from the Kernel-Power provider indicates the system was shut down without going through the normal shutdown process — a BSOD, a total freeze, a power outage or overheating. Event ID 6008 complements it: on the next boot, it records that the previous shutdown was unexpected.

# BSOD or freeze — the kernel didn't record a clean shutdown
Get-WinEvent -FilterHashtable @{
    LogName='System'
    ProviderName='Microsoft-Windows-Kernel-Power'
    Id=41
} | Select-Object TimeCreated, Message | Format-List

# Confirmation of an unexpected shutdown (logged at the next startup)
Get-WinEvent -FilterHashtable @{LogName='System'; Id=6008} |
    Select-Object TimeCreated, Message | Format-List

Use Format-List here instead of Format-Table: the full Event 41 message shows the BugCheckCode (the BSOD's hexadecimal code), which is the most useful data point for identifying the cause — a corrupted driver, faulty RAM, temperature.

Diagnosing a service that stopped working

The Service Control Manager logs two distinct situations when a service dies unexpectedly:

  • Event ID 7031 — the service terminated unexpectedly and a recovery action was triggered (restart, run a program).
  • Event ID 7034 — the service terminated unexpectedly, with no recovery action configured.
Get-WinEvent -FilterHashtable @{
    LogName='System'
    ProviderName='Service Control Manager'
    Id=7031,7034
} | Select-Object TimeCreated, Id, Message | Format-List

The message includes the service name and how many times it has failed in the current session. If you see a critical service — Windows Defender, DNS Client, RPC Server — failing repeatedly, the problem goes beyond an unstable process and deserves immediate attention.

Application errors over the past week

Application crashes live in the Application log, under Event ID 1000 (Application Error). The FilterHashtable's StartTime parameter accepts a DateTime object, which makes filtering by period straightforward:

Get-WinEvent -FilterHashtable @{
    LogName='Application'
    ProviderName='Application Error'
    Id=1000
    StartTime=(Get-Date).AddDays(-7)
} | Select-Object TimeCreated, Message | Format-List

The message shows the name of the executable that crashed, the name and version of the module that caused the failure, and the offset address. Those three pieces together are enough to track down the problem with the vendor's support or in databases like NTDebug without needing a full dump.

Querying the log of another machine on the network

This is the advantage the graphical Event Viewer hides behind several menus. With WinRM enabled on the target machine (Enable-PSRemoting -Force), one line is enough:

Get-WinEvent -FilterHashtable @{LogName='System'; Level=2} -ComputerName PC-NAME |
    Select-Object TimeCreated, Id, ProviderName, Message |
    Format-Table -AutoSize -Wrap

Replace PC-NAME with the machine's hostname or IP. The current user's credentials are used; if the machine is in another domain, add -Credential (Get-Credential).

Exporting to CSV

When you need to share the result with someone else or record the errors from a given period, the pipeline goes straight to a file:

Get-WinEvent -FilterHashtable @{LogName='System'; Level=2; StartTime=(Get-Date).AddDays(-7)} |
    Select-Object TimeCreated, Id, ProviderName, Message |
    Export-Csv -Path "$env:USERPROFILE\Desktop\system-errors.csv" -NoTypeInformation -Encoding UTF8

The file appears on the Desktop, ready to open in Excel or send to technical support — no screenshots of Event Viewer required.

Combining diagnostics and security

Get-WinEvent covers two different universes: the diagnosis of technical failures we've seen here, and security auditing — suspicious logins, service creation, script execution. If you want to use the same logs to detect malicious activity, the post on PowerShell for auditing Windows security logs covers that second angle with ready-made scripts for automatic alerts.

And if you want this error sweep to run automatically every week — without depending on remembering to open the terminal — the schtasks guide shows how to schedule any PowerShell script without opening Task Scheduler.

Comments