A script or an executable with a digital signature allows a user to make sure that a file is original and its code has not been changed by third parties. PowerShell also has an integrated feature to sign a *.ps1 script files.
You can sign a PowerShell script using a special type of certificate – Code Signing. This certificate can be obtained from an external certification authority, an internal enterprise CA or you can use a self-signed certificate (of course, it is not the best option).
Suppose, PKI services ( Active Directory Certificate Services) are deployed in your domain. Let’s request a new certificate by going to https://CA-server-name/certsrv and requesting a new certificate with the Code Signing template (this template must first be enabled in Certification Authority console).
Install this certificate to the local certificate authority (storage) on your computer.
After you got the certificate, let’s configure a PowerShell script execution policy and allow running only signed scripts. The default policy value (Restricted) blocks execution of any scripts. To allow running signed scripts, you can change the policy type to AllSigned or RemoteSigned with the only difference that RemoteSigned requires a signature only for the scripts downloaded from the Internet.
Set-ExecutionPolicy AllSigned –Force
Get a certificate from the local storage as a separate object for the current user:
$cert = (Get-ChildItem cert:\CurrentUser\my –CodeSigningCert)
Then sign the script using this certificate:
Set-AuthenticodeSignature -Certificate $cert -FilePath C:\PS\testscript.ps1
New-SelfSignedCertificate -DnsName testPC1 -Type CodeSigning
After the certificate has been generated, move it from Intermediate container to Trusted Root using Certificate Manager console (certmgr.msc).
You can sign a script with this certificate as follows:
Set-AuthenticodeSignature C:\PS\testscript.ps1 @(gci Cert:\LocalMachine\My -DnsName testPC1 -codesigning)
After the PowerShell script has been signed, a signature block is added to the text file of ps1 script:
# SIG # Begin signature block
# SIG # End signature block
If you select [A] Always run at the first run of the script, the next time you run the script, signed using this certificate, a warning will no longer appear.
File C:\PS\testscript.ps1 is published by CN=testPC1 and is not trusted on your system. Only run scripts from trusted publishers.
What will happen if you change the code of the signed PowerShell script? The attempt of running it will be blocked with the notification that the contents of the script has been changed.
Thus, any modification of a signed script will require to re-signing it.