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
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.
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.
Probably yes if any of these apply:
Affected OS versions
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.
Fix-Windows-Server-Powershell-Script-Block-Logging-Enabled-Hardening.ps1
5.1 KBRollback-Windows-Server-Powershell-Script-Block-Logging-Enabled-Hardening.ps1
1.7 KBSHA-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 minutesCheck 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↓
Tested On
—
Reboot
No RebootSCCM
✓ Compatible
Est. Time
10 minutes
Parameters
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
| Code | Meaning |
|---|---|
| 0 | Success — fix applied or already patched |
| 1 | Failure — check log file |
| 3010 | Success — reboot required to complete |
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.