Creating Self-Signing Certificates and assigning to Powershell scripts

If we take the assumption that you’ve just started out with powershell, you have probably seen this error when attempting to run a script:

File C:\scripts\test.ps1 cannot be loaded because the execution of scripts is 
disabled on this system. Please see "get-help about_signing" for more details.

Probably after some research and looking into about_signing you may have run the following in your Powershell editor:

Get-ExecutionPolicy

and found that your machine was set to be restricted. This policy prevents any scripts from being run in your environment. The next thing you probably did was set your execution policy to be Unrestricted, which then allows any scripts to be run without any security checks.

This would have solved your immediate problem of getting the script to run, however, to create more control over what can run and what cant, you can introduce certificates.

Self-Sign Certificates

To create Self-Signed ceriticates, the makecert.exe tool needs to be installed. This ships as part of the .NET Framework SDK (1.1 or higher) – i have 2.0 installed (found here)

To make the certificate:

C:\Program Files\Microsoft.NET\SDK\v2.0 64bit\Bin>makecert -n "CN=PowerShell Local Certificate Root" -a sha1 -eku 1.3.6.1.5.5.7.3.3 -r -sv root.pvk root.cer -ss Root -sr localMachine

Succeeded

C:\Program Files\Microsoft.NET\SDK\v2.0 64bit\Bin>makecert -pe -n "CN=PowerShell User" -ss MY -a sha1 -eku 1.3.6.1.5.5.7.3.3 -iv root.pvk -ic root.cer

Succeeded

After running these commands you will be prompted to provide passwords.  There are a number of ways to determine if the cert was created correctly including looking in the Certificated snap-in MMC (mmc.exe | add snap-in | certificates)

image

or by running the following PowerShell command (I have narrowed down gci to just return where the subject is Powershell as i have several different ceritifcates):

Get-ChildItem cert:\CurrentUser\My | Where-Object {$_.subject -match "Powershell"}

Directory: Microsoft.PowerShell.Security\Certificate::CurrentUser\My

Thumbprint                                Subject

———-                                ——————-

52F872D96D6A507846875CE83317C99F53E5C48F  CN=PowerShell User 

Sign the script

The last step is to sign the script using the newly created certificate:

$cert = @(Get-ChildItem cert:\CurrentUser\My -codesigning `
  | Where-Object {$_.subject -match "Powershell User"})[0]

  Set-AuthenticodeSignature "\\Path\myscript_New.ps1" $cert

SignerCertificate                         Status       Path

—————–                         ——       ——–

52F872D96D6A507846875CE83317C99F53E5C48F  Valid        myscript_New.ps1

Troubleshooting

If your having issues with signing the script then see this – UnknownError when using Powershell ISE to Set-AuthenticodeSignature

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: