Building on PowerShell: Execution Policies

  • Comments 3

One question we sometimes get asked is why Exchange changes PowerShell’s execution policy from “Restricted” to “RemoteSigned.” Doesn’t that lower PowerShell’s security?

The "Restricted" execution policy isn't intended to be something that PowerShell users live with forever. It's a safe default that protects non PowerShell users from being impacted by PowerShell-based malware.

For example, many home users had never used VBScript, but still got bitten by the flurry of WSH-based viruses that got mailed to them. PowerShell's Restricted execution policy solves this. To an attacker, a computer that has never used PowerShell is the same as a computer that doesn't have PowerShell installed at all. And since attackers look to affect the largest number of computers possible, PowerShell becomes a less attractive vehicle for their attack. That, in turn, makes PowerShell users safer too. Given all of PowerShell’s security barbs, an attacker is better off using executables or other popular scripting languages as an attack vehicle.

So in light of all this, the Exchange team updates the execution policy to RemoteSigned by our recommendation. If you are an application that uses PowerShell support, you probably fit into one of these situations:

You expect the vast majority of your users to run your scripts

If you are a vendor that ships PowerShell scripts as an integral part of your offering (not just cmdlets,) you should absolutely expect that your users will want to run them. It would be a poor user experience if they had to install your product, and then change their execution policy when they try to use it. There’s also the very real threat of them just trying to make the message go away and picking a needlessly lax execution policy (such as Unrestricted.)

In this situation, we recommend that:

  • You sign your scripts with a real Authenticode code signing certificate
  • During installation, you change the execution policy to AllSigned if it is currently Restricted. If it is anything but Restricted, leave it alone.
  • DO NOT modify the user's Certificate Store. They will (and should) be prompted the first time they run your scripts to ensure they trust your signing certificate.
  • If your installer supports silent installation, offer an option to not modify the execution policy.

To clarify the “leave it alone” point – a non-default execution policy has been put there for a reason. While you might want to increase security to change the execution policy to AllSigned, it is more likely that you will inadvertently break other installed products, or parts of their IT infrastructure that depends on unsigned scripts.

If you do not have a code signing certificate, we recommend getting one! If you cannot, then your installer should prompt the user to change the execution policy to RemoteSigned if it is currently Restricted. If it is anything but Restricted, leave it alone.

“<This product> includes scripts that help you <manage Active Directory, etc.> Your current PowerShell script execution policy will prevent these scripts from running. Would you like to update the execution policy to allow these scripts to run?” ([Yes – Default] / No / Cancel)

Your product itself depends on PowerShell scripts

In this case, PowerShell scripts are simply an implementation language, just like C#, C++, or assembly language. Since you are only running scripts that you wrote, use the PSExecutionPolicyPreference environment variable to change the execution policy for the scope of your application only. RemoteSigned (as opposed to AllSigned) is the best option in this situation so that your application doesn't need to prompt the user. If your application offers the ability to run random scripts (or launch a PowerShell console,) ensure that you clear your PSExecutionPolicyPreference variable before doing so.

Now what about Exchange?

From their design and user research, they know that a vast majority of their user base will write their own scripts, or run scripts from the community. When they do that, they will ultimately get our execution policy warning, and be forced to make a decision. The most secure decision they can make is the RemoteSigned execution policy, so the Exchange installer makes that decision on their behalf.

Lee Holmes [MSFT]
Windows PowerShell Development
Microsoft Corporation

Leave a Comment
  • Please add 1 and 3 and type the answer here:
  • Post
  • "Would you like to update the execution policy to allow these scripts to run?"

    To me this sentenece is absolutly misleading. Of course do I want these scripts to run. But it's most probably not everyones expectation that after clicking "yes" several - possibly thousands - of other scripts are then also alowed to run.

  • Hi Lee,

    first let me tell you that I really like idea of execution policies and I understand how import it is. What I don't like however is that fact how they are implemented.

    What drives me crazy is following message:

    "Security Warning

    Run only scripts that you trust. While scripts from the Internet can be useful, this script

    can potentially harm your computer."

    It is extremely hard to identify sometimes why the script doesn't want to run. Consider following example:

    PS C:\> 'write-host "Hello world!"' > c:\temp\test.ps1

    PS C:\> C:\temp\test.ps1

    Hello world!

    PS C:\> . \\\c$\temp\test.ps1

    Security Warning

    Run only scripts that you trust. While scripts from the Internet can be useful, this script can potentially harm your

    computer. Do you want to run \\\c$\temp\test.ps1?

    [D] Do not run  [R] Run once  [S] Suspend  [?] Help (default is "D"):

    At few different customers, I had to fiddle not just with Trusted sites, but also with some registry\GPO settings, environment variables (zone mask) etc etc...

    In case you use Powershell to write just few functions, it's fine. In case you try to implement it as enterprise standart with hundreds or thousands of scripts, it can become very painful :( Only quick solution in this case is to use Bypass execution policy, which is of course something no one wants to do


  • I may be missing something, but it does not appear to me that execution policies work very well with Windows Server 2008 R2 DFS domain shares. Perhaps you know. Why does PowerShell prevent me from running unsigned scripts and loading unsigned configuration files from \\domain\share after I

       set-executionpolicy remotesigned

       set-location c:\windows\\framework\v2.0.50727

       .\caspol.exe -pp off -m -ag 1 -url file://domain/share/* FullTrust -Exclusive on

    What's the caspol magic required to enable running unsigned scripts and loading unsigned configuration files from a DFS domain share?

Page 1 of 1 (3 items)

Building on PowerShell: Execution Policies