16

I'd prefer using the AllSigned execution policy with PowerShell, but self-signing my scripts seems to require several hundreds of megabytes of downloading and installation and the signing process seems to be a hassle.

Is there a simpler way to sign a PowerShell script than described in the documentation?

3 Answers 3

7

To do the signing you can use the Set-AuthenticodeSignature cmdlet. This, of course, requires a certificate. If you have a Certificate Authority (unlikely) that will be able to create a code signing certificate. Otherwise there are various tools to create a self-signed certificate.

You install the certificate in your certificate store (open the .cer or .pfx file in Windows Explorer to do this), and then pass it to Set-AuthenticodeSignature (the cert: provider/drive gives access to certificates in your store).

Use

help about_signing

or the online version of that help topic for details (including creating a self-signed certificate using the Windows SDK tools[1]).

[1] I assume this is the big download you're referring to: you can just install the bits you need, or make use of other tools (OpenSSL includes certificate generation). Getting the SDK is, for this purpose, a one-off activity.

3
  • I'm accepting this answer and assuming that there is no shortcut and signing just needs to be done as mentioned in the docs. Jan 19, 2010 at 12:30
  • 1
    Like quite a few "developer-y" things the initial set up and learning is hard, but the actual practice (especially if done regularly) isn't.
    – Richard
    Jan 20, 2010 at 10:31
  • For anyone who needs to make a self signed cert to do the above I found these two links helpful: serverfault.com/questions/824574/… and github.com/PowerShell/PowerShell/issues/4753
    – S. Melted
    Sep 14, 2020 at 18:05
6

I use this PowerShell script:

## sign-script.ps1
## Sign a powershell script with a Thawte certificate and 
## timestamp the signature
##
## usage: ./sign-script.ps1 c:\foo.ps1 

param([string] $file=$(throw “Please specify a script filepath.”)) 

$certFriendlyName = "Thawte Code Signing"
$cert = gci cert:\CurrentUser\My -codesigning | where -Filter 
  {$_.FriendlyName -eq $certFriendlyName}

# https://www.thawte.com/ssl-digital-certificates/technical-  
#   support/code/msauth.html#timestampau
# We thank VeriSign for allowing public use of their timestamping server.
# Add the following to the signcode command line: 
# -t http://timestamp.verisign.com/scripts/timstamp.dll 
$timeStampURL = "http://timestamp.verisign.com/scripts/timstamp.dll"

if($cert) {
    Set-AuthenticodeSignature -filepath $file -cert $cert -IncludeChain All -   
      TimeStampServer $timeStampURL
}
else {
    throw "Did not find certificate with friendly name of `"$certFriendlyName`""
}
1
  • How can you use a script to sign a script? Wouldn't your script signing script need to be signed?
    – HackSlash
    Dec 28, 2020 at 18:37
6

Once I had the certificate, I wanted to use imported on my user account. This regkey gave me an option, Sign, in the context menu (I'm using Windows 7). If the certificate you want to sign with is stored differently, just change the PowerShell command at the end.

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Classes\Microsoft.PowerShellScript.1]

[HKEY_CURRENT_USER\Software\Classes\Microsoft.PowerShellScript.1\Shell]

[HKEY_CURRENT_USER\Software\Classes\Microsoft.PowerShellScript.1\Shell\Sign]

[HKEY_CURRENT_USER\Software\Classes\Microsoft.PowerShellScript.1\Shell\Sign\Command]
@="C:\\\Windows\\\System32\\\WindowsPowerShell\\\v1.0\\\powershell.exe -command Set-AuthenticodeSignature '%1' @(Get-ChildItem cert:\\\CurrentUser\\\My -codesigning)[0]"
2
  • This worked for me for years until I changed the default app for .ps1 files from "Notepad" to "Visual Studio Code". After I made that change, I lost the "Sign" option in the Explorer context menu. Switching the default app back to "Notepad" restored the "Sign" option in the explorer context menu.
    – mwolfe02
    Aug 25, 2020 at 21:24
  • This trick also works for Powershell module files by creating the same set of keys as in the answer but substituting Microsoft.PowerShellModule.1 for Microsoft.PowerShellScript.1.
    – mwolfe02
    Aug 25, 2020 at 21:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .