Hey there! If you’re getting started with PowerShell, you might have encountered an annoying issue: your scripts just won’t run because they’re not digitally signed. It’s like trying to enter a high-security building without an ID – no way you’re getting in! This guide is your all-access pass. We’ll dive deep into the world of signing PowerShell scripts. Whether you’re a newbie or a seasoned pro, you’ll find valuable nuggets of info here. Let’s demystify this whole “PowerShell is not digitally signed” puzzle.

Warning: PowerShell detected that you might be using a screen reader and has disabled PSReadLine for compatibility purposes. If you want to re-enable it, run ‘Import-Module PSReadLine’.
i want to see output of this code with showing sign conventions of hand
asked Jan 7 at 6:08
Pandurang Shrirame
Outputting data from unit test in Python
What does Ruby have that Python doesn’t, and vice versa?
how to reload a Class in python shell?
Outputting data from unit test in Python
What does Ruby have that Python doesn’t, and vice versa?
how to reload a Class in python shell?
Unable to import multithreaded Python module.
Python newb MacOS in IDLE and PyCharm ModuleNotFoundError: No module named ‘nltk’
Signing a PowerShell script with self-signed certificates (and without makecert.exe)
Python is running a script randomly
Load 4 more related questions
Show fewer related questions
Reset to default
Install Unsigned Drivers

And we must click : “Install this driver software anyway”.
Tools that you need: (most are from the Windows Driver Kit – the latest version of Windows Driver Kit W11 22H2):
Inf2Cat.exe (To generate the unsigned catalog file from our INF)
Makecert.exe (Used to create our certificate)
Signtool.Exe (Sign our catalog file with an Authenticode digital signature)
Certmgr.exe (Used to add and delete our certificate to the system root)
Let’s have a look at each step that you must take to get your unsigned certificates installed silently.
Create a digital certificate by using the MakeCert tool
makecert -r -n "CN=Name" -ss CertStore -sr LocalMachine
Ex: makecert -r -n CN=”TestCert” -ss Root -sr LocalMachine
Specifies that the certificate is to be “self-signed,” rather than signed by a CA. Also called a “root” certificate.
-n “CN= Name “
Specifies the name associated with this new certificate. It is recommended that you use a certificate name that clearly identifies the certificate and its purpose.
Specifies the name of the certificate store in which the new certificate is placed.

The command returns the message “Succeeded” when the store and certificate are created.
Create a .cat (catalog) file for the driver
We notice that some drivers don’t contain a cat file, so we’ll need to generate one.
If it’s not there, add the lineat the end of the section. For example:
[version]Signature=xxxxxxProvider=xxxxxxCatalogFile=MyCatalogFile.cat
“MyCatalogFile.cat” is the name of the cat file that we want to generate. Not having a line specifying this will result in an “error 22.9.4 – Missing 32-bit catalog file entry” when we run Inf2Cat.exe.
Inf2Cat.exe /driver:"<Path to folder containing driver files
– /driver: c:\toaster\device
Specifies the location of the .inf file for the driver package. You must specify the complete folder path. A ‘.’ character does not work here to represent the current folder.
– /os: 10_x86 or 10_x64
Identifies the 32-bit version of Windows 10 as the operating system. Run the command inf2cat /? for a complete list of supported operating systems and their codes.

Export the certificate from certstore manually
Export the certificate manually:

Install the certificate to Root and TrustedPublisher
certutil.exe -addstore "Root" [PathToCertificatewithFile] certutil.exe -addstore "TrustedPublisher" [PathToCertificatewithFile]

