In this post I go over the process of using Certum’s open source code signing certificate to code sign PowerShell scripts.
Why code-sign?
In my case, to help anyone who might want to use PSBlitz in a more restrictive environment where PowerShell scripts are required to be code-signed.
The equipment
I’ve opted for Certum’s open source code signing set.
At the time of writing, the product page states that the included card reader is an ACS ACR39T-A1, but I’ve received an ACS ACR40T-A1.
Code signing a PowerShell script
I’ll skip the cryptographic card initializing and certificate configuration process since that’s covered by Certum already.
With the card reader connected to the computer, I run proCertum CardManager open the Common Profile.


Once the Common Profile is opened and the certificate overview is visible, it can be used for code signing.

In PowerShell, I run the following command to list any available code-signing certificates:
1 | Get-ChildItem -recurse Cert:\CurrentUser -CodeSigningCert | Format-Table -Auto |

So, the code-signing certificate is in my user’s certificate store.
If it isn’t, I can install it from the common profile via “Show certificate details” -> “Install Certificate”.
To reference the certificate itself you need to use the certificate store path followed by the certificate’s thumbprint.
I load the certificate into a variable, to make things easier to read.
1 | $Cert = Get-Item -Path Cert:\CurrentUser\My\1D93C47758AB3EB4FAF34D7BD6252D0C7C456121 |
Also use a variable for PSBlitz.ps1’s path.
1 | $Script = 'F:\PSBlitz_release\PSBlitz\PSBlitz.ps1' |
And then use Set-AuthenticodeSignature to sign the script.
1 | Set-AuthenticodeSignature -FilePath $Script -Certificate $Cert |
I’m prompted for the smart card’s PIN (both PIN and PUK codes are set up while initializing the cryptographic card).

And, after providing it, the script is signed.

I can validate this using the following command:
1 | Get-AuthenticodeSignature -FilePath $Script | Select-Object -Property * |

I can also validate the existence of the signature block by reading the last 90 lines of the script.
1 | Get-Content $Script -Tail 90 |

Testing code-signed script
My current execution policy is RemoteSigned, meaning that scripts created locally do not need to be signed.
To properly test, I’ll need to switch the execution policy of my current PowerShell process to AllSigned.
1 | Set-ExecutionPolicy -ExecutionPolicy AllSigned -Scope Process |

In this case, I’m prompted if I want to run the signed version of PSBlitz.
Attempting to run the unsigned version fails instantly due to the execution policy.

Conclusion
That’s pretty much it. If you’re curios about the post where I’ve first announced PSBlitz, you can find it here