Skip to content

PowerShell Event Logs for Forensics: Every ID That Matters

A map of PowerShell's forensic event IDs across the Operational and classic Windows PowerShell logs — 4104, 4103, 400, 403, 600, 800 — and what each one proves.

Published on 3 min read

TL;DR. PowerShell forensic evidence lives in two event logs. The modern Microsoft-Windows-PowerShell/Operational log holds 4104 (script block logging) and 4103 (module logging). The classic Windows PowerShell log holds 400/403 (engine start/stop), 600 (provider), and 800 (pipeline execution). Collect both and read them together. Open the parser to merge them into one timeline.

The two logs

PowerShell predates the modern event-log channels, so it kept its original "Windows PowerShell" classic log and added a per-provider Operational log later. An investigation needs both:

Event IDLogRecords
4104OperationalScript block logging: the compiled, de-obfuscated code
4103OperationalModule logging: pipeline execution details and bound parameters
400Windows PowerShellEngine state → Available (a host started)
403Windows PowerShellEngine state → Stopped (a host exited)
600Windows PowerShellProvider lifecycle (e.g. Registry, Certificate)
800Windows PowerShellPipeline execution details

Reading the classic events

Events 400 and 403 mark the lifetime of a PowerShell host. Their detail block carries HostName, HostApplication (the full command line, often the most useful field — an -EncodedCommand or -WindowStyle Hidden shows up here), EngineVersion and RunspaceId. A HostApplication that launches powershell.exe -Version 2 is a classic downgrade attempt to escape v5 logging and AMSI.

Event 800 records the command line of a pipeline and, depending on configuration, parameter binding details. On hosts without script block logging it is often the best record of what ran. The PowerShell Parser parses the Key=Value detail blocks of 400/600/800 into fields you can sort and export.

Which are on by default?

The classic Windows PowerShell log (400/600/800) is enabled out of the box. Module logging (4103) and full script block logging (4104) are governed by Group Policy under Administrative Templates → Windows Components → Windows PowerShell (Microsoft). Absence of 4104 does not mean nothing happened — check 800 and the warning-level 4104 blocks PowerShell logs on its own.

Collect and analyze

See how to collect the PowerShell logs, history and transcripts, then analyze them in your browser with nothing installed.

FAQ

Which logs does PowerShell write to?

Two. Microsoft-Windows-PowerShell/Operational holds modern events (4103 module logging, 4104 script block logging). The classic Windows PowerShell log holds engine and provider lifecycle (400/403/600) and pipeline execution (800).

What is the difference between 4103 and 4104?

4104 (script block logging) records the code that was compiled; 4103 (module logging) records pipeline execution details — the commands and bound parameters as they ran. They complement each other.

Is any of this on by default?

The classic Windows PowerShell log (400/600/800) is on by default. Module logging (4103) and full script block logging (4104) require a policy, though PowerShell still logs suspicious blocks at Warning level without it.

Related articles

What event ID 4104 records, how Windows splits long script blocks across events, why warning-level blocks appear without full logging, and how to read it in a case.
Step-by-step: open PowerShell .evtx logs, PSReadLine history and transcripts in a free in-browser viewer, reassemble script blocks, decode encoded commands and export CSV or JSON.
How PowerShell transcripts are structured, what the header records, how command timestamps work with -IncludeInvocationHeader, and how to investigate them.