PowerShell uses execution policy to determine which scripts to run. There are in fact five scopes where execution policy can be defined, and to see them all, use this command:
PS C:\> Get-ExecutionPolicy -List Scope ExecutionPolicy ----- --------------- MachinePolicy Undefined UserPolicy Undefined Process Undefined CurrentUser RemoteSigned LocalMachine Undefined
To determine the effective setting, PowerShell traverses these scopes from top to bottom, and the first setting that is not “Undefined” sets the effective setting. If all scopes are set to “Undefined”, PowerShell uses “Restricted” instead and prohibits script execution. This is the out-of-box default behavior.
Always make sure the “MachinePolicy” and “UserPolicy” scopes are set to “Undefined”. These scopes can only be set centrally by group policy, and if they are set to anything other than “Undefined”, a user can no longer change the effective setting.
Some companies are using this to restrict script execution, using execution policy like a security boundary – which it is not. Execution policy always is a personal preference setting, so group policy should set a default value at “LocalMachine” scope, but never force settings on a user.
If there are settings at “MachinePolicy” or “UserPolicy” scopes, there is also a bug in PowerShell 5 and lower that may cause delays of up to 30 seconds when you start a PowerShell script. This delay was caused internally: PowerShell uses WMI to determine the currently running processes to determine whether a PowerShell script was launched as part of a group policy or not, and the way this was implemented could cause excessive delays.
So if you see settings other than “Undefined” in “MachinePolicy” or “UserPolicy” scopes, you should talk to your Active Directory team and explain to them the purpose of execution policy: it is a preference setting, not a restrictive setting. Use other techniques such as “Software Restriction Policy” to safely limit the use of scripts.