How to Enable PowerShell Logging (Script Block and Module)

To enable PowerShell logging, turn on Script Block Logging, which records the code of every script and command that runs. For Windows PowerShell 5.1, set this registry value as administrator:

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

PowerShell 7 uses its own key and log. Below I check what’s already on, explain the three kinds of logging and show how to enable each one for both versions.

I didn’t change the logging settings on my PC. The examples read them and record a transcript in a test folder, and the commands that change policy are shown as code.

The three kinds of PowerShell logging

LoggingWhat it recordsWhere it goes
Script Block LoggingThe text of every script block that runs (event 4104)Operational event log
Module LoggingPipeline details for the modules you choose (event 4103)Operational event log
TranscriptionEverything typed and printed in each sessionText files in a folder

Security teams usually turn on Script Block Logging first, because it shows exactly what ran, even when a script hides its code.

The logs end up in the event log, which you can read with PowerShell event log commands.

Check the current logging policy

The settings live under the Policies key in the registry. Windows PowerShell and PowerShell 7 each have their own, so check both. Reading them doesn’t need admin rights:

$roots = @{
    'Windows PowerShell' = 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell'
    'PowerShell 7'       = 'HKLM:\SOFTWARE\Policies\Microsoft\PowerShellCore'
}
foreach ($setting in 'ScriptBlockLogging', 'ModuleLogging', 'Transcription') {
    [pscustomobject]@{
        Setting           = $setting
        WindowsPowerShell = if (Test-Path "$($roots['Windows PowerShell'])\$setting") { 'Configured' } else { 'Not set' }
        PowerShell7       = if (Test-Path "$($roots['PowerShell 7'])\$setting") { 'Configured' } else { 'Not set' }
    }
}

Output:

Setting            WindowsPowerShell PowerShell7
-------            ----------------- -----------
ScriptBlockLogging Not set           Not set
ModuleLogging      Not set           Not set
Transcription      Not set           Not set
PowerShell check logging policy in the registry
Nothing is configured on my PC yet (PowerShell 7)

Configured means the key exists. Open it with Get-ItemProperty to see whether the Enable value is 1. Group Policy writes these same keys, so this check works on domain PCs too.

You can read more about checking registry values in PowerShell Get-ItemProperty: registry and file examples.

Check the event logs

Windows PowerShell writes to Microsoft-Windows-PowerShell/Operational. PowerShell 7 writes to PowerShellCore/Operational:

Get-WinEvent -ListLog 'Microsoft-Windows-PowerShell/Operational', 'PowerShellCore/Operational' |
    Select-Object -Property LogName, IsEnabled

Output:

LogName                                  IsEnabled
-------                                  ---------
Microsoft-Windows-PowerShell/Operational      True
PowerShellCore/Operational                    True
PowerShell Operational event logs
Both Operational logs exist and are enabled (Windows PowerShell 5.1)

If PowerShellCore/Operational is missing, register the event provider from an elevated window with & $PSHOME\RegisterManifest.ps1.

For more ways to filter these events, see reading Windows event logs.

Enable Script Block Logging for PowerShell 7

Run this as administrator. New PowerShell 7 sessions start logging right away:

$key = 'HKLM:\SOFTWARE\Policies\Microsoft\PowerShellCore\ScriptBlockLogging'
New-Item -Path $key -Force | Out-Null
Set-ItemProperty -Path $key -Name EnableScriptBlockLogging -Value 1

To follow the Windows PowerShell setting instead, set UseWindowsPowerShellPolicySetting to 1 in the same key. On a domain, use Group Policy: Administrative Templates > Windows Components > Windows PowerShell, or the PowerShell Core templates you install with & $PSHOME\InstallPSCorePolicyDefinitions.ps1.

The setting lives in the registry, so creating the registry key if it does not exist avoids errors on a fresh PC.

Enable Module Logging

Module Logging needs two values: the switch itself and a list of module names. An asterisk logs every module:

<