How to sign a PowerShell script

Version 5
    INTRODUCTION

     

    The old times of batches and VbScript files that everyone can run seems to be gone.

    Microsoft is putting more and more attention on the security and now with Microsoft PowerShell we have the ability to run sign our scripts.

    I think that every new user of PowerShell that tried to launch his first scrip saw this error:

     

    The file C:\my_script.ps1 cannot be loaded. The execution of scripts is disabled on this system. Please see "Get-Help about_signing" for more details.

     

    The default setting of the PowerShell interpreter is to do not allow you to run unsigned script.

    This is very secure but very annoying as well so many users tend to disable this setting using the command

    Set-ExecutionPolicy -ExecutionPolicy Unrestricted

     

    "Problem Solved" then? Yes but the price we pay is that every script can be run without control. So if someone maliciously modifies one of your favorite scripts it will be executed regardless.

     

    The web is plenty of articles about how to sign a PowerShell script: the problem is that you need to read all of them and interpolate them to make it work for real.

     

    It is possible to use a self-signed certificate to sign your scripts but this article will focus on how to set up a Certificate Authority and request a Code Signing certificate to it.

    If you want to know how to create a self-signd certificate you can read this very good artilce written by Scott Hanselman: http://www.hanselman.com/blog/SigningPowerShellScripts.aspx

    PART ONE: Set up a Certificate Authority (Active Directory Certificate Services)

     

    To set up an Active Directory Certificate Services you need a Windows 2008 R2 Server. Do not use a LANDesk Core Server or an ALM/LPM server because you may create damages to the IIS configuration

     

    1. Open the Server Manager snap-in
    2. Click on the Roles section and click on Add Roles
    3. Check the Active Directory Certificate Services and press Next twice
    4. Select at least the Certification Authority and the Certification Authority Web Enrollment options and press Next
    5. At this point you can decide if you want and Enterprise or Standalone certification authority: this depends from your needs: if you click on the link in the setup wizard you can read in the help file what are the main differences.
      In this example we are using the Enterprise one
    6. Leave all the defaults and press next until the reach the end of the Wizard.

     

    PART TWO: How to access it

     

    Now that you have a certification Authority up an running the best way to access it is though the web interface. The URL is:

     

    http://myserver/certsrv

     

    Check that you are able to browse it using HTTPS as well:

     

    https://myserver/certsrv

     

    If you are not able to do so you need to follow this simple procedure:

    1. Open the Internet Information Services (IIS) Manager snap in
    2. Click on your server node
    3. Double click on the Server Certificates icon
    4. Click on Create Self-Signed certificate... (in the right pane)
    5. Enter a name for it and press ok
    6. Explode the node Sites, right click on the Default Web Site and choose the Edit Bindings... option
    7. Click on the Add button then under Type select HTTPS
    8. Select in the SSL Certificate dropdown the SSL certificate created previously
    9. Press ok and then close
    10. Now you'd be able to access the site in HTTPS mode as well.

     

    PART THREE: Own to obtain the Code Signing certificate

     

    First of all we need to verify that we are allowed to ask the Code Signing certificates to your CA

    The procedure is simple:

    1. Open the Server Manager snap-in
    2. Explode the Active Directory Certificate Services
    3. Explode the certification authority (normally it comes immediately after the Certificate Templates icon)
    4. Click on the Certificate Templates folder and verity that Code Signing template is listed.
    5. If is not listed right click on the Certificate Templates folder and select New -> Certificate Template to Issue
    6. Select the Code Signing one and press OK.

     

    Now finally is the moment to access your Certification Authority via HTTPS and get our certificate

     

    1. Browse to https://myserver/certsrv
    2. Click on Request a Certificate link
    3. Click on Advanced Certificate Request link
    4. Click on Create and Submit a request to this CA link
    5. Select from the Certificate Template dropdown the Code Signing one
    6. You can leave all the options like that and click on the submit button
    7. If you are the administrator the certificate request is immediately approved: simply click on Install this certificate link to install it.

     

    PART FOUR - Finally Sign it!!

     

    It is the time now to use it to sign your script:

     

    Suppose that you have already a PowerShell script and you want to sign it.

    You only need to follow this procedure:

    1. Open the PowerShell console
    2. Issue the following command:
      Set-AuthenticodeSignature c:\foo.ps1 @(Get-ChildItem cert:\CurrentUser\My -codesigning)[0]
      NOTE: cert:\CurrentUser\My needs to be written as is...do not substitute the name of your real current user to the string!
    3. If everything is ok you'd receive an answer like that:
      SignerCertificate Status Path
      ----------------- ------ ----
      A180F4B81AA81143AD2969114D26A2CC2D2AD65B Valid foo.ps1

     

    But what about if a receive and error and the error is Unspecified ?

     

    Many things can go wrong but 99% of the times the reason is that your script was not saved in UTF-8.

    Try to open the script with NOTEPAD and click on File -> Save As  and be sure that the ENCODING is set to UTF-8

    After you save your script in UTF-8 try the signing procedure again.

     

    PART FIVE: Now test it!

     

    Now that everything let try if really works...

    1. Launch the PowerShell console as administrator (right click -> Run as Administrator)
    2. issue the command
      Set-ExecutionPolicy -ExecutionPolicy AllSigned
    3. Launch a not signed script:C:\myscripts\notsigned.ps1
    4. You will obtain an error
    5. Launch now your script:  C:\myscripts\foo.ps1
    6. Does it Work?!?! Yes?? Well DONE!

     

    PART SIX: The FAQs

     

    Q: I noticed that when I request the certificate the option "Mark keys as Exportable is grayed out"..why? what I can do?

     

    A:This is a big mystery to me as well because in a lot of articles I read this option is always selectable but in my labs is grayed out.

    To circumvent the problem you need to follow this procedure:

    1. Open server manager and select the Certificate Templates node that is under the Active Directory Certificate Services

    2. Right click on the Code Signing template and select the option "Duplicate template"

    3. Give it a name like My Code Sign, in the Request Handling tab check the box Allow private keys to be exported and press ok.

    4. Explode your certification authority node (under Active Directory Certificate Services) and right click on the Certificate Templates folder

    5. Choose the option New -> Certificate Template to issue

    6. Select the newly create template and press ok

    The next time you ask for a certificate via the web interface select as template the newly created one.

     

    Q: Now I can sign my scripts but how the others are going to trust them?

     

    A:You need to distribute via GPO or other ways the public part of your signing certificate (THE PUBLIC ONLY!!!!)

    This public part of the certificate need to be installed under the Trusted Publishers repository of the certificates.

    Be sure that the certificate is valid once imported. If not you need to deploy the ROOT CA certificate of your CA and install it under the Trusted Root Certification Authority repository

     

    Q: Set up and mantain a CA (Certification Authority) is complex and troublesome for my organization. What can I do?

     

    A: In this case you may want to buy a Code Signing certificate from a trusted CA like GoDaddy, Verisign, Entrust or other trusted CA on the market.

       The cost is around 250 US Dollars (check the prices...may vary..).

       When you start the buy process they will tell you how to create the request file to obtain the certificate. They will guide you through...no worries.

     

    Q: do you have some examples about PowerShell scripts about LANDesk?

     

    A:You can have a look in the community. I personally wrote a couple of them: http://community.landesk.com/support/docs/DOC-7248 about managing the LANDesk services and http://community.landesk.com/support/docs/DOC-22692 about snooping into the Windows Event log.