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:
- Export the certificate:
Export-Certificate -Cert $cert -FilePath "C:\Temp\LocalCodeSigning.cer" - Open
certlm.msc - 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.
