When you enable ScriptBlockLogging, PowerShell logs all PowerShell code that is executed on your machine. Even if it is disabled, any security-relevant code is still logged. That’s awesome. However, the log can be read by any user, so anyone could browse through the logged code like this:
Get-WinEvent -FilterHashtable @{ ProviderName="Microsoft-Windows-PowerShell"= 4104 }
To harden security and limit the access to the log file, you have two choices:
- You can set up encrypted logging by installing a digital certificate. This way, the logged data would be protected even from fellow Administrators. However, setting up and managing these certificates is not trivial.
- You can harden the access security to the PowerShell operational log, and use the same access that is used for the classic Security log. This way, only local Administrators can read the log. This is the approach we are taking in this tip today:
#requires -RunAsAdministrator # this is where the PowerShell operational log stores its settings $Path = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\winevt\Channels\Microsoft-Windows-PowerShell/Operational" # get the default SDDL security definition for the classic security log $sddlSecurity = ((wevtutil gl security) -like 'channelAccess*').Split(' ')[-1] # get the current SDDL security for the PowerShell log $sddlPowerShell = (Get-ItemProperty -Path $Path).ChannelAccess # store the current SDDL security (just in case you want to restore it later) $existsBackup = Test-Path -Path $Path if (!$existsBackup) { Set-ItemProperty -Path $Path -Name ChannelAccessBackup -Value $sddlPowerShell } # set the hardened security to the PowerShell operational log Set-ItemProperty -Path $Path -Name ChannelAccess -Value $sddlSecurity # restart the service to take effect Restart-Service -Name EventLog -Force
Once you run the script, reading the PowerShell operational log is limited to local Administrators.