PowerShell Execution Policy & Profile Impact

  • Welcome to ITBible, we're your #1 resource for enterprise or homelab IT problems (or just a place to show off your stuff).

Andy

OG
ITB-OG
Security Engineer
Apr 6, 2023
28
7
68
Texas
After writing about prompt customizations, I realized that I likely need to address a common issue that pops up when users are first configuring their PowerShell (PS) environment. If you have not read that post yet, I would start there before continuing with this one. As we discussed in that thread, PS profiles are simple .PS1 files that can contain configuration instructions which are to be interpreted by the PS engine at the time of execution. Bonus tip: you may hear this called JIT (Just-In-Time). This means that PowerShell scripts are not compiled like most non-scripting-oriented languages. Lines of script are parsed one by one; each line's cmdlets and statements are evaluated in real time during execution.

So what does any of this have to do with PS profiles and customizations? Let's dive in!

PowerShell Execution Policy is a safety feature and security control that determines the conditions under which PowerShell loads configuration files and runs scripts. Execution policies are important because they are a critical front-line defense that allow admins to determine what conditions are required for a script to be considered safe to run. I will emphasize once more that PS profile files are just normal PS1 script files. Because of that, Execution Policy evaluates it indescriminately from other scripts and will aggressively dictate whether profiles load on launch.

Now we can see how this relates to profiles. The default policy will block unsigned scripts. No matter how much time is spent crafting the perfect PS profile, if the system's Execution Policy determines that the necessary conditions are not met, that profile is not loading. In my experience, unless devs are well-versed in PowerShell development and code signing, it is generally safe to assume that a given script file is not digitally signed with a trusted PKI cert. If anyone would like a deeper dive into PS code signing, just let me know and I can work on it.

PowerShell has the following execution policy configurations:
  • Restricted (default): Scripts are not allowed to run. PowerShell functions and cmdlets can still be used interactively.
  • AllSigned: Only scripts that have been digitally signed by a trusted authority are allowed to run. This includes scripts created locally.
  • RemoteSigned: Scripts created locally can run without a digital signature. However, downloaded scripts require a trusted digital signature.
  • Unrestricted: All scripts are allowed to run, regardless of their origin or whether they have been digitally signed. This setting is dangerous! It is a major security risk and should be avoided unless absolutely necessary for temporary testing.
To find out which configuration is currently set, launch a new instance of PowerShell as administrator. The Get-ExecutionPolicy cmdlet, when run without any arguments/flags/parameters, will return the value of the policy with the highest precedence. This can be very confusing when trying to troubleshoot issues in this scope. The best approach is to simply append the -List flag to the cmdlet which returns the values for all policies on that endpoint.

If the execution policy is preventing profiles and/or scripts from running, it can be changed to a less restrictive setting. However, it's important to take the time to carefully review the implications of each policy configuration. For example, if execution policy is set to "Restricted", changing it to "RemoteSigned" to allow locally created scripts and profiles to run without requiring a digital signature:

Launch PowerShell as administrator:

Set-ExecutionPolicy RemoteSigned -Scope CurrentUser

This command sets policy value for the current user only. To set it back for all users on the system, change the scope to "LocalMachine".

Hopefully this helps with tackling some of the early potential roadblocks, and with understanding one of the core security controls in PowerShell.