Introduction to PowerShell Execution Policies
In PowerShell, execution policies are a safety feature designed to control the conditions under which PowerShell scripts run on a system. These policies are not exactly a security mechanism but are intended to serve the following purpose:
- Prevent accidental execution of scripts
- Help manage the risk of running scripts from unknown or untrusted sources
Execution policies play an important role in enhancing script security. They act as a first line of defense by restricting the types of scripts that can run on a system. They also establish trust for script sources, such as policies like AllSigned and RemoteSigned ensure that scripts originate from trusted sources. This helps reduce human error, as in a situation where users might unknowingly execute scripts downloaded from email attachments or the web. In a wider context, organizations can use execution policies to enforce consistent security practices across machines and users.
However, you must also keep in mind that:
- Execution policies are not a security boundary. They can be overridden by users with administrative privileges or bypassed via specific PowerShell flags.
- Their primary purpose is to prevent accidental execution, not to stop malicious actors with deliberate intent.
PowerShell execution policies should be used as part of a broader security strategy, including signed scripts, secure repositories, and other protective measures.
Understanding PowerShell Execution Policies
Let’s start with how execution policies work in practice. When you run a script, PowerShell checks the execution policy.
- If the script meets the requirements, such as signed by a trusted publisher or locally sourced, it runs.
- If the script does not meet the policy’s requirements, PowerShell prevents its execution and displays an error message.
Key Benefits
Some key benefits of PowerShell execution policies are:
- Prevents Accidental Execution of Malicious Scripts – Execution policies reduce the risk of unintentionally running untrusted or harmful scripts, particularly those downloaded from the internet.
- Encourages Secure Scripting Practices – Policies like AllSigned and RemoteSigned encourage script authors and users to sign scripts with trusted certificates, ensuring authenticity and integrity.
- Differentiate Local vs. Remote Scripts – Policies such as RemoteSigned allow locally created scripts to run without restrictions while enforcing stricter controls on remote or downloaded scripts.
- Flexible Configuration – Execution policies can be applied at various scopes (Process, CurrentUser, LocalMachine, MachinePolicy, and UserPolicy), giving administrators control over how and where policies are enforced.
- Temporary Overrides for Flexibility – Temporary overrides (for example, using -ExecutionPolicy Bypass) allow scripts to run in controlled scenarios without permanently modifying the system’s security settings.
- Promotes Organizational Compliance – Execution policies can be enforced across an organization via Group Policy to ensure consistent security practices for script execution.
- Raises Awareness of Script Security – By requiring explicit action, such as signing scripts or bypassing policies, execution policies encourage users to think critically about script sources and trustworthiness.
Key Limitations
Some key limitations of PowerShell execution policies are:
- Execution policies are not a security boundary as they are not designed to prevent deliberate attacks. A knowledgeable user with administrative privileges can easily bypass them by:
- Using the -ExecutionPolicy Bypass flag
- Modifying the system registry
- Running scripts within another process or bypassing PowerShell entirely
- Execution policies do not analyze the contents of scripts. Even signed scripts can contain malicious code if the signing key is compromised.
- Execution policies have a limited protection scope as they only apply to PowerShell scripts and commands. They do not control other script types (for example, VBScript, Python) or executable files, leaving gaps in protection.
- Strict policies like AllSigned can cause delays if users lack access to a trusted signing infrastructure or are frequently working with unsigned scripts.
- Execution policies rely on users to adhere to them. Untrained users might bypass execution policies or disable them without fully understanding the implications.
- Multiple policy scopes, such as MachinePolicy, UserPolicy, and Process, can create confusion, especially in environments with mixed or overlapping configurations.
- Automated scripts or CI/CD pipelines may encounter issues due to restrictive policies, necessitating additional configuration or temporary policy overrides.
- Execution policies may create a false sense of security. Administrators and users might mistakenly assume that they are a robust security mechanism, whereas they are primarily a safeguard against accidental script execution.
The following table sums up the key benefits and limitations of PowerShell execution policies.
Aspect | Key Benefits | Key Limitations |
Script Execution Control | Prevents accidental execution of harmful scripts | Easily bypassed by users with administrative privileges |
Source Validation | Encourages script signing and trusted sources | Does not verify script contents for malicious behavior |
Organizational Use | Supports consistent enforcement through Group Policy | May hinder productivity in environments with unsigned scripts |
Flexibility | Allows scoped configurations and temporary overrides | Multiple scopes can be confusing for policy management |
Security Scope | Adds a layer of defense in a security strategy | Limited to PowerShell scripts, leaving other tools unprotected |
Scope of PowerShell Execution Policies
PowerShell execution policies can be applied at various scopes, which determine how and where the policy is enforced. Scopes allow administrators to control script execution behavior at different levels, such as for individual users, all users on a machine, or a single session. The various scopes are discussed below.
Scope | Description |
MachinePolicy | Set by a Group Policy for all users of the computer. This policy overrides LocalMachine and CurrentUser. To override this policy, remove the Group Policy setting. It is used for centralized management of script execution policies for all users on a machine. |
UserPolicy | Set by a Group Policy for the current user of the computer. This policy overrides LocalMachine and CurrentUser. It is used or centralized management for individual users within a domain environment. Like MachinePolicy, this policy cannot be overridden locally. |
Process | Applies to the current PowerShell session only. The policy is saved in the $env:PSExecutionPolicyPreference environment variable. When the PowerShell session is closed, the variable and value are deleted. Hence the policy is temporary and ends when the session is closed. It is useful for testing or temporarily overriding the system policy without permanent changes. |
CurrentUser | Applies only to the current logged-in user. This policy is stored in the CurrentUser configuration file. It is used to set a policy for individual users without affecting other users on the same computer. |
LocalMachine | Applies to all users on the computer. This policy is stored in the AllUsers configuration file. This is the default scope when no scope is specified. Use it for organization-wide policies on shared machines or when multiple users need the same policy. |
Execution policies for the current user and local computer are stored in the PowerShell configuration files. The execution policy for a specific session is stored only in memory and is lost when the session is closed.
Scope Precedence
When multiple execution policies are defined at different scopes, PowerShell uses the following precedence order to determine which policy is effective (from highest to lowest priority):
- Group Policy: MachinePolicy
- Group Policy: UserPolicy
- Execution Policy: Process
- Execution Policy: LocalMachine
- Execution Policy: CurrentUser
Remember the following:
- Group Policy settings (MachinePolicy and UserPolicy) override local configurations.
- If no scope is specified when setting an execution policy, LocalMachine is used by default.
- If a Group Policy is in place, attempts to change the policy with Set-ExecutionPolicy at lower scopes will fail.
Setting PowerShell Execution Policies
Setting a PowerShell execution policy determines how scripts are executed on a system.
Check the Current Execution Policy
Use the following cmdlet to check the current execution policy:
Get-ExecutionPolicy
Check Policies for All Scopes
Use the following cmdlet to check the policies for all scopes:
Get-ExecutionPolicy -List
Set an Execution Policy
Use the Set-ExecutionPolicy cmdlet to set an execution policy for PowerShell.
Command Syntax
Set-ExecutionPolicy <PolicyName> -Scope <Scope>
Example 1 – Set an execution policy
Use the following cmdlet to set the policy to Unrestricted.
Set-ExecutionPolicy Unrestricted
Press Y to proceed or L to abort the action.
Example 2 – Specify the Execution Policy Scope
You can set the policy at different levels (scopes). Use the following cmdlet to set the policy to RemoteSigned for the local machine:
Set-ExecutionPolicy RemoteSigned -Scope LocalMachine
Note the following:
- You must run PowerShell as an administrator to set execution policies for the LocalMachine scope.
- If a policy is enforced by Group Policy (MachinePolicy or UserPolicy), it will override other settings, and attempting to change the policy will result in an error.
Apply the Execution Policy from a Remote Computer to a Local Computer
To apply a PowerShell execution policy from a remote computer to a local computer, you can use a combination of PowerShell remoting and the Set-ExecutionPolicy cmdlet. It is as follows:
Invoke-Command -ComputerName TargetComputer -ScriptBlock {
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force
} -Credential (Get-Credential)
Here, -ComputerName specifies the target computer. -ScriptBlock contains the command to run (Set-ExecutionPolicy in this case). -Credential allows you to specify credentials if the current account doesn’t have permissions on the target computer.
Force the Policy Setting
To bypass prompts during execution policy changes, use the -Force parameter.
Set-ExecutionPolicy RemoteSigned -Force
Remove an Execution Policy
To remove a policy for a specific scope, set the policy to Undefined.
Set-ExecutionPolicy Undefined -Scope CurrentUser
If all scopes are set to Undefined, the default policy becomes Restricted.
Temporarily Bypass PowerShell Execution Policies
You can temporarily bypass execution policies when running a script in PowerShell without permanently changing the policy. However, bypassing execution policies can expose your system to security risks. Ensure the scripts you’re running are from trusted sources.
Also note that administrative privileges may be required for some commands.
Example 1: Bypass Execution Policy for a Single Script
This command bypasses the execution policy for that specific invocation of PowerShell.
powershell.exe -ExecutionPolicy Bypass -File "C:\Temp\Script.ps1"
Example 2: Bypass in the Current Session
You can temporarily change the execution policy for the duration of the current session.
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
Here, -Scope Process ensures the change is limited to the current PowerShell session. When you close the session, the execution policy will revert to its original setting.
Example 3: Run Scripts Without Changing Policy
Use the -Command parameter to directly execute the script inline.
powershell.exe -ExecutionPolicy Bypass -Command “& { . ‘C:\Temp\Script.ps1’ }”
Use Group Policy to Manage Execution Policy
The Turn on Script Execution Group Policy setting enables you to manage the execution policy of computers in your enterprise. The Group Policy setting overrides the execution policies set in PowerShell in all scopes.
- When Turn on Script Execution is disabled, scripts do not run. This is equivalent to the Restricted execution policy.
- You can enable Turn on Script Execution and select an execution policy.
- When Turn on Script Execution is not configured, it has no effect. The execution policy set in PowerShell is effective.
Manage Signed and Unsigned Scripts
A signed script is a PowerShell script that includes:
- The script content
- A digital signature from a trusted certificate authority (CA) or a self-signed certificate
This ensures that scripts are from a trusted source and that they have not been modified after they were signed. Signed scripts help enhance security in environments that require control over which scripts can be executed.
The following execution policies are related to signed scripts:
- AllSigned – Requires all scripts and configuration files to be signed by a trusted publisher.
- RemoteSigned – Requires that scripts downloaded from the internet be signed by a trusted publisher. Local scripts do not need to be signed.
Sign a Script
To sign a script, you need a code-signing certificate.
- You can get a certificate from a certificate authority (CA) or generate a self-signed certificate using the New-SelfSignedCertificate cmdlet.
- Use the Set-AuthenticodeSignature cmdlet to sign the script.
Here is how you can sign the script.
$cert = Get-Item Cert:\CurrentUser\My\CERT_THUMBPRINT
Set-AuthenticodeSignature -FilePath "C:\Temp\Script.ps1" -Certificate $cert
Replace CERT_THUMBPRINT with the actual thumbprint of your certificate.
View Script Signature Status
To verify whether a script is signed and the status of the signature, use:
Get-AuthenticodeSignature -FilePath "C:\Temp\Script.ps1"
Manage Untrusted or Unsigned Scripts
To manage permissions for scripts without bypassing policies entirely, consider the following:
- If a script is marked as ‘from the internet’, unblock it.
- When running signed scripts from a publisher for the first time, you may need to approve the publisher certificate. You can add it as trusted using the certificate management tools.
Example: Unblock a Script
Sometimes, a script may be blocked due to being downloaded from the internet. Use the Unblock-File cmdlet to unblock it without bypassing execution policies.
Unblock-File -Path "C:\Temp\Script.ps1"
Manage Script Permissions
Managing script permissions in PowerShell involves controlling which scripts can be executed and by whom. This includes configuring execution policies, leveraging file permissions, and using code-signing practices.
Control Script Execution Using PowerShell Execution Policies
Execution policies restrict the conditions under which scripts can run. Different policies apply different restrictions. For example, no scripts can be run under the Restricted policy.
Use Code Signing for Scripts
Signing scripts ensures only trusted scripts can execute in environments with strict policies.
Use NTFS File Permissions
Restrict access to script files by modifying file or folder permissions. Here is how you can grant or deny permissions.
- Right-click the script file or folder and choose Properties.
- Go to the Security tab and click Edit.
- Add or remove users or groups and assign the appropriate permissions (e.g., Read, Write, Execute).
- Deny permissions for unauthorized users to prevent execution or modification.
Control Permissions Using Group Policy
Group Policy can enforce script permissions and execution policies across multiple systems. To configure a group policy:
- Open the Group Policy Management Console (GPMC).
- Navigate to Computer Configuration > Administrative Templates > Windows Components > Windows PowerShell.
- Set the desired execution policy using the “Turn on Script Execution” policy.
Secure Scripts from Internet Sources
Scripts downloaded from the internet are marked as unsafe. Open the script in a text editor to review it for safety before running.
Best Practices for Setting Execution Policies
Setting PowerShell execution policies correctly is essential for balancing security and functionality. From a security perspective, you must understand that execution policies are not a robust security boundary but a tool to prevent accidental script execution. They should be used with other security measures like access controls, script signing, and endpoint protection. In enterprise environments, enforce consistent policies through Group Policy, and educate users about best practices to minimize risks.
Some best practices for configuring execution policies that balance security with functionality are given below.
Use the Least Permissive Policy
You should apply the Restricted or AllSigned execution policy whenever possible to enforce stricter controls. RemoteSigned is a practical choice for environments that require some flexibility but still need to protect against external threats.
Avoid Using Bypass Permanently
Use the Bypass execution policy only in specific automation or troubleshooting scenarios. Revert to a stricter policy once the task is complete.
Use Digital Signing
Sign scripts using a trusted certificate authority (CA) to ensure integrity and authenticity. You must also encourage script developers to sign their scripts, especially for use with the AllSigned policy.
Implement Monitoring and Logging
Enable logging for PowerShell activity (for example, script block logging, module logging, and transcription) to detect and respond to suspicious activity.
Use the following cmdlet to enable module logging:
Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ModuleLogging" -Name EnableModuleLogging -Value 1
Logs can be viewed in the Event Viewer under Applications and Services Logs > Microsoft > Windows > PowerShell.
You can also use tools like Microsoft Defender for Endpoint or SIEM solutions to monitor logs.
Test Policies in a Non-Production Environment
To avoid surprises, test execution policies in a controlled environment before deploying them organization-wide. This would also ensure that legitimate scripts and automation workflows are not disrupted.
Use Conditional Policy Changes
To manage workflows that require flexibility, modify policies temporarily using the -Scope Process parameter. The cmdlet is as:
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process
Consider the Environment when Applying the Policy
The recommended PowerShell execution policies vary depending on the environment.
- Development Environment – RemoteSigned remains the recommended policy. It allows flexibility for developers to run local scripts without signing them and ensures that scripts downloaded from the internet are signed and trusted. You should also enable script block logging to monitor script execution.
- Test/Staging Environment – Use the RemoteSigned or AllSigned policy. RemoteSigned is practical for testing a mix of local and external scripts with basic integrity checks while AllSigned enforces stricter control by requiring all scripts to be signed.
- Production Environment – Use the AllSigned or Restricted policy. AllSigned ensures that only scripts signed by a trusted publisher are executed. However, Restricted is the most secure option for environments that do not rely on PowerShell scripts. You should also enforce policies via Group Policy to ensure consistency across systems.
- Automation Environment – Bypass is the recommended policy (for specific tasks only). It allows automation tasks to run without interruption, especially when policies are managed by other mechanisms, like application whitelisting and DevOps pipelines. You must also secure the automation environment with appropriate access controls and regular audits.
- Highly Secure Environments – The Restricted policy should be your choice as it prevents any scripts from running.
Troubleshooting Execution Policy Errors
Following are common errors related to PowerShell execution policies and their solutions.
“Execution of scripts is disabled on this system”
You may receive an error message as:
File C:\Temp\Script.ps1 cannot be loaded because running scripts is disabled on this system.
Cause: The execution policy is set to Restricted or Undefined, which prevents any scripts from running.
Solution: Check the current policy and change it temporarily for the specific session. Alternatively, you can change the policy for the current user or machine:
To change the policy for the current session, use the following cmdlet:
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
To change the policy for the current user or machine, use the following cmdlet:
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
“Cannot be loaded because the script is not digitally signed”
You may receive an error message as:
File C:\Temp\Script.ps1 cannot be loaded. The file is not digitally signed.
Cause: The execution policy is set to AllSigned or RemoteSigned, which requires scripts to be signed.
Solution: Use RemoteSigned instead of AllSigned if you trust local scripts. Or you may temporarily bypass the policy.
“Access to the registry key is denied”
You may receive an error message as:
Set-ExecutionPolicy : Access to the registry key is denied.
Cause: You do not have sufficient permissions to modify the execution policy at the LocalMachine scope.
Solution: Run PowerShell as an administrator or set the policy for the current user using the following cmdlet:
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
Execution Policy Conflicts Between Scopes
Different scopes (MachinePolicy, UserPolicy, Process, CurrentUser, LocalMachine) have conflicting policies.?
Cause: A stricter policy at a higher scope (such as MachinePolicy) overrides a more permissive policy at a lower scope (such as LocalMachine).?
Solution: Check the policies for all scopes using the following cmdlet:
Get-ExecutionPolicy -List
Once you have this information, you can modify the policy at the appropriate scope or run scripts in a session with a more permissive policy.
“Cannot change the execution policy because it is controlled by a Group Policy Object (GPO)”
This issue arises when the execution policy is enforced by Group Policy, preventing local changes.
Solution: Consult with your system administrator to modify the Group Policy. For a quick solution, however, you can temporarily bypass the policy.
“Policy scope not recognized”
You may receive an error message as:
Set-ExecutionPolicy : The specified scope is not recognized.
Cause: A typo in the scope name.
Solution: Ensure the scope is correctly specified as one of these.
Unexpected Behavior in Different PowerShell Versions
Older PowerShell versions, such as 2.0 handle execution policies differently or lack certain features.
Solution: Upgrade to the latest version of PowerShell.
Scripts Marked as Blocked
You may receive an error message as:
File cannot be loaded. The file is not digitally signed or was downloaded from the internet and is blocked.
Cause: The script is marked as blocked because it was downloaded from the internet.
Solution: Unblock the scrip using the following cmdlet:
Unblock-File -Path C:\Temp\Script.ps1
Conclusion: Choosing the Right PowerShell Execution Policy
You must take these factors into consideration when choosing an effective execution policy.
- Identify the environment before choosing an execution policy as different environments require a different policy. For example, for production servers, AllSigned or RemoteSigned is best to enforce some level of script verification.
- You should also assess your security requirements and decide accordingly. For example, use AllSigned if you have a robust code-signing process in place and want to enforce strict control over script execution. Or use Restricted for systems that should not run scripts.
- Consider your automation needs. It would be simpler to use the Bypass policy in environments where scripts are run automatically by trusted processes.
- Lastly, evaluate the source of scripts. If scripts are sourced internally and trusted, RemoteSigned provides a balance between usability and security. And if scripts are a mix of internal and external, consider AllSigned for enhanced security.
FAQs
What is the $env:psexecutionpolicypreference variable?
The $env:PSExecutionPolicyPreference environment variable is used in PowerShell to temporarily override the execution policy for a single session without changing the system-wide or user-specific execution policies. When you close the session, the change is lost.
You can use $env:psexecutionpolicypreference in the following ways:
- Assign a value to $env:PSExecutionPolicyPreference to change the execution policy temporarily, as shown below:
$env:PSExecutionPolicyPreference = “Bypass”
After this, scripts will run without restrictions for the duration of the session.
- Check the current value of this variable, as shown below:
$env:PSExecutionPolicyPreference
- Remove the temporary policy and revert to the default behavior, as shown below:
Remove-Item Env:PSExecutionPolicyPreference