Understanding PowerShell’s Execution_Policy and Scope functionality
Windows started life as a text-based OS that had graphical elements bundled on top. Today most of the interaction with the OS is done through the graphical interface although the underlying text-based interface still exists and is important to reach certain nooks and crannies that are not exposed graphically.
The command prompt or cmd was the first and (still) default character-based scripting language to interact with the components making up the operating system. In 2006 an alternative called PowerShell (PS) became available for Windows. PS is an environment that manipulates configuration files and runs scripts. PS constructs make it easier to develop more complex solutions than with cmd.
The latest version of PS is 7. Version 7 is available for other platforms other than Windows. Joining cmd commands into a script was done in a text file with the extension bat or (later) cmd extensions while PS scripts are identified using the ps1 extension.
PowerShell under Windows has a safety feature called ExecutionPolicy (EP) that is similar to Microsoft Office PROTECTED VIEW functionality. With Microsoft Office, when one attempts to open a document from an internet location, the document is opened in read only-mode with all functionality that may contain viruses or cause havoc disabled. A person has to click the Enable Editing button to be able to manipulate the file or perform certain actions such as printing.
PS’s EP allows one to control the loading of configuration files and running of scripts. For the purposes of this article, the term files will be used to mean either configuration files or scripts. The EP cannot be classified a security mechanism because it does not block users from typing script contents one command at a time. If a person opens a blocked PS script in a text editor and copies and pastes the contents of the script one instruction at a time and presses enter after each EP restrictions will not apply.
EP helps users implement certain controls that are aimed at protecting them from being targeted by malicious perpetrators or from their own unintentional actions (for example in production systems).
Types of Execution Policies
In Windows, the following EP exists:
AllSigned
All files, including those you develop on the local computer must be signed by a trusted publisher. Scripts by publishers that you have not classified as trusted will require confirmation before they can be executed.
Bypass
Nothing is blocked.
This is equivalent to the restrictions that apply to cmd files.
RemoteSigned
Files that are download from the internet must be signed by a trusted publisher or must be unblocked. Locally written scripts don’t need to be signed.
This is the default execution policy for Windows server computers.
Restricted
No file can be run. The default execution policy for Windows client computers.
This is the most restrictive setting.
Unrestricted
Unsigned scripts can run, although a user will need to confirm before running scripts and configuration files that are not from the local intranet zone.
Bypass
This is typically unrestricted without warnings.
This is the least restrictive setting.
Undefined
There is no EP in the current Scope (see below for an explanation of Scope)
If the execution policy in all scopes is Undefined, the effective EP is Restricted for Windows clients and RemoteSigned for Windows Server.
This setting is used to clear a previously set EP
Execution Policy Scope
Scope allows one to assign different EP to different categories depending on which layer they fall in.
5 different scopes are defined: MachinePolicy, UserPolicy, Process, CurrentUser, and LocalMachine.
MachinePolicy has the highest precedence with LocalMachine being the lowest. If a particular Scope is undefined the list is traversed downwards until a setting is found or, if all scopes are undefined, Restricted or RemoteSigned is assumed depending on the version of Windows.
To get a dump of the execution policy settings for all scopes type the following:
PS> Get-ExecutionPolicy -List
Output:
Scope ExecutionPolicy
— — — — — — — — — — -MachinePolicy ………….. Undefined
UserPolicy ……………… Undefined
Process …………………. Undefined
CurrentUser ……………. Undefined
LocalMachine ………….. RemoteSigned
The cmdlet to set the EP is Set-ExecutionPolicy. If the Scope parameter is not specified it will apply to LocalMachine.
MachinePolicy and UserPolicy scopes can only be set through Group Policy and will not be covered here. Administrators use these scopes to manage PowerShell execution within the environments they manage.
The scope Process applies only to the current process; the session that it is applied to. As shown below the setting applied to PS Session 8116 did not get inherited by the session that was opened after.
Another point worth noting is that modifying the EP of Process sessions does not require elevated privileges.
CurrentUser and LocalMachine can only be adjusted in a PS session with elevated privileges. In Windows this is achieved by running PS as administrator. In the screenshot below, an attempt to adjust the EP of LocalMachine (Reminder: If Scope is not specified it defaults to LocalMachine) fails with the following error: ‘Set-ExecutionPolicy: Access to the path ‘C:\Program Files\PowerShell\7\powershell.config.json’ is denied.
To change the execution policy for the default (LocalMachine) scope, start PowerShell with the “Run as administrator” option. To change the execution policy for the current user, run “Set-ExecutionPolicy -Scope CurrentUser”.’
The same instruction in an Administrator session works.
EP applied to CurrentUser or LocalMachine scopes persist, although any sessions open before these scopes are adjusted will not automatically inherit the adjusted settings.
Applying these settings in real-world situations
There are situations in which you would like to be able to process a PS file. The safest solution short of signing your script would be to use the Process scope because any adjustments here are short-lived and will be “forgotten” the moment the process exists. Also, Process does not require elevated privileges (that may not always be available).
Let’s assume you have a PS script called Say-HelloWorld.ps1 (which you downloaded from the internet and trust). To execute this script open a PS session and type the following:
Set-ExecutionPolicy -Scope Process Bypass
.\Say-HelloWorld.ps1
There could be situations in which you are calling your PS files from an environment that is out of the PS terminal window. This could be a cmd batch file or Task Scheduler. You can get the same outcome as above by specifying the path to the PS interpreter as part of your command.
“C:\Program Files\PowerShell\7\pwsh.exe” -ExecutionPolicy Bypass .\Say-HelloWorld.ps1
In the above example “C:\Program Files\PowerShell\7\pwsh.exe” corresponds to the (default) folder where PS v7 has been installed.
The Unblock alternative
An alternative approach to what has been described here would be to use PS’s Unblock-File cmdlet or the equivalent in the File Properties GUI window. In a future article I will delve into these functions.