← All cheat sheets

POWERSHELL LOGGING

Plain-text reference · 4 KB. Read it, search it (Ctrl-F) or print it.

How to enable and read PowerShell logging for detection and forensics.
Three independent features: Module Logging, Script Block Logging, and
Transcription. All configured via Group Policy or registry; events land in
the "Microsoft-Windows-PowerShell/Operational" and "Windows PowerShell" logs.

KEY EVENT IDS#

Log: Microsoft-Windows-PowerShell/Operational
  4103  Module logging  - pipeline execution details (command invocation)
  4104  Script block logging - the actual code that was run (deobfuscated)
        Level "Warning" (vs Verbose) marks blocks the engine flagged as
        suspicious. 4104 is the single most useful PowerShell event.
  4105  Script block execution started
  4106  Script block execution stopped

Log: Windows PowerShell (classic)
  400   Engine state changed to Available (a session/host started)
        HostName field shows the host (powershell.exe, ISE, custom host).
  403   Engine state changed to Stopped (session ended)
  500/501  Command started / stopped (older)
  600   Provider lifecycle (e.g. "Provider Registry started")

WHERE EACH IS CONFIGURED (GPO)#

Computer/User Configuration >
  Administrative Templates > Windows Components > Windows PowerShell

  "Turn on Module Logging"        -> Event 4103
      Specify module names (use * for all).
  "Turn on PowerShell Script Block Logging" -> Event 4104
      Optional: "Log script block invocation start/stop" -> 4105/4106.
  "Turn on PowerShell Transcription" -> writes .txt transcripts
      Set output directory (central share recommended) and
      "Include invocation headers".

REGISTRY EQUIVALENTS (read to verify config)#

Script Block Logging:
  HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging
    EnableScriptBlockLogging = 1
    EnableScriptBlockInvocationLogging = 1   (optional, 4105/4106)

Module Logging:
  HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging
    EnableModuleLogging = 1
  ...\ModuleLogging\ModuleNames   (value "*" = all modules)

Transcription:
  HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell\Transcription
    EnableTranscripting = 1
    OutputDirectory = \\server\share\pstranscripts
    EnableInvocationHeader = 1

WHAT EACH FEATURE GIVES YOU#

Script Block Logging (4104)
  - Records the full text of script blocks AS EXECUTED, after the engine
    has deobfuscated/decoded them. Catches -EncodedCommand payloads,
    Invoke-Expression content, and in-memory execution.
  - Best single source for "what did the attacker actually run".

Module Logging (4103)
  - Logs pipeline invocation and parameter binding per command. More verbose,
    noisier, and does not always capture obfuscated input as cleanly as 4104.

Transcription
  - Plain-text input/output transcript of interactive and script sessions,
    one file per session, with timestamps and host info. Good for human
    review and for capturing command OUTPUT (which 4104 does not).

Note: PowerShell v2 lacks these features. "powershell -version 2" is a known
downgrade/evasion attempt -- alert on it and consider removing the v2 engine
(Windows optional feature "Windows PowerShell 2.0").

READING THE LOGS (read-only)#

# All script blocks in the last day
Get-WinEvent -FilterHashtable @{
  LogName='Microsoft-Windows-PowerShell/Operational'; Id=4104;
  StartTime=(Get-Date).AddDays(-1) } |
  Select-Object TimeCreated, @{n='Script';e={$_.Message}}

# Only blocks flagged suspicious (Warning level)
Get-WinEvent -FilterHashtable @{
  LogName='Microsoft-Windows-PowerShell/Operational'; Id=4104; Level=3 }

# Classic engine starts with host name
Get-WinEvent -FilterHashtable @{LogName='Windows PowerShell'; Id=400} |
  Select-Object TimeCreated, Message

DETECTION IDEAS (strings to hunt in 4104/transcripts)#

  -enc / -EncodedCommand / -e        (base64 command)
  FromBase64String                   (inline decode)
  IEX / Invoke-Expression            (dynamic execution)
  DownloadString / DownloadData / Invoke-WebRequest / Net.WebClient
  -nop / -noprofile -w hidden / -ExecutionPolicy Bypass
  [Reflection.Assembly]::Load / System.Reflection  (in-memory loading)
  powershell -version 2              (engine downgrade)
Always tune against your admin baseline before alerting.

Defensive reference on CyberRamen. Offensive / red-team sheets live on OffensiveRamen.com.