How To Digitally Sign a Microsoft PowerShell Script with a Third-Party Code Signing Certificate (Update April 4, 2012)
September 30, 2011
I recently wrote an article on using Microsoft PowerShell to document a Citrix XenApp 6.0 farm. I am also in the process of finishing up follow-up articles for XenApp 5 and XenApp 6.5. One of the options I wanted to make available is a digitally signed copy of the script used in that article. As there may be environments where only signed PowerShell scripts are allowed, I want to make signed copies of all my PowerShell scripts available. I still consider myself a PowerShell rookie, so I wanted to document what I had to go through to sign a PowerShell script.
Update: I now use the Digicert Certificate Utility for Windows to sign all my scripts.
The first thing needed is to request a code signing certificate. At DigiCert, I clicked on Code Signing Certificates (Figure 1).
I then selected Buy Now (Figure 2).
I then selected Code Signing Cert, a Validity Period, and clicked Continue (Figure 3).
Next, I selected Microsoft Authenticode and clicked Continue (Figure 4).
Next, I filled in my Organization Details and clicked Continue (Figure 5).
I then filled in my Contact Details and clicked Continue (Figure 6).
I removed the Payment step information. I selected I agree to the Terms of Service above and clicked Complete Order (Figure 7).
I then received an e-mail from DigiCert Support asking me to verify that I did request a Code Signing Certificate. After I replied to the e-mail in the affirmative, I received another e-mail with a link to create the code-signing certificate (Figure 8).
Clicking the link in the e-mail opens my Internet browser with the following popup (Figure 9). I clicked Yes.
Which then took me to the web site shown in Figure 10. I then clicked Generate Certificate.
Which then took me to the web page shown in Figure 11.
I verified in Internet Explorer that the certificate is installed (Figure 12 and Figure 13).
On the computer where the Code Signing Certificate was installed, I started a PowerShell session running as Administrator. Using the information from Don Jones’ Windows PowerShell 2.0 TFM book on page 149, I entered the following PowerShell command (should be one long line):
Set-AuthenticodeSignature ` "C:\Users\cwebster\Documents\carlwebster.com\Documenting a Citrix XenApp 6 Farm with Microsoft PowerShell\XA6_Inventory_Signed.ps1" ` -TimestampServer "http://timestamp.digicert.com/" @(Get-Childitem cert:\CurrentUser\My -codesigning)
Which then returns a successful signing (Figure 14).
Opening my script shows the added signature block (Figure 15).
To verify the newly signed script, I went to my XenApp 6 server, copied the signed script to the C:\PSScripts folder, started a PowerShell session as Administrator, and changed to the C:\PSScripts folder. I then set the PowerShell script execution policy to AllSigned (Figure 16).
I then tried to run the original unsigned script (Figure 17). The script would not run because it is not digitally signed.
I then tried to run the signed script (Figure 18).
I answered A to Always run scripts signed by me (Figure 19) and the script runs successfully.
By answering Always run my code signing certificate was installed on the server in the Trusted Publishers store (Figure 20).
The next time I run the signed script, the script automatically runs (Figure 21).
What I learned is that digitally signing PowerShell scripts is simple to do. It is not cheap, but it is simple.