How to Configure and Audit PowerShell Script Block and Module Logging in Windows 11

Windows PowerShell is an indispensable automation and systems management platform for enterprise administrators. However, because PowerShell provides deep access to the Windows API, Windows Management Instrumentation (WMI), and kernel memory structures, it is also the tool of choice for modern cyber adversaries executing fileless attacks, living-off-the-land techniques, and post-exploitation discovery scripts. Malicious actors frequently employ obfuscation techniques—such as base64 encoding, variable substitution, and string concatenation—to hide malicious payloads from traditional command-line audit logs. Windows 11 includes a native forensic defense mechanism known as Script Block Logging (Event ID 4104). By capturing the fully de-obfuscated code blocks at the exact moment of execution within the PowerShell engine, Script Block Logging delivers uncompromised forensic visibility. Understanding how to configure, audit, and tune script block and module logging ensures enterprise security compliance.

Understanding PowerShell Auditing Tiers in Windows 11

The Windows PowerShell engine incorporates three complementary logging tiers:

  • Transcription Logging: Records all text inputs, interactive keystrokes, and standard output responses into timestamped, plain-text text files stored in a designated filesystem directory.
  • Module Logging (Event ID 4103): Records pipeline execution events, cmdlet invocations, and parameter data for specified PowerShell modules. Useful for monitoring execution of core administrative modules such as ActiveDirectory or NetSecurity.
  • Script Block Logging (Event ID 4104): Captures the complete content of script blocks as they are parsed and executed by the PowerShell Abstract Syntax Tree (AST). Even if a script was loaded in memory using deeply nested obfuscation, dynamic base64 decoders, or secure strings, Script Block Logging logs the raw, executed plaintext code block.

Configuring Script Block and Module Logging via Group Policy

The most robust method to enforce PowerShell logging across standalone or domain-joined Windows 11 workstations is via the Local Group Policy Editor.

  1. Press Windows Key + R, type gpedit.msc, and press Enter to open the Local Group Policy Editor.
  2. Navigate through the policy tree: Computer Configuration > Administrative Templates > Windows Components > Windows PowerShell.
  3. Double-click the policy setting labelled Turn on PowerShell Script Block Logging.
  4. Select Enabled.
  5. To capture all executed script blocks regardless of whether the operating system considers them inherently suspicious, check the box labelled Log script block execution start / stop events.
  6. Click Apply, then click OK.
  7. Next, double-click Turn on Module Logging and select Enabled.
  8. Under the Module Names configuration window, click Show…. In the dialog, enter an asterisk (*) to capture all modules, or specify target modules individually. Click OK.

Enforcing Script Block Logging via the Windows Registry

For automated deployment scripts, cloud images, or environments running Windows 11 Home edition (which lacks the graphical Group Policy Editor), configure logging directly through elevated PowerShell registry cmdlets.

# Enable Script Block Logging
$regPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging"
if (!(Test-Path $regPath)) { New-Item -Path $regPath -Force }
Set-ItemProperty -Path $regPath -Name "EnableScriptBlockLogging" -Value 1 -Type DWord
Set-ItemProperty -Path $regPath -Name "EnableScriptBlockInvocationLogging" -Value 1 -Type DWord

# Enable Module Logging
$modPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging"
if (!(Test-Path $modPath)) { New-Item -Path $modPath -Force }
Set-ItemProperty -Path $modPath -Name "EnableModuleLogging" -Value 1 -Type DWord

$modNamesPath = "$modPath\ModuleNames"
if (!(Test-Path $modNamesPath)) { New-Item -Path $modNamesPath -Force }
Set-ItemProperty -Path $modNamesPath -Name "*" -Value "*" -Type String

Executing these registry commands enforces universal logging instantaneously without requiring an operating system reboot.

Auditing and Inspecting Captured Logs in Event Viewer

Captured script blocks and module activities are routed to dedicated channels within the Windows Event Log repository.

  1. Press Windows Key + X and select Event Viewer.
  2. In the left-hand console tree, navigate to: Applications and Services Logs > Microsoft > Windows > PowerShell > Operational.
  3. In the right-hand Actions pane, click Filter Current Log….
  4. In the Includes event IDs field, enter 4104 (Scriptblock Logging) and 4103 (Module Logging), then click OK.
  5. Select an Event ID 4104 entry. In the general description tab below, inspect the ScriptBlock Text block. You will observe the exact lines of PowerShell code executed during that transaction, regardless of whether the command was typed interactively, invoked from an external .ps1 script, or passed via encoded CLI flags.

Inspecting Script Block Logs Programmatically Using Get-WinEvent

Security analysts can extract and parse recent script block telemetry directly within a PowerShell console:

Get-WinEvent -FilterHashtable @{
    LogName = 'Microsoft-Windows-PowerShell/Operational'
    Id = 4104
} -MaxEvents 10 | Select-Object TimeCreated, Message | Format-List

This command extracts the ten most recent script execution records, displaying the execution timestamp alongside the raw code payload for rapid threat triage.

Managing Log Buffer Capacity and Preventing Overwrite Bottlenecks

Enabling universal script block logging significantly increases event log volume. To prevent rapid log wrap-around and lost telemetry, expand the maximum log channel capacity.

  1. In Event Viewer, right-click the Operational log under Microsoft-Windows-PowerShell and select Properties.
  2. Increase the Maximum log size (KB) allocation from the default 15 MB to at least 262144 KB (256 MB) or 524288 KB (512 MB).
  3. Ensure Overwrite events as needed (oldest events first) is selected.
  4. Alternatively, configure this capacity via an elevated command prompt:
    wevtutil sl Microsoft-Windows-PowerShell/Operational /ms:268435456

Deploying Script Block and Module Logging establishes transparent, tamper-evident PowerShell execution auditing across enterprise Windows 11 environments.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.