How to Collect PowerShell Logs, Transcripts and History
Acquire the PowerShell event logs, PSReadLine history and transcripts from a live host, a triage collection or a disk image — with copy-paste commands and the gotchas.
TL;DR. On a live host, export the two PowerShell event logs with wevtutil epl (a plain copy fails — the service holds them open) and robocopy each user's *_history.txt and PowerShell_transcript.*.txt. Or grab them with KAPE / Velociraptor, or from a mounted image. Keep the Users\<name>\ path so history and transcripts are attributed. Then analyze them in your browser. The drop zone has the same commands with copy buttons.
Live host (quickest)
Run Windows PowerShell as administrator:
New-Item -ItemType Directory -Force C:\triage\logs | Out-Null
wevtutil epl Microsoft-Windows-PowerShell/Operational "C:\triage\logs\Microsoft-Windows-PowerShell%4Operational.evtx" /ow:true
wevtutil epl "Windows PowerShell" "C:\triage\logs\Windows PowerShell.evtx" /ow:true
wevtutil epl PowerShellCore/Operational "C:\triage\logs\PowerShellCore%4Operational.evtx" /ow:true 2>$null
robocopy C:\Users C:\triage\Users *_history.txt PowerShell_transcript.*.txt /S /XJ /R:0 /W:0 /NP /NDL
The third line collects the PowerShell 7 log if it exists (harmless if it does not). Then pack it into one archive with the tar.exe built into Windows 10 1803+:
tar -a -c -f C:\triage\powershell.zip -C C:\triage logs Users
Triage tools
KAPE — the EventLogs target copies every .evtx (including the PowerShell logs) from the raw disk; PowerShellConsole and PowerShellTranscripts collect the history and transcript files:
kape.exe --tsource C: --tdest C:\triage\kape --target EventLogs,PowerShellConsole,PowerShellTranscripts
Velociraptor — current releases build an offline collector from Windows.Triage.Targets in the GUI with the same EventLogs, PowerShellConsole and PowerShellTranscripts targets. Older releases that still ship Windows.KapeFiles.Targets can run:
velociraptor.exe artifacts collect Windows.KapeFiles.Targets --args Device=C: --args EventLogs=Y --args PowerShellConsole=Y --args PowerShellTranscripts=Y --output C:\triage\powershell.zip
Both target names are verified against the Velociraptor triage collector. Drop the collection ZIP as-is — non-PowerShell logs are ignored on load.
Disk image
Mount read-only and copy from winevt\Logs plus each user's profile. On Linux/macOS with the image at /mnt/win:
mkdir -p ~/triage/logs && cp "/mnt/win/Windows/System32/winevt/Logs/Microsoft-Windows-PowerShell%4Operational.evtx" "/mnt/win/Windows/System32/winevt/Logs/Windows PowerShell.evtx" ~/triage/logs/ 2>/dev/null
(cd /mnt/win && find Users \( -iname '*_history.txt' -o -iname 'PowerShell_transcript.*.txt' \) -exec cp --parents {} ~/triage/ \;)
Check the image's volume shadow copies too: an older snapshot can hold logs that have since rolled over and history that was later cleared.
Gotchas
- Script Block Logging (4104) is off by default until enabled by policy; even then, Windows logs suspicious blocks at Warning level. The classic
Windows PowerShelllog and PSReadLine history are on by default. - The EventLog service keeps logs open, so use
wevtutil epl, KAPE or Velociraptor — not a plain copy. - PSReadLine history has no timestamps and can be weeks older than the logs; treat its order as the only chronology.
- Transcripts store local time with no zone: note the host's time zone before you correlate with the UTC event logs.