for remove :
certutil.exe -delstore "Root" [PathToCertificatewithFile] certutil.exe -delstore "TrustedPublisher" [PathToCertificatewithFile]
Now we can install the driver without the prompt.
Build the MSI
Now that we have understood how you sign a driver we also need to learn how you add the actions in the MSI. Basically all you need are two steps:
- Install the certificate
- Install the driver
For the second step we already had a look a chapter earlier on how to achieve that, so basically all we have to do is create a script that performs the certutil commands previously mentioned. Let’s assume that the driver .inf name is HP.inf and let’s assume that we are going to place the certificate directly into the C:\Windows\DPInst.
Option Explicit
On Error Resume Next
Dim strCmd,WshShell,strInstalldir
Set WshShell = CreateObject("WScript.Shell")
strInstalldir = WshShell.ExpandEnvironmentStrings( "%SYSTEMROOT%" )
strCmd = "certutil.exe -addstore " & chr(34) & "Root" & chr(34) & " " & chr(34) & strInstalldir & "\DPInst\TestCer.cer" & chr(34)
WshShell.Run strCmd- Option Explicit: This statement enforces variable declaration in the script, ensuring that all variables are explicitly declared before they are used.
- On Error Resume Next: This statement allows the script to continue running even if an error occurs, bypassing the error and continuing with the next line of code.
- Dim strCmd, WshShell, strInstalldir: Declares three variables: strCmd to hold the command to be executed, WshShell to access the Windows Script Host Shell object, and strInstalldir to store the expanded value of the %SYSTEMROOT% environment variable.
- Set WshShell = CreateObject(“WScript.Shell”): Creates an instance of the Windows Script Host Shell object, which allows the script to run shell commands and interact with the Windows environment.
- strInstalldir = WshShell.ExpandEnvironmentStrings(“%SYSTEMROOT%”): Retrieves the value of the %SYSTEMROOT% environment variable using the ExpandEnvironmentStrings method of the WshShell object. The %SYSTEMROOT% variable represents the path to the Windows installation directory.
- strCmd = “certutil.exe -addstore ” & chr(34) & “Root” & chr(34) & ” ” & chr(34) & strInstalldir & “\DPInst\TestCer.cer” & chr(34): Constructs the command to be executed. It uses the certutil.exe utility to add a certificate (TestCer.cer) to the “Root” certificate store. The path to the certificate file is obtained by combining strInstalldir (Windows installation directory) with the relative path \DPInst\TestCer.cer. The chr(34) is used to insert double quotes into the command string.
- WshShell.Run strCmd: Executes the command stored in the strCmd variable using the Run method of the WshShell object. This runs the command in a separate process.
In summary, the script uses VBScript to execute the certutil.exe command and add a certificate (TestCer.cer) to the “Root” certificate store. The script retrieves the Windows installation directory, constructs the command with the appropriate paths and options, and then runs it using the WshShell object.
Once the script is created, navigate to the Custom Actions Page and add the Launch attached file predefined custom action into the sequence, select the installation vbscript file that was previously created and configure the Custom Action as such:

Make sure that the script which installs the certificate is placed before the script which installs the driver under the “Install Execution Stage” section.
With PowerShell it’s even easier because we can use the Import-Certificate cmdlet:
$CerLocation = $env:SystemRoot + "\DPInst\TestCer.cer" Import-Certificate -FilePath $CerLocation -CertStoreLocation Cert:\LocalMachine\Root Import-Certificate -FilePath $CerLocation -CertStoreLocation Cert:\LocalMachine\TrustedPublisher
Once we have the script ready, navigate to the Custom Actions Page and add the Run PowerShell script file predefined custom action into the sequence, select Attached Script and select the file that was previously created and configure the Custom Action as such:

Next, build the package and during installation/uninstallation the PowerShell scripts will run and install/uninstall the driver without asking if we want to install an unsigned driver.
Installing unsigned drivers with Advanced Installer
As you can see, handling unsigned certificates is not an easy task and it’s definitely time consuming. Advanced Installer makes it easier to install unsigned drivers with just a click of a button..and yes that is not a figure of speech.
Navigate to the Drivers page and click on New Driver. A window will open for you to select the .inf file which must be present in the package.

Next, all you have to do is just select “Install unsigned driver packages and driver packages that have missing files” and Advanced Installer does everything for you!

And that is it! Next, just build and install the package and you should have a clean installation without any warning messages from the OS.

