How to Sign a PowerShell Script on Windows 10/Windows Server 2016?

PowerShell Execution Policy is enabled by default in Windows 10 and Windows Server 2016, which prevents PowerShell scripts (files with the *.PS1 extension) from running. In this article, we will show you how to sign a PowerShell script using a Code Signing certificate.

Create a simple PowerShell script with the following code:

Write-Host "Hello World! It works"

Save it as TestScript.ps1 file and try running from the elevated PowerShell console:

C:\ps\TestScript.ps1

The script won’t run with an error:

File C:\ps\TestScript.ps1 cannot be loaded. The file C:\ps\TestScript.ps1 is not digitally signed. You cannot run this script on the current system. For more information about running scripts and setting execution policy, see about_Execution_Policies

+ CategoryInfo : SecurityError: (:) [], PSSecurityException

+ FullyQualifiedErrorId : UnauthorizedAccess

sign a powershell script

As you can see, the execution of the PowerShell script is blocking by the execution policy. The current security level of the execution policy can be obtained using the command:

Get-ExecutionPolicy

ps1 is not digitally signed

On Windows 10, the default policy value is Restricted. This option prevents any PowerShell scripts from running. You can only execute interactive PowerShell commands.

To allow signed PowerShell scripts to run, you need to change the policy value to AllSigned or RemoteSigned.

Run the command (requires administrator privileges):

Set-ExecutionPolicy AllSigned

Press Y, then Enter.

powershell not digitally signed

However, the Restricted policy allows you to run digitally signed PowerShell scripts.

Let’s try to sign your PowerShell script using a certificate. In this example, we will create a self-signed certificate (however, you can use a certificate obtained from your CA).

  1. Open an elevated PowerShell console and use the New-SelfSignedCertificate cmdlet to create a certificate of type Codesigning:
    New-SelfSignedCertificate -DnsName theitbroscert -CertStoreLocation Cert:\CurrentUser\My\ -Type Codesigning
  2. Now open the Certificate Management Console: certmgr.msc > Personal > Certificates. Select and Copy your theitbroscert to the clipboard;
    powershell script not digitally signed
  3. Then paste this certificate into Trusted Root Certification Authority (or you can import this certificate to the computer’s Trusted Root CA);
    powershell script is not digitally signed
  4. Now you can sign the PowerShell script using this certificate:
    Set-AuthenticodeSignature -FilePath C:\ps\TestScript.ps1 -Certificate (Get-ChildItem -Path Cert:\CurrentUser\My\ -CodeSigningCert)

    If the given certificate is trusted, the Status line should indicate Valid.
    powershell digitally signed

  5. If you open your PS1 file with any text editor, you will see a block at the end of the script. It starts with the label “# SIG # Begin signature block” and contains the public key. Now, whenever you change the code of your PS script, you will need to re-sign it with your digital cert.
    digitally sign powershell script

Now, if you run your PowerShell script, a notification will appear:

Do you want to run software from this untrusted publisher?

File C:\ps\TestScript.ps1 is published by CN=theitbroscert and is not trusted on your system. Only run scripts from trusted publishers.

Press Y > Enter to run the script. This message will only appear the first time you run the PowerShell script. To prevent this notification from appearing, you need to import your certificate into the Trusted Publishers cert store.

powershell remote signed

The PowerShell script will now run without displaying any notifications.

powershell signing

I enjoy technology and developing websites. Since 2012 I'm running a few of my own websites, and share useful content on gadgets, PC administration and website promotion.
Cyril Kardashevsky

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.