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.
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 ID | Log | Records |
|---|---|---|
| 4104 | Operational | Script block logging: the compiled, de-obfuscated code |
| 4103 | Operational | Module logging: pipeline execution details and bound parameters |
| 400 | Windows PowerShell | Engine state → Available (a host started) |
| 403 | Windows PowerShell | Engine state → Stopped (a host exited) |
| 600 | Windows PowerShell | Provider lifecycle (e.g. Registry, Certificate) |
| 800 | Windows PowerShell | Pipeline 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.