Site icon Think PowerShell

PowerShell Execution Policy Explained

 

Before you can run a PowerShell script, you will need to check the PowerShell Execution Policy setting and possibly change it. Here’s how.

Running PowerShell Scripts

OK, so you’ve written your first script, and it looks something like this:

# Awesome-Script.ps1
Write-Host "My script executed!"

Now you try to run it for the first time. Whether you execute it in Windows PowerShell ISE or attempt to run it from a PowerShell command prompt, you get the same error:

PS C:\Users\aaron> C:\TEMP\Awesome-Script.ps1
File C:\TEMP\Awesome-Script.ps1 cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Policies at http://go.microsoft.com/fwlink/?LinkID=135170.
+ CategoryInfo : SecurityError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : UnauthorizedAccess

The script doesn’t run because the PowerShell Execution Policy is set to the default of Restricted.

What’s a PowerShell Execution Policy?

Does anyone remember the Anna Kournikova virus of 2001? It was a Visual Basic Script file (.vbs) that was sent around as an Outlook attachment. If you opened the script, it sent the same malicious attachment to all of your Outlook contacts (I long for the day that is all malicious files did!). Beyond security practices that have changed for allowing executable email attachments (hint: you shouldn’t be allowing them), that virus demonstrated the risk of having a malicious script file downloaded from the Internet and executed on your computer. This is where the PowerShell Execution Policy comes into play.

Per about_Execution_Policies,

Windows PowerShell execution policies let you determine the conditions under which Windows PowerShell loads configuration files and runs scripts. The execution policy is not a security system that restricts user actions. For example, users can easily circumvent a policy by typing the script contents at the command line when they cannot run a script. Instead, the execution policy helps users to set basic rules and prevents them from violating them unintentionally.

Restricted by default

Unintentionally is the keyword there. Most users who use Windows would never have a need to run a PowerShell script, so why have it enabled by default to be leveraged by an attacker? Microsoft made a security conscious decision to disable executing scripts out of the box. Execution Policy has five potential values (and a phantom sixth):

Policy recommendation? It depends

If you plan on using PowerShell scripts at all, Restricted obviously is out of the running. I personally think RemoteSigned is a good compromise between functionality and security in a Windows AD domain environment. It allows you to write scripts internally and use them on domain systems without any friction, while still preventing unintentional execution of an outside script. AllSigned is a better option, but you need the PKI/certificate infrastructure in place as well as good policies and processes for signing and managing script code, which a lot of organizations are lacking.

Ultimately, only YOU can determine what the best default Execution Policy is for your environment (and prevent forest fires).

Determine your current Execution Policy

OK, now that all of the academic stuff is out of the way, how do you find out what your current Execution Policy is, and how do you change it?

To see your current Execution Policy, run Get-ExecutionPolicy:

PS C:\Users\aaron> Get-ExecutionPolicy
Restricted

Pretty straight forward, but I am on a non-domain computer. If you are trying to figure out your Execution Policy in a domain environment where Group Policy can be in play, run the following:

PS C:\Users\aaron> Get-ExecutionPolicy -List

Scope ExecutionPolicy
----- ---------------
MachinePolicy Undefined
UserPolicy Undefined
Process Undefined
CurrentUser Undefined
LocalMachine Undefined

Not very interesting on a non-domain computer, but you can see now why when I run Get-ExecutionPolicy it returns Restricted, because all of the scopes are set to Undefined and the default for Windows 10 is Restricted.

A domain computer’s list could look very different. LocalMachine‘s value is set in the Local Group Policy Editor. MachinePolicy and UserPolicy would come from AD Domain Group Policy objects. The Process value is retained only for the live of the powershell.exe process containing it. The applied policy isn’t determined by the most restrictive, it is determined by scope precedence, which follows the output display order (MachinePolicy gets top precedence, then UserPolicy, etc.)

When there different values set for different scopes, Get-ExecutionPolicy will tell you which value is in effect for the PowerShell session you are in. Your UserPolicy may be set to RemoteSigned, but if the MachinePolicy is set to Restricted you will not be able to run scripts.

Setting Execution Policy using PowerShell

You can set a local computer’s Execution Policy with Set-ExecutionPolicy (Run As Administrator):

PS C:\WINDOWS\system32> Set-ExecutionPolicy RemoteSigned

Execution Policy Change
The execution policy helps protect you from scripts that you do not trust. Changing the execution policy might expose
you to the security risks described in the about_Execution_Policies help topic at
http://go.microsoft.com/fwlink/?LinkID=135170. Do you want to change the execution policy?
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "N"): a

Now when I run Get-ExecutionPolicy again:

PS C:\Users\aaron> Get-ExecutionPolicy -List

Scope ExecutionPolicy
----- ---------------
MachinePolicy Undefined
UserPolicy Undefined
Process Undefined
CurrentUser Undefined
LocalMachine RemoteSigned

I can specify the scope as well if I only want to set a policy for my user (Run As Logged In User):

PS C:\Users\aaron> Set-ExecutionPolicy RemoteSigned -Scope CurrentUser

Execution Policy Change
The execution policy helps protect you from scripts that you do not trust. Changing the execution policy might expose
you to the security risks described in the about_Execution_Policies help topic at
http://go.microsoft.com/fwlink/?LinkID=135170. Do you want to change the execution policy?
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "N"): a

I run Get-ExecutionPolicy and you will see CurrentUser is now set to RemoteSigned:

PS C:\Users\aaron> Get-ExecutionPolicy -List

Scope ExecutionPolicy
----- ---------------
MachinePolicy Undefined
UserPolicy Undefined
Process Undefined
CurrentUser RemoteSigned
LocalMachine RemoteSigned

Setting Execution Policy with Group Policy

In a Windows domain setting, you likely don’t want to configure Execution Policy one machine at a time. You also don’t want someone with local Administrator rights on a computer to be able to change this setting. Luckily, there is a simple Group Policy setting that can be configured either at the Computer Configuration or User Configuration level.

  1. Make sure you have PowerShellExecutionPolicy.admx file loaded. This is installed out of the box with Windows Server 2008 R2 or later.
  2. For computers, in your GPO go to Computer Configuration\Administrative Templates\Windows Components\Windows PowerShell. (Remember, MachinePolicy has overall precedence).
  3. For users, in your GPO go to User Configuration\Administrative Templates\Windows Components\Windows PowerShell.
  4. The setting is called Turn on Script Execution. Potential settings and impact:
    • Not Configured (default). No effect, PowerShell Execution Policy is set and enforced on the local computer.
    • Disabled. Scripts won’t run. (Restricted)
    • Enabled. You can choose between three execution policies:
      • Allow all scripts. (Unrestricted)
      • Allow local scripts and remote signed scripts. (RemoteSigned)
      • Allow only signed scripts. (AllSigned)
  5. Apply the updated GPO to computers or users for the settings to be enforced and run gpupdate for those computers/users.

Next Steps

  1. Identify your computer’s active Execution Policy as well as any policies configured for different scopes.
  2. If you are on a computer you administer and want to be able to execute scripts, run Set-ExecutionPolicy RemoteSigned (or whatever Policy you prefer).
  3. Run your script!
    PS C:\temp> .\Awesome-Script.ps1
    My script executed!

     

Reference

Exit mobile version