When it comes to PowerShell — or anything else to do with technology — Brien Posey, because he is a Microsoft MVP award-winner in a slew of categories, has firsthand experience on how to make an IT pro’s job easier. This entry in our 20 Best of 2020 series walks you through setting PowerShell execution policies at the Group Policy level. Do it, and boost your company’s security quickly and easily.
One of the best ways to protect your organization against malicious PowerShell scripts is to leverage the PowerShell execution policies as a tool for restricting the use of scripts. One of the best ways to accomplish this is to configure the execution policy at the Group Policy level. In this article, I will show you how it’s done.
Configuring Group Policy
Microsoft makes it relatively easy to control your PowerShell execution policy enforcement at the Group Policy level. To do so, simply open the Group Policy Editor and load your Group Policy of choice. Next, navigate through the console tree to Computer Configuration\Policies\Administrative Templates\Windows Components\Windows PowerShell. When you do, you should see a Group Policy setting called Turn On Script Execution. You can see what this looks like in the screenshot below. Incidentally, this setting can also be applied at the user level.
You can find the PowerShell-related Group Policy settings at Computer Configuration\Policies\Administrative Templates\Windows Components\Windows PowerShell.
Now, double click on the Turn On Script Execution policy setting, and you will be allowed to configure it. You can see what options exist for this policy setting in the screenshot below.
As you look at the screenshot above, you might notice that Microsoft uses slightly different terminology within the Group Policy setting then they do when you set the execution policy through PowerShell.
Setting the execution policy from within PowerShell involves using the Set-ExecutionPolicy cmdlet, followed by the name of the policy that you want to use. There are presently seven different execution policies recognized by PowerShell. These include:
- AllSigned: All PowerShell scripts must be digitally signed by a trusted publisher.
- Bypass: All scripts are allowed to run, and the user receives no warnings or prompts.
- Default: This setting sets the execution policy to Restricted for Windows client computers, and to RemoteSigned for Windows Server machines.
- RemoteSigned: If a script has been downloaded from the Internet, then it must be signed by a trusted publisher.
- Restricted: No PowerShell scripts are allowed to run.
- Undefined: No execution policy is defined for the given scope. If the execution policy is set to Undefined for all scopes, then the effective policy will be Restricted.
- Unrestricted: All scripts are allowed to run.
By default, the Turn On Script Execution Group Policy setting is not configured, which allows the execution policy to be managed on a per-machine basis. Conversely, if you disable this policy, then it does essentially the same thing as setting the PowerShell execution policy to Restricted.
Enabling the Turn On Script Execution policy allows you to choose between three different execution policy options. The Allow Only Signed Scripts option causes the AllSigned execution policy to be used. Choosing the Allow Local Scripts and Remote Signed Scripts setting sets the execution policy to RemoteSigned. Likewise, choosing the Allow All Scripts option sets the execution policy to Unrestricted.
PowerShell execution policies: What is the benefit?
It’s easy to assume that the primary (and possibly only) benefit to managing PowerShell execution policies at the Group Policy level is that doing so lets you centrally manage PowerShell security. While this is indeed a compelling benefit, there is another major advantage of applying PowerShell execution policies through Group Policy. Take a look at the screenshot below.
As you can see in the screenshot, I set the Turn On Script Execution policy to Disabled. From there, I opened an administrative PowerShell session and then used the GPUpdate /Force command to apply the newly configured Group Policy setting. I then verified that the execution policy had been set to Restricted and then used the Set-ExecutionPolicy command to set the execution policy to Unrestricted. At first, it looks as though PowerShell is going to allow the change. However, PowerShell then informs me that my change is overridden by a policy that is defined at a more specific scope (namely the Group Policy). So even though I am logged in as a domain admin and am using an administrative PowerShell session, PowerShell blocks my attempt to set a new execution policy.
In case you are wondering, PowerShell also blocks any attempt to perform a scope level policy override. In the screenshot below, I listed the execution policies that are in effect for each scope and then attempted to change the policy for a specific scope. Upon doing so, PowerShell produced an error. The same thing happens if I try to set the execution policy to Bypass.
Practice defense in depth
As you can see, setting the execution policy at the Group Policy level can greatly enhance your organization’s security, because even administrators are prohibited from making changes to, or bypassing the PowerShell execution policy. Even so, it is important to understand that execution policies are not the be-all, end-all of PowerShell security.
There are a variety of methods that can be used to circumvent PowerShell’s execution policy. Tools exist, for example, that can turn a PowerShell script into an executable file. PowerShell execution policies do not apply to .EXE files, so the code is allowed to run regardless of any execution policies that may exist.
A simpler method involves a user or administrator simply running a script’s commands one at a time (by pasting them into the command prompt) rather than running the actual script.
My point is that setting a restrictive execution policy is not a guarantee that PowerShell will remain secure. It is therefore important to practice defense in depth. Execution policies are an important security tool, but they need to be used in conjunction with other security mechanisms such as restrictive permissions and PowerShell logging.
Featured image: Freepik / Design vector created by gstudioimagen
More Best of 2020 articles
- Open-source security tools for cloud and container applications
- Deploying fully patched Windows 10 computers: A guide for IT pros
- Setting up static IP address for Linux: Easier than you think
- Microsoft 365 troubleshooting: Diagnostic tools at your fingertips
- Managing disk and file system partitions in an Azure Linux VM
More PowerShell Basics articles
- Using JSON with PowerShell: A guide for IT professionals
- Reading text files with PowerShell and Linux bash shell
- How malicious PowerShell scripts evade detection
- Building PowerShell hash tables
- Reading a Windows INI file into PowerShell