Tools · Windows security and Event Logs · 17 / 27
PowerShell execution policy explained: why it is not a security boundary
Understand Restricted, RemoteSigned, AllSigned, and Bypass, how scopes combine, and which controls actually stop untrusted scripts.
What execution policy does
Execution policy decides whether PowerShell will run script files and whether they must be signed. Restricted runs no scripts. RemoteSigned requires a signature on scripts downloaded from the internet, identified by the Mark of the Web. AllSigned requires every script to be signed. Bypass and Unrestricted run everything, with Unrestricted warning on downloaded files.
Scopes stack: MachinePolicy and UserPolicy from Group Policy win over Process, CurrentUser, and LocalMachine. Get-ExecutionPolicy -List shows them all.
Get-ExecutionPolicy -List Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
Why it is not a boundary
Microsoft documents execution policy as a safety feature to prevent accidental script runs, not a security control. Any user can start powershell -ExecutionPolicy Bypass, pipe a script’s text into PowerShell, or paste commands interactively. None of those are blocked by execution policy.
Attackers routinely add -ep bypass to their commands. Seeing that in a 4688 command line is a useful hunting clue but not proof of malice, because administrators use it too.
Lab: see the limits
Set the CurrentUser policy to AllSigned. Try running an unsigned local script and see it fail. Then run it with powershell -ExecutionPolicy Bypass -File, and again by reading it with Get-Content and piping to Invoke-Expression. Both succeed.
Check the Mark of the Web on a downloaded script with Get-Item -Stream Zone.Identifier, and remove it with Unblock-File, to understand what RemoteSigned actually checks.
Set-Content .\hello.ps1 'Write-Output "hello from script"' Set-ExecutionPolicy AllSigned -Scope CurrentUser -Force .\hello.ps1 # blocked powershell -ExecutionPolicy Bypass -File .\hello.ps1 # runs Get-Content .\hello.ps1 | Invoke-Expression # runs Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Force
Controls that do enforce
Application control with App Control for Business (WDAC) or AppLocker can enforce Constrained Language Mode for PowerShell, which blocks most of the APIs attackers use. AMSI lets Defender scan script content at runtime. Script block logging records what ran. Those are the layers that matter.
Keep execution policy at RemoteSigned or AllSigned as a guardrail for users, and invest in the enforcing controls.
Diagram
Execution policy versus application control
Which one an attacker can switch off.
Purpose. Prevent accidental script runs.
Bypass. -ExecutionPolicy Bypass, piping, pasting.
Role. Guardrail only.
Purpose. Enforce which code may run.
Bypass. Requires a policy flaw or admin rights.
Role. Real control.
Check yourself
1. What does RemoteSigned require?
2. Why is execution policy not a security boundary?
3. Which control actually restricts what PowerShell code can do?