Page Nav

HIDE

Grid

GRID_STYLE

Signing a Powershell Script with a Self-Signed Certificate

Introduction You can create a cert to allow you to sign Powershell scripts. Using unsigned scripts requires you to completely disable ...

Image result for Signing a Powershell Script with a Self-Signed Certificate

Introduction

You can create a cert to allow you to sign Powershell scripts. Using unsigned scripts requires you to completely disable security measures that protect against running unwanted code, which would be bad. This method allows you to avoid disabling the code-signed policy.
Everything we do below uses a Powershell prompt, not a command prompt.
Background on certs:
Certificates are given their authority by certificate authorities (CAs). CAs confirm whether or not a certificate is valid. When your computer attempts to use a certificate, it confirms the validity of the certificate by requesting a "trusted" CA validate the certificate.
You can pay a CA to sign a cert for you, or use a process called self-signing to create your own CA, then create your own certificate, and then sign your certificate with your own CA.
Windows stores information about which CAs are valid in the certificate store (again, in the "trusted CA list". For our purposes this is CurrentUser>Trusted Root Certification Authorities>Certificates.
Windows stores certificates in the certificate store, for our purposes this is CurrentUser>Personal>Certificates and CurrentUser>Personal>Certificates.

Steps (9 total)

1

Install the Windows SDK (which installs makecert)

https://www.microsoft.com/en-us/download/details.aspx?id=8279
This is the link to download the SDK for Windows 7.
We'll use makecert to create both the CA cert and your personal cert.
Protip: the SDK failed to install for me until i uninstalled all previous versions of Visual Studio
2

Add the path to makecert to your PATH environment var

Start > right-click Computer > Properties
click Advanced system settings
Advanced tab > Environment Variables...
User variables > PATH entry > Edit...
Add C:\Program Files\Microsoft SDKs\Windows\v7.1\bin to your path.
If you've never done this before, you'll typically want to add on to the end of the existing entry. To do this, add a semicolon to the end, and then paste in the new entry at the end. So you'll end up with something like:
otherdirectoriesthatalreadyexisted;C:\Program Files\Microsoft SDKs\Windows\v7.1\bin
3

Use powershell to create the CA cert

Now you have access to makecert in Powershell (because we have the SDK in place).
PS C:\Users\username> 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
Error: Save encoded certificate to store failed => 0x5 (5)
Failed
----
Alternatively,
makecert -n "CN=TempCA" -r -sv TempCA.pvk TempCA.cer
4

Add and conf the CA cert is trusted

open certmgr.msc
under CurrentUser>Trusted Root Certification Authorities, right click Certificates
select All Tasks > Import
find the file you just created, import it
5

Create a personal cert and use the new CA cert to sign the new personal cert

PS C:\Users\benb> 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
you should now see the Powershell User cert in CurrentUser>Personal>Certificates
Ok, great. You've created your own CA, and then created and signed a cert using your CA. Almost done!
--
Alternatively,
makecert -sk SignedByCA -iv TempCA.pvk -n "CN=SignedByCA" -ic TempCA.cer SignedByCA.cer -sr currentuser -ss My
you should now see the SignedByCA cert in CurrentUser>Personal>Certificates
If not, you can import the SignedByCA.cer into the Personal Certificates manually (see last step for example).
6

Tell Windows to allow signed scripts to run

(the default state in Windows is to not run any scripts, signed or not)
Start menu > type "powershell" > right-click powershell and select Run as Administrator...
set-executionpolicy allsigned
yes/confirm
7

Confirm your cert is available

gci cert:\CurrentUser\My -codesigning
If this is blank, you may be unable to use the next step to sign your script. Blank means Windows is unaware of any available personal certs.
8

Sign your Powershell script using your new cert

Two commands, we'll set a variable ($cert) and then use it:
$cert = @(Get-ChildItem cert:\CurrentUser\My -CodeSigning)[0]
Set-AuthenticodeSignature .\your-script.ps1 $cert
Should output something like:
Directory: C:\xxxxxx
SignerCertificate Status Path
----------------- ------ ----
12B3xxxxxxxxxxxxxxxxxx Valid yourscript.ps1
----
Alternatively,
signtool sign /a <yourscriptpathandname>
should output:
Done Adding Additional Store
Successfully signed: .\backup-docs.ps1
9

Test running your script

Right-click and Edit your script from Windows Explorer, your script will open in the powershell_ise (Powershell Code Editor). You should see a big block of text below your script - this is the signature you've just applied.
If you click the green > play icon, your script should run. Previously, if the script was not signed, the run would fail with an unsigned code error.

No comments