Blog Post

Determining An Enterprise Execution Policy Setting

,

Windows PowerShell has the concept of execution policy that determines in which cases script and configuration files are able to run. The various execution policy settings are described in about_Execution_Policies. Run Get-Help about_execution_policies or see the online version for additional information.

The default setting for the execution policy is restricted which means PowerShell will not run scripts or load your profile. Of course, as a IT Pro the default setting is too restrictive for either your workstation or the servers you manage. When adopting PowerShell in an enterprise environment you’ll need to determine the most appropriate execution policy setting. In order to run scripts this means you’ll need to choose between AllSigned or RemoteSigned setting. Note: Restricted, UnRestricted and ByPass settings are not appropriate for obvious reasons.

After research, testing and careful consideration I propose RemoteSigned enforced via Group Policy to be the most appropriate setting for an enterprise environment for the following reasons:

  1. Microsoft’s products do not support an AllSigned Policy
  2. The Execution Policy is Not an Effective Security Feature
  3. Using AllSigned is unnecessary in a well-managed environment
  4. No one uses AllSigned
  5. You are not a Software Vendor

Microsoft’s Products Do Not Support an AllSigned Policy

In the course of research and testing I’ve identified at least three products Exchange, IIS and PowerShell ISE where AllSigned isn’t supported. There are probably additional products and if you know of others please comment. The details of each products lack of AllSigned support is described below…

Exchange

All the files used by the Exchange Management Tools and are signed.  You would think EMS would run using an AllSigned policy, however, if you try launching the EMS with the execution policy set to ALLSIGNED you’ll see a series of prompts like this:

Do you want to run software from this untrusted publisher?

File C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1 is published by CN=Microsoft Corporation,

OU=MOPR, O=Microsoft Corporation, L=Redmond, S=Washington, C=US and is not trusted on your system. Only run scripts  from trusted publishers.

[V] Never run  [D] Do not run  [R] Run once  [A] Always run  [?] Help (default is "D"):

This works up to the point where the remote module will be imported to the local session.  There are two format.ps1xml files created and used.  Since they are dynamically created   there are no signatures.  Hence the reason REMOTESIGNED works and ALLSIGNED does not.

The REMOTESIGNED requirement for Exchange is documented in two places:

Install Windows Management Framework

Troubleshooting the Exchange Management Shell

This applies to all machines where the Exchange Management tools are installed.

Note: This is really not an Exchange implementation issue so much as a PowerShell remoting issue which means that this issue will come up again with other products.

IIS

PowerShell was included in the Microsoft Common Engineering Criteria each product team is responsible for building their own PowerShell component invariably some inconsistencies creep in. One of those inconsistencies has been around script signing. It would seem some product teams are failing to sign their components. As an example IIS 7.5 is unsigned. The IIS 7.5 module will not run using an AllSigned policy.

PowerShell ISE

Did you know PowerShell ISE breaks script signing by default? The following connect item documents the issue:

 https://connect.microsoft.com/PowerShell/feedback/details/483431/set-authenticodesignature-fails-on-scripts-created-from-ise.

The reason PowerShell ISE by default lacks support for script signing is due to the default encoding being Unicode Big Endian. As documented in the connect item, there is a workaround to change PowerShell ISE encoding, however this should be cause of concern since the issue shows how script signing isn’t being tested internally.

The Execution Policy is Not an Effective Security Feature

That’s right, using AllSigned does not prevent scripts from being run. As demonstrated by Tome Tanasovski (blog|twitter) in his blog post Attacking Execution Policy. The following PowerShell code will read in a PowerShell script called test.ps1 and execute even if the execution policy is set to AllSigned or Restricted:

1
PowerShell -noprofile -Command "PowerShell -noprofile -encodedCommand ([Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes((Get-Content .\test.ps1 |%{$_}|out-string))))"

As Tome notes “Microsoft doesn’t consider this an exploit because execution policy was never intended to be a security feature.  In a way this makes sense.  It’s real intention is to prevent a user from accidentally double-clicking on an untrusted PowerShell script.”

A second method for circumventing an AllSigned policy is to use the –ExecutionPolicy parameter for powershell.exe. Provided your execution policy isn’t being enforced through Group Policy:

powershell.exe –executionpolicy -RemoteSigned

The above command will launch a powershell host with the execution policy set to remotesigned. This will override previous set powershell execution policy unless the execution policy is being enforced via Group Policy.

Note: Just because execution policy can be circumvented does not make PowerShell less secure than any other scripting or programming language. The concept of execution policy doesn’t even exist in other scripting languages. Keep in mind you can only perform tasks you have permissions to in PowerShell. If you’re using Vista or higher operating system and have UAC enabled you this means PowerShell scripts won’t change settings without prompting for approval. What got scripting languages in trouble in the past has been scripts that automatically download and execute or scripts that are simply double-clicked and execute. These issues have been addressed many years ago even in VBScript. PowerShell does not automatically execute and by default a PowerShell script file (.ps1) is associated with Notepad, so double-clicking a file will not execute the script.

Using AllSigned is Unnecessary in a Well-Managed Environment

Using ALLSIGNED is not necessary in a properly managed environment. A well-managed environment has a change control process to move items into production. Part of this process involves testing in development and QA environments. In such an environment every script is checked and tested following a stringent process. Simply signing a script doesn’t improve the quality.  If someone says “Trust this certificate” and the signer was negligent or malicious, signing hasn’t accomplished anything.   In the end the signature tells you who has staked their reputation on the quality of the code and not that the code is quality. If you trust people who don’t work to keep a good recommendation you might as well not bother requiring signing.  If there are strict controls of what goes onto a machine then it is not necessary to sign.

No One Uses AllSigned

One final consideration is whether there are real world implementations of an AllSigned policy in an enterprise environment. I haven’t found a single organization doing so. If you work as an IT Pro in an enterprise environment and use an AllSigned, please comment. What’s also interesting is that there isn’t anyone inside Microsoft advocating “use allsigned”—which in itself tells you something.

You are Not a Software Vendor

If you are a software vendor selling a product which includes PowerShell components—sign them! Using signing in an environment where you’ll never distribute scripts to customers makes little sense. The benefits to self-signing are dubious and you will encounter issues with Microsoft products being managed with PowerShell.

Summary

You need to make a determination on whether the benefits of an AllSigned policy for PowerShell  is worth the effort to make it practical. An important consideration is Microsoft’s own products lack support for implementing an AllSigned policy.  Complicating research into Microsoft product is finding documentation whether each Microsoft product supports an AllSigned policy. You’ll often find documentation is missing or difficult to locate. As we’ve seen signing scripts does not prevent script execution. The lack of real world implementations or best practice guidance to use AllSigned should also be a cause for concern. In my case after carefully considering each issue I found RemoteSigned to be the best choice for execution policy. My suggestion is enforce PowerShell execution policy as  RemoteSigned with Group Policy and move on to using PowerShell to automate your environment.

Rate

You rated this post out of 5. Change rating

Share

Share

Rate

You rated this post out of 5. Change rating