Change can be dangerous. This is especially true in large IT environments, wherein only approved versions of scripts...
should run. Signing code helps ensure script integrity and enforce good computing hygiene.
With Microsoft PowerShell, most admins use the Set-ExecutionPolicy RemoteSigned command and effectively negate enterprise security. RemoteSigned is one step more secure than an unrestricted policy, so it enables a great deal of freedom for execution. Microsoft's execution policy options include Unrestricted, RemoteSigned, AllSigned, Restricted, Default, Bypass and Undefined. For added ops security, change the policy to run only signed code, under the AllSigned option. To try it out, create your own self-signed certificate.
Author's note: This article covers self-signed certificates for testing purposes. In a production environment, the certificate should be signed by the corporate root certificate. To tighten up control and restrict code execution to scripts signed by a trusted individual, a Windows administrator can modify the policy around PowerShell execution using Group Policy Objects (GPOs).
To modify the execution policy in Windows on a local workstation, open the PowerShell console with administrative privileges. Use the Get-ExecutionPolicy command to display the current execution policy setting. As mentioned, most organizations rely on RemoteSigned, which does not require a signature if the script was written locally. It only restricts code from outside sources.
This PowerShell script is a simple one that takes your name as input and outputs it in a sentence, courtesy of The PowerShell Guy's blog:
$yourName=Read-Host "What is your name?"
Write-Host "Hello $yourName"
Change the execution policy to run only signed code with AllSigned, controlling internal and external sources:
Any change prompts the administrator for approval.
An attempt to run PowerShell scripts at this point would fail because code isn't signed, but this only restricts the use of scripts and potentially any add-in modules from running.
Administrators can still use the PowerShell console for individual commands, but not full scripts. Although there are several other execution policies, this tutorial focuses on how to ensure only signed code runs. This can be enforced via GPO.
Create a new self-signed certificate for demonstration purposes. Microsoft added the New-SelfSignedCertificate cmdlet in PowerShell 4 and eliminated the need for a separate certificate tool, such as MakeCert.
To utilize this cmdlet, run the following command on a system with Windows 8.1 and up. Include the ‘ to allow the command to stretch over several lines.
$mycert = New-SelfSignedCertificate -Subject "CN=PowerShell signing example" `
-KeyAlgorithm RSA -KeyLength 2048 -Type CodeSigningCert `
The above code snippet creates a new certificate (see Figure 3) and assigns it to the variable $mycert. The key is stored in the local certificate store. The -Type CodeSigningCert switch is vital to include to create the correct certificate type. The common name should be useful and intuitive.
To ensure the self-signed certificate generates correctly, type the variable name in PowerShell, $mycert, to make PowerShell echo the variable contents and display the certificate thumbprint.
Move the certificate to the root certificate store with the following command:
Move-Item "Cert:\LocalMachine\My\$($mycert.Thumbprint)" Cert:\LocalMachine\Root
To sign this code example, assign the certificate thumbprint to a variable, which will make it easier to use.
$myrootcert = "Cert:\LocalMachine\Root\$($mycert.Thumbprint)"
Now, sign the PowerShell script with the following:
set-AuthenticodeSignature \Users\Stuart\Desktop\test.ps1 $mycert
This PowerShell file should now be correctly signed. Because the code is not signed by a trusted provider -- just your own self-signed certificate -- you must run the code. Press R to run once or A to accept recurring use.
At the bottom of the PowerShell script file, a section of new code appears: the certificate thumbprint. If either the script or the signing code at the bottom is modified, the script will not run.
This process enabled signed code in PowerShell for a test. Don't try to use this self-signed certificate for the entire estate. Organizations should install an official certificate in a production environment to ensure only signed certificates authorized by the company work.