IRONSMITHINTEL
HIGH
|Auth: local access|Reboot: not required|Est. 10 minutes|✓ ScriptJump to Patch ↓

Enable Script Block Logging to Capture All PowerShell Commands for Forensic Investigation

Without script block logging, attackers can execute PowerShell payloads on your server and leave no trace — enabling it captures every command for forensic investigation.

✓ Tested on WS2022·Rollback included

Published May 7, 2026 · Updated May 7, 2026
Why patchRisk explained in plain English
Worst-case scenarioIf unpatched

Without script block logging, an attacker can download and execute Mimikatz, Empire, Cobalt Strike stagers, or any other PowerShell payload with no forensic evidence in the Windows event logs. Investigations after an incident cannot determine what commands were run, what data was exfiltrated, or how lateral movement occurred.

How the attack works

PowerShell is the primary tool used by attackers, penetration testers, and malware for post-exploitation activities including credential dumping, lateral movement, and ransomware deployment. Without script block logging enabled, PowerShell commands and scripts execute without any log entry being created. This leaves incident responders blind during forensic investigation. Script block logging records the content of every PowerShell script block that executes, even when obfuscated or run via reflection.

Am I affected?Quick check

Probably yes if any of these apply:

All Windows Servers
Domain Controllers
Any server where PowerShell is available
Running Script block logging disabled (EnableScriptBlockLogging = 0 or not configured)

Affected OS versions

Windows Server 2016Windows Server 2019Windows Server 2022
Fixed inScript block logging enabled (EnableScriptBlockLogging = 1)
Real-world incidentsWhat we've seen

In the majority of ransomware incident response cases, PowerShell was used to deploy the ransomware payload. Without script block logging enabled, incident responders cannot determine the original infection vector or the full scope of lateral movement. Organisations with logging enabled can reconstruct the entire attack chain from event logs.

How to patchRecommended: PowerShell script
Script Package✓ Tested WS2022
v1.0.0

Fix-Windows-Server-Powershell-Script-Block-Logging-Enabled-Hardening.ps1

5.1 KB
↓ Download Fix

Rollback-Windows-Server-Powershell-Script-Block-Logging-Enabled-Hardening.ps1

1.7 KB
↓ Download Rollback

SHA-256: 46b476b028c4e5f2d2770923af065e8e5869aaa26f9cd6f4f80e210db9fab03c

Run interactively

.\Fix-Windows-Server-Powershell-Script-Block-Logging-Enabled-Hardening.ps1

Run silently (SCCM / Intune)

.\Fix-Windows-Server-Powershell-Script-Block-Logging-Enabled-Hardening.ps1 -Silent -OutputPath C:\Logs

Manual fallback (no script)

10 minutes

Check Current Logging Status

$path = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging'
$val = Get-ItemProperty -Path $path -Name EnableScriptBlockLogging -ErrorAction SilentlyContinue
if ($val.EnableScriptBlockLogging -eq 1) {
    Write-Host "SECURE: Script block logging is enabled" -ForegroundColor Green
} else {
    Write-Host "NOT CONFIGURED: Script block logging is disabled" -ForegroundColor Red
}

Enable Script Block Logging

$path = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging'
New-Item -Path $path -Force | Out-Null
Set-ItemProperty -Path $path -Name EnableScriptBlockLogging -Value 1 -Type DWord

# Also enable Module Logging for additional visibility
$modPath = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging'
New-Item -Path $modPath -Force | Out-Null
Set-ItemProperty -Path $modPath -Name EnableModuleLogging -Value 1 -Type DWord
New-Item -Path "$modPath\ModuleNames" -Force | Out-Null
Set-ItemProperty -Path "$modPath\ModuleNames" -Name '*' -Value '*' -Type String

View Captured Script Blocks

# Script blocks are logged to: Windows PowerShell event log, Event ID 4104
Get-WinEvent -LogName 'Microsoft-Windows-PowerShell/Operational' |
    Where-Object { $_.Id -eq 4104 } |
    Select-Object TimeCreated, Message |
    Select-Object -Last 20

Verification

(Get-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging').EnableScriptBlockLogging
# Must return 1

Verify after patching

Confirm the patched version is running:

# Expect: Script block logging enabled (EnableScriptBlockLogging = 1) or later
Script details · parameters · exit codes
Script Packagev1.0.0 · Tested WS2022 · Rollback included
✓ Fully tested
Fix Script
Fix-Windows-Server-Powershell-Script-Block-Logging-Enabled-Hardening.ps1
↓ Download
Rollback Script
Rollback-Windows-Server-Powershell-Script-Block-Logging-Enabled-Hardening.ps1
↓ Download
SHA-256 verified · Hashes confirmed on download

Tested On

Reboot

No Reboot

SCCM

✓ Compatible

Est. Time

10 minutes

Parameters

-SilentSuppress all console output. Always used when called via API or SCCM.
-OutputPathDirectory for log files and downloaded installers. Defaults to script directory.

How to Run

Interactive — see output in console

.\Fix-Windows-Server-Powershell-Script-Block-Logging-Enabled-Hardening.ps1

Silent mode — for SCCM / automation

.\Fix-Windows-Server-Powershell-Script-Block-Logging-Enabled-Hardening.ps1 -Silent

With custom log path

.\Fix-Windows-Server-Powershell-Script-Block-Logging-Enabled-Hardening.ps1 -OutputPath "C:\Logs"

Exit Codes

CodeMeaning
0Success — fix applied or already patched
1Failure — check log file
3010Success — reboot required to complete
✓ Fully tested

Fix, idempotency, and rollback verified on

⚠ Rollback available. If this fix causes issues, run Rollback-Windows-Server-Powershell-Script-Block-Logging-Enabled-Hardening.ps1 to restore the previous state.