Self-signing your Windows Powershell scripts allows you to run your scripts without fully disabling security. Disabling security would permit malicious scripts to run.

This example uses Windows 10, so change your targets as appropriate.

Install the Windows SDK

Install the SDK by running the downloaded executable.

Make makecert available

Find

In my version of Windows, make cert is found under the folder, C:\Program Files (x86)\Windows Kits\10\bin. Explore to find the exact location of makecert.

Copy

I choose to copy the makecert to my C:\bin folder (already in my PATH) but you may choose to add the folder to your path instead.

  • In Powershell, copy "C:\Program Files (x86)\Windows Kits\10\bin\x64\makecert.exe" C:\bin

Add to PATH

Alternatively, you may add the folder to your path.

  • Windows key - r

  • Enter SystemPropertiesAdvanced

  • Click Environment Variables

  • Select PATH

  • Click Edit

  • Add C:\Program Files (x86)\Windows Kits\10\bin\x64 as a new variable in your path

Using makecert

  • Start Powershell as an Administrator

Local Certificate Authority

  • 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

    • Enter passwords

    • Operation should succeed

  • Verify via CertMgr

    • Navigate to Trusted Root Certificate Authorities >> Certificates

    • Find the certificate named, PowerShell Local Certificate Root

Generate a Personal Certificate

  • makecert -pe -n "CN=Gary PowerShell Cert" -ss MY -a sha1 -eku 1.3.6.1.5.5.7.3.3 -iv root.pvk -ic root.cer

    • Enter password

    • Operation should succeed

  • Verify via CertMgr

    • Navigate to Personal >> Certificates

    • Find the certificate named, Gary PowerShell Cert

  • Verify your certificate is available, get-childitem cert:\CurrentUser\my -codesigning

    • You should see your certificate listed

The certificate is now ready for use on the current system. See http://www.darkoperator.com/blog/2013/3/5/powershell-basics-execution-policy-part-1.html for information on how to export it to other systems.

Change Powershell Execution Policy

  • Show current execution policy, Get-ExecutionPolicy -List

  • Change execution policy to AllSigned with a CurrentUSer scope, Set-ExecutionPolicy AllSigned -Scope CurrentUser

Sign some code

Have your freshly written script ready for signing. For demonstration, the script is named example.ps1.

  • Start Powershell as a user

  • $cert = @(Get-ChildItem cert:\CurrentUser\My -codesigning)[0]

  • $file = "\bin\screenshot.ps1"

  • Set-AuthenticodeSignature $file $cert

The reply you receive should be similar to:

Directory: C:\path

SignerCertificate        Status                  Path
-----------------        ------                  ----
34552NJNH568NJBH3256I    Valid                   example.ps1

Downloaded Scripts

Downloaded scripts cannot be signed due to special metadata attached to the file. This may be viewed by opening a cmd window and entering the command dir /r or dir /r filename. You will notice that some files may have a second entry similar to the following:

08/27/2015  12:51 PM    372,681 filename
                             26 filename:Zone.Identifier:$DATA

Resources