Signing PowerShell Scripts
05 Sep 2016PowerShell scripts used in production environments should be signed to prevent modification, and server configurations should enforce script signing to mitigate risks of malicious code being run on them.
- Get and install a signing certificate, ideally in an environment that’s completely separate from your production environment where the signed script will be run. I used StartSSL but you may wish to go with a less shady Certificate Authority. If you go with a self-signed certificate, you’ll need to deploy your CA certificate on all your machines where you plan to run this script.
- Ensure the signing certificate is available to PowerShell. I assume you only have 1 cert installed in the step below since I use [0] in the next step.
> Get-ChildItem cert:\CurrentUser\My -codesign Thumbprint Subject ---------- ------- 3355EBE8EB05071263E1B0DC989EEE072DFE0A72 CN=Justin Ho, L=Toronto, S=Ontario, C=CA
- Sign the script, which I’ve named
somescript.ps1
in the example below.- Pull the cert from the local store
> Set-AuthenticodeSignature somescript.ps1 @(Get-ChildItem cert:\CurrentUser\My -codesigning)[0] -IncludeChain "All" -TimestampServer "http://timestamp.verisign.com/scripts/timstamp.dll"
- You can also use
http://timestamp.comodoca.com
per https://support.comodo.com/index.php?/Knowledgebase/Article/View/68/0/time-stamping-server orhttp://timestamp.digicert.com/
. - If you don’t want to import the certificate, you can just load the certificate for this process:
> $Cert = Get-PfxCertificate -FilePath "mycert.pfx" > Set-AuthenticodeSignature -FilePath somescript.ps1 -Certificate $Cert -IncludeChain "All" -TimeStampServer "http://timestamp.verisign.com/scripts/timstamp.dll"
- Pull the cert from the local store
- Verify that PowerShell recognizes the signature is valid. You should see a
TimeStamperCertificate
in addition to theSignerCertificate
and theStatus
should beValid
.> Get-AuthenticodeSignature .\somescript.ps1 -Verbose | fl
- Check the current Execution Policy and update it for the local machine.
Get-ExecutionPolicy -List | ft -AutoSize Set-ExecutionPolicy AllSigned -Scope LocalMachine
- Test your newly signed script and trust your certificate as needed. (Note this is required even if you have a publicly issued cert.)
.\somescript.ps1