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:
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
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:
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):
Press Y, then Enter.
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).
- 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
- Now open the Certificate Management Console: certmgr.msc > Personal > Certificates. Select and Copy your theitbroscert to the clipboard;
- Then paste this certificate into Trusted Root Certification Authority (or you can import this certificate to the computer’s Trusted Root CA);
- 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.
- 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.
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.
The PowerShell script will now run without displaying any notifications.