Code-Signing PowerShell Scripts (Part 1)

by May 18, 2022

Adding a digital signature to a PowerShell script is no black magic anymore these days, and while you ideally need an official “trusted” code signing certificate from your corporate IT or trusted authority, even this is not mandatory anymore these days.

Before we proceed with code signing, why would you want to code sign a PowerShell script in the first place?

A digital signature is a hash of your script code, encrypted with the private key of a digital certificate. View it as a “wrapper” or “seal” around your script. With it, you now can always tell whether someone tampered with your script. Without it, you cannot.

If you do not already own a digital certificate suitable for code signing, on Windows machines there is a cmdlet that you can use to create one on the fly: New-SelfSignedCertificate.

Run this line to create your own brand-new code signing certificate and store it in your personal certificate store (which is valid for one year unless you specify a different expiration date using -NotAfter):

 
PS> New-SelfSignedCertificate -Subject MyPowerShellCode -Type CodeSigningCert -CertStoreLocation Cert:CurrentUsermy -FriendlyName 'My Valid PowerShell Code'


   PSParentPath: Microsoft.PowerShell.SecurityCertificate::CurrentUsermy

Thumbprint                                Subject
----------                                -------
57402F9D82231CABA4586127C99819F055AA2AF2  CN=MyPowerShellCode  
 

To retrieve it later at any time, either remember its thumbprint and access it like this (adjust the thumbprint to match the one of your certificates):

 
PS> $cert = Get-Item -Path Cert:CurrentUserMy57402F9D82231CABA4586127C99819F055AA2AF2

PS> $cert.Subject
CN=MyPowerShellCode

PS> $cert.FriendlyName
My Valid PowerShell Code

PS> $cert.NotAfter

Monday, May 1, 2023 17:47:43  
 

Or, you can use a filter if you just remember the subject or friendly name:

 
PS> Get-ChildItem -Path Cert:CurrentUserMy -CodeSigningCert | Where-Object Subject -like *MyPowerShell*


   PSParentPath: Microsoft.PowerShell.SecurityCertificate::CurrentUserMy

Thumbprint                                Subject
----------                                -------
57402F9D82231CABA4586127C99819F055AA2AF2  CN=MyPowerShellCode   
 

In our next tip we take this certificate to use and start signing a PowerShell script.


Twitter This Tip! ReTweet this Tip!