Steps to Resolve “Powershell Script is Not Digitally Signed” Error
Learning how to fix the “Powershell script is not digitally signed” error message is an important skill for any Windows system administrator, developer or power user. This detailed guide will provide step-by-step instructions to troubleshoot and resolve this common Powershell issue.
Key Takeways
- The “not digitally signed” error appears when trying to run unsigned Powershell scripts on Windows.
- It’s caused by Powershell’s default security policy blocking untrusted scripts.
- Solutions include adjusting execution policy, using self-signed certificates or signing scripts with trusted certificates.
- Execution policy can be set with Set-ExecutionPolicycmdlet or Group Policy settings.
- Self-signed certificates can be generated through New-SelfSignedCertificateto temporary sign scripts.
- Importing signed modules or signing scripts with code-signing certificates provide robust long term fixes.
Why “Powershell Script is Not Digitally Signed” Error Occurs
To understand how to properly fix this error, you first need to know what causes it.
By default, Powershell has a restricted execution policy on Windows that prevents running unsigned Powershell script files (.ps1, .psm1, .ps1xml, .pssc). This policy is designed as a safety mechanism to stop potential malware or unapproved scripts from executing.
When you attempt to run an unsigned script, Windows compares the script signature against trusted certificates in the system’s root certificate store. If no signature is found, the “not digitally signed” error appears and blocks execution.
Scripts loaded from the internet are blocked by default in Windows clients unless the execution policy is adjusted. Even scripts created locally on your system will trigger the error until properly signed.
Adjust Powershell Execution Policy
The quickest way to bypass the signature check is to adjust the Powershell execution policy on your local machine or Windows domain. This can allow running unsigned scripts so you don’t have to deal with code-signing.
Here are the key methods for changing execution policy:
Set-ExecutionPolicy Cmdlet
You can use the built-in Set-ExecutionPolicy cmdlet to adjust the policy restriction level.
For example, to set the policy to RemoteSigned for the current user scope:
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
Some common permission levels you can specify:
- Restricted – Default, blocks all scripts.
- RemoteSigned – Allows local unsigned scripts.
- AllSigned – Requires scripts to be signed.
- Unrestricted – Allows all scripts to run.
See Get-Help Set-ExecutionPolicy for all possible options.
Group Policy Setting
For domain-joined machines, the execution policy can be configured through Group Policy. This allows setting the default policy for many computers/users at once.
The policy can be found under:
Computer Configuration > Administrative Templates > Windows Components > Windows PowerShell
This will distribute the chosen execution policy to all domain members upon next Group Policy update.
Sign Powershell Scripts with Self-Signed Certificate
If you cannot change the system-wide execution policy due to security reasons, another option is signing scripts with a self-signed certificate.
A self-signed certificate acts as a temporary signature that designates your script as trusted so it can bypass the policy check.
Here is how to generate and apply a self-signed certificate for signing scripts:
1. Generate certificate using New-SelfSignedCertificate cmdlet:
$cert = New-SelfSignedCertificate -Type Custom -KeyUsage DigitalSignature -Subject "CN=PowerShell Local Cert"
2. Export certificate’s public key to .cer file:
Export-Certificate -Cert $cert -FilePath my_self_signed_cert.cer
3. Import the .cer file into your trusted root store:
Import-Certificate -FilePath my_self_signed_cert.cer -CertStoreLocation Cert:\LocalMachine\Root
4. Digitally sign your script with the certificate using Set-AuthenticodeSignature:
Set-AuthenticodeSignature my_script.ps1 -Certificate $cert
After signing, you can run the script without the “not digitally signed” error.
The downside is this certificate is not trusted outside your local machine. For wider use, a trusted code-signing certificate is better.
Import Signed Powershell Modules
Powershell modules (.psm1 files) that contain pre-made functions can be signed by publishers and used in your scripts.
Importing trusted signed modules allows running the module functions without needing to adjust execution policy or sign your own scripts.
For example, modules from the PowerShell Gallery repository like PSReadLine and AzureAD are signed by trusted publishers.
To use them, first install the modules:
Install-Module PSReadLine, AzureAD
Then import the modules in your script:
Import-Module PSReadLine
Import-Module AzureAD
This provides an easy way to access useful signed code logic without signing your full scripts.
Digitally Sign Scripts with Code Signing Certificate
For company-wide usage or public distribution, your Powershell scripts should be digitally signed with a trusted code signing certificate rather than self-signed.
Digitally signing a script attaches an encrypted signature that designates the publisher and ensures the code is legitimate. This allows scripts to pass execution policy checks on any Windows machine.
Here is how to get and use a code signing certificate for Powershell scripts:
Get Code Signing Certificate
You can purchase a code signing certificate from a trusted Certificate Authority (CA) like Digicert or Comodo. The certificate file allows applying your digital signature to scripts.
For companies, a good option is purchasing an Organizational CA that can issue multiple code signing certificates for your teams.
For individual usage, personal code signing certificates can be purchased from CAs like Digicert, Comodo, Symantec, or GoDaddy.
Import Certificate to Certificate Store
Once you obtain a .PFX code signing certificate file, import it into your certificate store.
On Windows, use the Certificates MMC snap-in to import it to your personal certificate store:
Certificates (Local Computer) > Personal > Certificates
Or import through Powershell:
Import-PfxCertificate -FilePath my_code_cert.pfx -CertStoreLocation Cert:\CurrentUser\My
Enter the certificate password when prompted.
Digitally Sign Your Script
With your code signing certificate imported, you can now apply the digital signature to your Powershell scripts.
Use the Set-AuthenticodeSignature cmdlet to sign a script:
Set-AuthenticodeSignature my_script.ps1 -Certificate (Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert)
This embeds the signature within the script so it can pass the execution policy check on other machines.
You can verify the applied digital signature using:
Get-AuthenticodeSignature my_script.ps1
Troubleshooting Tips
When trying to resolve the “not digitally signed” error, there are a few key troubleshooting tips that can help identify and fix the problem:
Verify Execution Policy Setting
First, check what execution policy is currently set on the local machine or through group policy.
Use Get-ExecutionPolicy to view the current effective policy for each scope.
This can confirm if the policy is actively blocking unsigned scripts. If set to Restricted, that is the cause of the error.
Check Script Signature
Next, examine your script’s digital signature details with:
Get-AuthenticodeSignature myscript.ps1
This will reveal if the script has a signature from a trusted provider.
If it shows “Unknown” instead of a certificate, that means the script is unsigned and will trigger the error like “Unknown Publisher Security Warning“.
Review Trusted Publishers
You can also review the trusted publishers that are authorized to run signed code on your system.
Check the certificate store for trusted root and intermediate CA certificates:
Get-ChildItem -Path Cert:\LocalMachine\Root
Get-ChildItem -Path Cert:\LocalMachine\CA
And confirm any third-party modules were published by one of the trusted certificates.
If you see unfamiliar or unexpected publishers, that’s a sign something is misconfigured.
Check Certificate Expiration
Another possibility is an expired signing certificate. The signature validation will fail if the certificate used has passed its validity period.
Check any applied certificate signatures on scripts and confirm they are still within the valid “Not Before” and “Not After” dates.
If expired, re-sign the scripts using a valid certificate.
Test Policy Adjustments
As you adjust execution policy or sign scripts with various methods, test running the scripts between each change.
This can isolate what specific adjustments are needed to resolve the problem for your environment and scripts.
Conclusion on Powershell Script is Not Digitally Signed
The “Powershell script is not digitally signed” error ultimately comes down to the script execution policy that is restricting unsigned code from running.
While the policy provides security benefits, it can also block legitimate automation scripts. Thankfully there are various solutions covered in this guide like adjusting to a less restrictive policy, using self-signed certificates for temporary signing, importing trusted signed modules, and signing scripts with an official code certificate.
By properly signing your scripts or adjusting policy when safe, you can bypass the signature checks and confidently run Powershell automation. Just be sure to only lower restrictions after careful consideration and testing.
With the troubleshooting tips and options outlined, you should now have the knowledge to remediate this common Powershell scripting error. So you can safely unlock the full potential of Powershell automation.
Frequently Asked Questions
Here are some common questions that arise when dealing with this error:
Why are internet-based scripts blocked?
Internet scripts are blocked by default for security reasons as they come from unknown publishers. The script content could be malicious or inject viruses or malware. For internet scripts, the execution policy should only be overridden after thoroughly validating the source and contents.
What are the risks of loosening the execution policy?
An overly permissive execution policy like Unrestricted or Bypass can open your system to potential risks. Unsigned or unapproved scripts could contain trojans, delete data or leak sensitive information. Only lower restrictions after assessing the safety impacts.
How can I trust third-party modules?
When using Powershell modules from third-parties like the PowerShell Gallery, check
that the module is published by a recognized provider and digitally signed. Validate the publisher’s certificate is issued by a trusted certificate authority to confirm authenticity.
Does signing prevent viewing or editing scripts?
No, applying a digital signature does not encrypt or lock a Powershell script. You can still freely view the source code or modify the contents as needed. The signature only provides a means of verifying the publisher identity.
What if I lose my signing certificate?
Ideally, the certificate’s private keys should be safely backed up in case it is ever lost or deleted. If you lose your signing certificate completely, any scripts signed with it will start triggering the “not digitally signed” error again until re-signed with a new valid certificate.