Fix PowerShell Script Errors with a Self-Signed PowerShell Certificate (Step-by-Step Guide)

If you’re running PowerShell scripts like npm.ps1 and encounter this error:

A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider.

You’re not alone. This happens often when PowerShell’s execution policy is set to AllSigned. In this guide, you’ll learn how to create a self-signed PowerShell certificate to sign your scripts locally, trust them, and fix these execution policy issues — all without internet access or third-party tools.


🔍 What Causes the “Untrusted Certificate” PowerShell Error?

PowerShell execution policies such as AllSigned and RemoteSigned protect your system by allowing only trusted scripts to run.
If a script is digitally signed but the certificate isn’t trusted, PowerShell blocks it — even when it’s from a trusted source like Node.js.

A common example is:

C:\Program Files\nodejs\npm.ps1

To check your policy:

Get-ExecutionPolicy -List

If you see AllSigned, all scripts must have a trusted digital signature.


🔐 Step 1: Create a Self-Signed PowerShell Certificate

Create a local code-signing certificate using PowerShell:

New-SelfSignedCertificate `
  -CertStoreLocation Cert:\CurrentUser\My `
  -Subject "CN=Local Code Signing" `
  -KeyUsage DigitalSignature `
  -Type CodeSigningCert

This creates a new self-signed PowerShell certificate under your Current User certificate store.


🏢 Step 2: Trust the Certificate Locally

To prevent trust errors, add your new certificate to both the Trusted Root Certification Authorities and Trusted Publishers stores:

$cert = Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert | Where-Object {
    $_.Subject -like "*Local Code Signing*"
}

# Add to Trusted Root
$storeRoot = New-Object System.Security.Cryptography.X509Certificates.X509Store "Root", "CurrentUser"
$storeRoot.Open("ReadWrite")
$storeRoot.Add($cert)
$storeRoot.Close()

# Add to Trusted Publishers
$storeTrusted = New-Object System.Security.Cryptography.X509Certificates.X509Store "TrustedPublisher", "CurrentUser"
$storeTrusted.Open("ReadWrite")
$storeTrusted.Add($cert)
$storeTrusted.Close()

🖊️ Step 3: Sign the PowerShell Script

Use Set-AuthenticodeSignature to sign your script, for example npm.ps1:

Unblock-File "C:\Program Files\nodejs\npm.ps1"

Set-AuthenticodeSignature `
  -FilePath "C:\Program Files\nodejs\npm.ps1" `
  -Certificate $cert

If successful, you’ll see:

Status        : Valid
StatusMessage : Signature verified.

🧪 Step 4: Test Your Signed Script

Run the command:

npm -v

If the configuration is correct, the self-signed PowerShell certificate will allow execution under strict policies.


🧯 Optional: Trust the Certificate for All Users

If you want your signed scripts trusted system-wide:

  1. Export the certificate: Export-Certificate -Cert $cert -FilePath "C:\Temp\LocalCodeSigning.cer"
  2. Open certlm.msc
  3. Import into:
    • Trusted Root Certification Authorities
    • Trusted Publishers

🚀 Why Use a Self-Signed PowerShell Certificate?

✅ Run signed scripts without policy errors
✅ Stay compliant with AllSigned or RemoteSigned
✅ Avoid insecure execution policy bypasses
✅ Increase trust and traceability


🧠 Final Thoughts

PowerShell’s strict execution policies protect your system — but they don’t have to block your workflow.
By creating and trusting a self-signed PowerShell certificate, you can run scripts securely and confidently on your local machine or across your organization.


🔗 Recommended Reading

Similar Posts

Leave a Reply