In our previous tip we explained how you can use New-SelfSignedCert to create a self-signed code signing certificate. Today, we’ll use a self-signed or corporate code signing certificate to actually start and digitally sign a Powershell script.
For this, take any PowerShell script file you want. All you need is its path. Also, you need the path to a valid code signing certificate stored in any of Windows certificate stores. Here is a quick recap of part 1 to create a self-signed certificate in case you have no corporate certificate at hand:
$Subject = 'MyPowerShellCode' $FriendlyName = 'My Valid PowerShell Code' # expires 5 years from now: $ExpirationDate = (Get-Date).AddYears(5) # store in user personal store: $certStore = 'Cert:CurrentUsermy' # create certificate: $cert = New-SelfSignedCertificate -Subject $Subject -Type CodeSigningCert -CertStoreLocation $certStore -FriendlyName $FriendlyName -NotAfter $ExpirationDate $thumbprint = $cert.Thumbprint $Path = Join-Path -Path $certStore -ChildPath $thumbprint Write-Warning "Certificate Path: $Path"
When you run this code, you get a self-signed code signing certificate, and the code returns the path to your generated certificate, i.e.:
Cert:CurrentUsermyF4C1F9978D564E143D554F3679746B3A79E1FF87
To use your certificate, read it via Get-Item like so (make sure you adjust the path to match your certificate – each certificate has a unique thumbprint):
PS> $myCert = Get-Item -Path Cert:CurrentUsermyF4C1F9978D564E143D554F3679746B3A79E1FF87
To add a digital signature to a PowerShell script file (or any other file that is capable of carrying a digital signature for this matter), use Set-AuthenticodeSignature. Run the demo code below (adjust paths to file and certificate as needed):
# digitally sign this file (adjust path to an existing ps1 file): $Path = "$env:temptest.ps1" # adjust this path to point to a valid code signing certificate: $CertPath = 'Cert:CurrentUsermyF4C1F9978D564E143D554F3679746B3A79E1FF87' # if it does not exist, create a dummy file $exists = Test-Path -Path $Path if ($exists -eq $false) { 'Hello World!' | Set-Content -Path $Path -Encoding UTF8 } # read a code signing certificate to use for signing: $myCert = Get-Item -Path $CertPath # add a digital signature to a PS script file: Set-AuthenticodeSignature -FilePath $Path -Certificate $myCert # show changes inside script file: notepad $Path
When you run this code, the script file specified in $Path opens and shows the digital signature that was added to the bottom of your script:
Hello World!
# SIG # Begin signature block
# MIIFcAYJKoZIhvcNAQcCoIIFYTCCBV0CAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU4QK+x7NLicgrIdzN+Nvxqbuq
# Qv2gggMKMIIDBjCCAe6gAwIBAgIQG5jphqHXvLJFA0oCJTgcpDANBgkqhkiG9w0B
…
Congrats, you just digitally signed a PowerShell script! We’ll explore the benefits of such a signature in part 3.