MSI Packaging In-Depth Training Book
by Alexandru Marin
Troubleshooting Guide
Here are solutions for common errors seen when running signed PowerShell scripts:
Error: “Powershell says The file C:\scripts\myscript.ps1 cannot be loaded. The signature of the certificate cannot be verified…”
Solution: Ensure your root CA certificate is installed correctly in the Trusted Root CA store. Rerun the Install-Certificate command from Step 2.
Error: “The script has an invalid signature. The signature is valid, but it comes from an untrusted source”
Solution: Get the script signed by a trusted CA provider like DigiCert, GoDaddy, etc. instead of using a self-signed cert.
Error: “The file is not digitally signed” in spite of signing the script.
Solution: Close and re-open the PowerShell session and retry running the script. The signed status is sometimes not refreshed in active sessions.
Error: Access is denied. (0x80070005 (E_ACCESSDENIED))
PowerShell Execution Policies
Before we dive into signing, let’s talk about execution policies. These are rules that determine how PowerShell handles scripts. If your policy is set to “Restricted,” even signed scripts won’t run. The “AllSigned” policy is like a VIP pass – only signed scripts can run.
Configuring your PowerShell execution policy is a critical step in setting up your environment for script signing. This policy serves as a gatekeeper, determining which scripts will run on your system. It’s imperative to modify the execution policy to allow for the execution of digitally signed scripts, thus providing a safeguard against running potentially harmful scripts.
| Execution Policy | Description | Scope of Impact |
|---|---|---|
| Restricted | No scripts allowed to run | Default on Windows |
| AllSigned | Only runs scripts signed by a trusted publisher | Recommended for most users |
| RemoteSigned | Requires remote scripts (Internet) to be signed | Flexible yet secure option |
| Unrestricted | No restrictions on script execution | Not recommended due to security risks |
| Bypass | Ignores all execution policies | Should be used with extreme caution |
Signing a PowerShell script involves cryptographically signing the script contents using a code signing certificate. This validates and establishes the source and integrity of the script. Signing the script ensures PowerShell can verify the script’s publisher and prevents tampering. The digital signature container embeds signing details within the script itself.
Here’s how to ensure your scripts withstand the demands of security-conscious environments:
- Prepare the PowerShell Script for Signing – Begin by ensuring your script (sign.ps1) is finalized and free of any syntactical errors. Review your code thoroughly to avoid signing an incorrect version.
- Obtain Your Digital Certificate – You must have a valid digital certificate available to sign your script. This can be from a trusted Certificate Authority or a self-signed certificate, depending on your requirements and the level of trust you need to establish.
- Use the Set-AuthenticodeSignature Cmdlet – PowerShell is equipped with Cmdlets to facilitate script signing directly within the console. Set-AuthenticodeSignature is the Cmdlet you’ll use to append your digital signature to the script.
- Verify the Script is Signed – After appending the digital signature, validate the signing process by running a check on the script to confirm the signature is attached and recognized by the system.
Prerequisites for Signing PowerShell Scripts
- Code Signing Certificate: You need a valid code/digital signing certificate issued from a trusted Certificate Authority. It can be self-signed for testing.
- Administrative Privileges: You must have administrative privileges on the system to install certificates or make changes to sign scripts.
Step 1: Get a Digital Certificate
To sign scripts, you need a digital certificate. It’s like your unique digital fingerprint. You can get one from a Certificate Authority (CA) or create a self-signed certificate for testing. For scripts that will be distributed or deployed in a production environment, it is advisable to opt for a digital certificate from a Trusted Certificate Authority. Such a certificate carries more weight as it is issued by an external, trusted entity, lending greater credibility to your scripts.
Creating a Self-Signed Certificate
Self-signed certificates are a feasible option for code-signing PowerShell scripts, especially when the scripts are for internal or testing purposes. They are easy to generate and provide a layer of security without incurring the costs associated with certificates from a Certificate Authority (CA). However, they lack the trust factor provided by a third-party CA, which is often important for scripts used in broader and more formal settings. Below are the necessary steps to create a self-signed certificate on a Windows machine:
- Open PowerShell as an administrator.
- Use the New-SelfSignedCertificate cmdlet to create a certificate.
- Specify the certificate parameters such as type, subject name, and expiration date.
- Once the certificate is created, export it to “Trusted Root” and use it to sign scripts with certificates in PowerShell.
#Parameters
$CertificateName = "PowerShell Code Signing"
#Create a Self-Signed SSL certificate
$Certificate = New-SelfSignedCertificate -CertStoreLocation Cert:\CurrentUser\My -Subject "CN=$CertificateName" -KeySpec Signature -Type CodeSigningCert
#Export the Certificate to "Documents" Folder in your computer
$CertificatePath = [Environment]::GetFolderPath("MyDocuments")+"\$CertificateName.cer"
Export-Certificate -Cert $Certificate -FilePath $CertificatePath
#Add Certificate to the "Trusted Root Store"
Get-Item $CertificatePath | Import-Certificate -CertStoreLocation "Cert:\LocalMachine\Root"
Write-host "Certificate Thumbprint:" $Certificate.ThumbprintVoilà! You’ve got a certificate. Make a note of the certificate Thumbprint. If you don’t add the certificate to the Trusted Root certification authorities, you’ll see an error message, “File <File-Path> cannot be loaded. A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider.”
Step 2: Signing Your Script
Now, let’s get to the important part – signing your script. Find your script’s path. Let’s say it’s C:\Temp\Backup.ps1. and locate your certificate. Make sure you obtain and update the Certificate thumbprint from the previous step.
#Set Parameters
$CertificateThumbprint = "D00AC4CE2C766783510D67B5DAD3971891AC9239"
$ScriptPath = "C:\Temp\Backup.ps1"
#Get the Certificate from Cert Store
$CodeSignCert = Get-ChildItem -Path Cert:\CurrentUser\My | Where-Object {$_.Thumbprint -eq $CertificateThumbprint}
#Sign the PS1 file
Set-AuthenticodeSignature -FilePath $ScriptPath -Certificate $CodeSignCertBoom! Your script is now signed, and the Powershell script is not digitally signed. The error should go away!
You can obtain the certificate thumbprint from the certificate console:

$Cert = Get-ChildItem -Path Cert:\CurrentUser\My | Where-Object {$_.Thumbprint -eq $CertificateThumbprint}
Set-AuthenticodeSignature -FilePath "C:\Path\To\Your\Script.ps1" -Certificate $cert -TimestampServer "http://timestamp.digicert.com"Replace C:\Path\To\Your\Script.ps1 with the actual path to your script, $cert with the imported code signing certificate and TimestampServer with the name of a trusted timestamp authority.
After completing these steps, your PowerShell script will be digitally signed, ensuring that it is safe to use and has not been tampered with.
Step 3: Verify Signed Script
If you open the signed PS1 file, you’ll find the encrypted signature:

You’ll also find a “Digital Signature” tab on the PS1 file’s properties window.

You can also validate the script with the below script:
Get-AuthenticodeSignature C:\Temp\Backup.ps1 | fl

Managing Certificates for Script Signing
Ensuring the security and integrity of your PowerShell scripts is a continuous process that extends beyond just creating and signing scripts. A critical aspect of maintaining this security posture involves the adept management of digital certificates used for script signing. It’s crucial to not only keep a keen eye on the validity of these certificates but also to have robust procedures in place for renewing certificates and dealing with potentially compromised ones. Let’s delve into the methods you can employ to keep your certificates up-to-date and manage them effectively.
Renewing Certificates
Certificates come with an expiration date, and it’s imperative that you renew your certificates well before they expire to prevent any interruption in your workflow. Renewing certificates for script signing is a task that safeguards the continuity of trust for your scripts. Below, you will find essential steps and considerations for the renewal process:
- Monitor the expiration dates of your certificates regularly using certificate management tools or a manually maintained schedule.
- Start the renewal process early to allow ample time for re-signing any existing scripts and to avoid a lapse in the trust chain.
- Follow the renewal procedures provided by your Certificate Authority; these may vary but generally involve a similar verification process as the initial issuance.
- Post-renewal, promptly update your scripts with the new certificate to ensure that all future script executions are verified against the current, valid certificate.
Revoking and Managing Compromised Certificates
When a certificate used for signing PowerShell scripts is compromised, it poses a serious security risk and must be dealt with immediately. A compromised certificate can allow malicious scripts to appear as trustworthy, potentially causing damage to your systems and reputation. Here’s what you need to do in the event of compromise:
- Immediately revoke the compromised certificate through your Certificate Authority to prevent its further use.
- Communicate with your users regarding the compromise and revocation to maintain transparency.
- Re-sign all affected scripts with a new, secure digital certificate to restore security and trustworthiness.
- Review and enhance your certificate management and security policies to mitigate the chance of future compromises.
Best Practices for PowerShell Script Security
Here are some recommendations for securely signing PowerShell scripts:
- Obtain code signing certificates from trusted providers like DigiCert, Comodo etc
- Use a unique certificate exclusively for PowerShell script signing
- Ensure the root CA and intermediates are added to Trusted Root stores
- Do not share the code signing certificate’s private key
- Keep your scripts up-to-date. Old scripts might have vulnerabilities.
- For production, always use certificates from a trusted CA. Self-signed ones are great for testing, but not for real-world use.
Implementing these practices ensures optimal security when signing and running PowerShell scripts. Microsoft Reference: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_signing?view=powershell-7.4
Wrapping up
Congratulations! You’re now a wizard in signing PowerShell scripts. Signing PowerShell scripts digitally enables secure execution of automation scripts and prevents tampering by malicious actors. It also averts certain PowerShell security controls and allows running scripts seamlessly across systems.
What are the benefits of signing PowerShell scripts?
Signing PowerShell scripts provides assurance of authenticity, establishes trustworthiness, and ensures compliance with organizational security policies. It also helps prevent the execution of unauthorized code, thus maintaining the integrity and security of the scripts.
What should I do if my signing certificate is compromised?
If your certificate is compromised, you should immediately revoke the certificate to prevent its further use. Next, assess the impact and potential breach, communicate with affected parties, and reissue your scripts with a new, secure signing certificate as needed.
Can I run unsigned PowerShell scripts?
Running unsigned scripts is contingent on the execution policy of your PowerShell environment. For security reasons, most production environments require scripts to be signed. However, for testing purposes or on trusted networks, your execution policy may permit running unsigned scripts.
How can I manage the certificates used for PowerShell script signing?
Managing certificates involves monitoring for validity, renewing them before expiration, and revoking them if compromised. Tools are available within the Windows operating system and PowerShell to facilitate these management tasks.
How can I verify a PowerShell script’s signature?
You can manually verify a script’s signature by using the Get-AuthenticodeSignature cmdlet in PowerShell or through the properties of the file in Windows. For automated verifications, scripts and tools such as sigcheck can be used, particularly useful in large-scale or frequent verification scenarios.
What is the Set-AuthenticodeSignature cmdlet and how is it used?
The Set-AuthenticodeSignature cmdlet is used in PowerShell to apply a digital signature to a script. It requires parameters specifying the path to the script and the certificate with which you want to sign it. Mastery of this cmdlet’s parameters facilitates a smooth script signing process.
How do you sign a PowerShell script?
To sign a PowerShell script, you use the Set-AuthenticodeSignature cmdlet and provide it with the script you wish to sign and the signing certificate. Once the cmdlet is applied, it embeds a digital signature into the script.
How do I create a digital certificate for PowerShell script signing?
You can create a self-signed certificate using PowerShell or tools like MakeCert, or you can acquire a certificate from a trusted Certificate Authority (CA). Trusted CA certificates offer broader acceptance for scripts distributed publicly or within professional organizations.
What are the prerequisites for signing PowerShell scripts?
Before you sign PowerShell scripts, you need a valid digital certificate, which can be self-signed or issued by a trusted Certificate Authority (CA). Additionally, you must configure your PowerShell execution policy to allow signed scripts to run on your system.
Table of contents
- Understanding the Need for Signing
- Setting the Stage: PowerShell Execution Policies
- Step-by-Step Guide to Signing a PowerShell Script
- Managing Certificates for Script Signing
- Best Practices for PowerShell Script Security
- Troubleshooting Guide
- Wrapping up
Understanding the Need for Signing
PowerShell scripts can be extremely useful for automating tasks and processes on Windows systems. However, running unsigned PowerShell scripts often results in errors like “PowerShell not digitally signed”, “the file is not digitally signed.” or “is not digitally signed. You cannot run this script on the current system.”. Let’s see how to sign PowerShell scripts to resolve these errors.
Why Sign?
The Risks of Unsigned Scripts
Imagine downloading a script claiming to organize your files but instead, it wreaks havoc. That’s why PowerShell, by default, stops unsigned scripts. It’s like a bouncer for your system’s safety.




