My “getting started” series ran out of steam a bit partly because I didn’t get much feedback on them — maybe you’re not interested, or maybe it wasn’t easy enough, or was just too confusing. In any case, I want to put up at least this one last post to suggest that you get the PowerShell Code Repository set up, and to show you the final version of my profile script and how it loads the various pieces it needs, and then I’ll send you on your way.

Once you’ve got your PowerShell all installed and have set up your first profile to auto-load … you’re going to want some scripts (well, maybe you’ll want to learn more about how to use PowerShell, but go with me on this)!

One of the best places to look for scripts is the PowerShell Code Repository, and although you can browse and search on the website, you can also do it using the PoshCode module (or the version 1 compatible script). These scripts include a Get-PoshCode cmdlet which you can use with search terms to get a list of scripts and cmdlets back, or with numeric IDs to download scripts (you’ll see what I mean later on, for now, go ahead and grab the appropriate version of that script).

I’m going to assume you put it into your AutoModules folder. If you grabbed the module, it should be saved to WindowsPowerShell\AutoModules\PoshCode\PoshCode.psm1 otherwise, to WindowsPowerShell\AutoModules\PoshCode.ps1 … but you may have run into a minor problem if you load the .ps1 version ). Both the module and the script are signed, but they are signed by my self-issued code signing certificate which your computer almost certainly doesn’t trust… You can use the signature to verify that the file hasn’t been modified since I signed it, but that’s about all (and even that’s a bit of a trick). To actually use the script (module), you’ll need to sign the script yourself (see the steps and how to get a certificate in part 2).

If you’re on CTP2, this would be a good time to get my Authenticode script module to help with signing, and to learn a little about those PoshCode cmdlets … (more…)

There’s been a lot of discussion on the #PowerShell IRC channel about code signing lately — mostly in response to my earlier posts (which I won’t link to here, because I should probably retract some of it after the discussions we’ve had). The discussion mostly revolves around how code signing applies to the PowerShell script repository and users’ ability to trust scripts that they download.

In order to keep the conversation going, and hopefully, include some of the Microsoft MVPs and PowerShell developers that don’t participate in the IRC channel at all, I’m going to post a summary of the conclusions we’ve drawn so far, and then outline a proposal for the repository.

In case you don’t know, PowerShell implements code-signing for scripts using x509 Certificates (basically, SSL certs with “Extended” use properties), but the signatures are just embedded in the script as a comment, much like PGP signatures in email. Depending on your settings, the engine will actually check the signature on a script before executing it, and refuse to execute it if the signature isn’t valid, for instance, if the script has been modified, or the certificate used to sign it can’t be traced to a trusted Certificate Authority.

PowerShell code-signing is inconvenient, and expensive. Scripts are only Valid if they are signed, unmodified, and the certificate traces back to a CA(Certificate Authority) that is in your Trusted Roots store (by default, basically, Microsoft’s, VeriSign, Thawte, and Comodo).

You can create your own “test” certificate (that is, one that you sign yourself), but scripts signed by that certificate will only work on that computer. This system works fine for large companies which typically have either a subscription for purchasing certificates, or their own in-house trusted CA, but not for small private developers or open source script sharing communities without financial motivation.

Because of this, to take advantage of PowerShell’s code-signing on your computer (that is, to set your ExecutionPolicy to “AllSigned” or “RemoteSigned”) you must do one of these things:

  1. Make sure that all script authors rent and use code-signing certs which cost more than $150 a year.
  2. Add a non-commercial root CA certificate (like CACert) to (all of) your computer(s), and offer your authors the option of going through the process of getting one of those instead.
  3. Create a “community” CA … and try to figure out how to make sure the certificate is secure enough to convince people to use it (yeah, ok, this was partly my idea, and it’s really a bad idea).
  4. Generate your own code-signing certificate (which can be self-signed) and just sign every script that you trust.

So far, it seems like that last option is the only one that’s going to fly, because although some developers are willing to buy certificates to sign software they’re going to sell … most scripters and sys-admins aren’t willing to buy one to share their certificates for free. (more…)

This continues a short series of posts about getting started with PowerShell … with a few tips about things you can do to keep your PowerShell profile safe and organized. Your “profile” is the script that is automatically loaded when you start up PowerShell. Really, I should say that your profile is the set of scripts which are loaded by default when you start up PowerShell. “By default” because you can always skip loading them by passing the -NoProfile switch to PowerShell.exe, and a set because PowerShell does, in fact, attempt to load at least four scripts when you run it:

PowerShell loads “machine” profile scripts (which are located in the PowerShell folder) and “user” profile scripts (located in your Documents\WindowsPowerShell folder). But there’s a little more to it than that: PowerShell is a scripting engine which can be hosted inside any app, PowerShell.exe is a DOS-style console which is the default host. There are several third-party hosts available such as PowerShell Plus and PowerGUI and several open source hosts such as BgShell and PoshConsole … in order to support this ecosystem of hosts, the default PowerShell behavior is to load a host-specific profile script (for both the machine settings and the local-user settings). Not all hosts will do that, but anyway … the default host loads Microsoft.PowerShell_profile.ps1 and Profile.ps1 from both the user and machine locations.

By default, none of those profiles actually exist. Once you’ve installed everything as in Part 1, you should have a Profile.ps1 file provided by PSCX. This profile defines a whole bunch of values that are used by various PSCX cmdlets and scripts, so you may want to change some of it, but you should be careful about just deleting things until you’re well acquainted with the PSCX cmdlets. Over time, I’ve added settings to my profile for other snapins as well, and there gets to be a lot of noise in there that’s specific to different snapins, so instead of just leaving all of that in my main profile, I rename the Profile.ps1 file provided by PSCX and then dot-source it from a new blank profile script.

In fact, and I found that I started collecting a lot of scripts in my WindowsPowerShell folder so I created a sub-folder for them, and I automatically load everything that’s in that folder, so I don’t have to manually dot-source things when I add a new snapin profile.

Authenticode Signing your auto-load scripts

In order to make sure that automatically loading scripts doesn’t become a way for people to attack my computer, I made a decision awhile ago that I would only auto-load signed scripts. The how and why of this is a bit much to get into, and I wrote about Generating Windows Authenticode Code-Signing Certificates with OpenSSL a while back, so you can read that if you want more details, I want to review the simplest steps. (more…)

One of the major security features of PowerShell is the support for code signing of scripts, so that you can set an execution policy that requires scripts to be signed before they can be run. Of course, it goes a bit further than that. When a script has been signed by a certificate with a root Certificate Authority (CA) that you don’t already “know” or trust it can’t be run at all until you add the root CA to the system’s certificate store.

Even after you trust a specific authority, you haven’t trusted a script author — so any signed script you run will prompt you whether you want to allow it or not, like so:

[19]: .\test-script.ps1

Do you want to run software from this untrusted publisher?
File C:\Users\Joel\Documents\WindowsPowerShell\test-script.ps1 is published by
E=NoUser@HuddledMasses.org, O=Huddled Masses, L=Rochester, S=New York, C=US
and is not trusted on your system. Only run scripts from trusted publishers.
[V] Never run [D] Do not run [R] Run once [A] Always run [?] Help (default is “D”):

The important thing to note here is that you’re really being asked not about the script, but about the author. If you choose the Never or Always options, the certificate that was used to sign the script is added to the appropriate certificate store (“Untrusted Certificates” or “Trusted Publishers”, respectively). To be clear: this happens for each every new author certificate, regardless of whether it’s signed by a self-signed cert (where you’ve already installed the root certificate in your root store) or a certificate issued by a commercial CA — there’s no loophole, no matter what anyone may have said in the past.

So, you see … the support for code signing is built into the core of PowerShell — and it’s really a shame not to take advantage of it. There are plenty of articles out there about how to sign your scripts, and more, so I’m not going to get into that much — I want to address the question of how hard it is to create the certificates in the first place (and finish by giving you a sample script which will generate and import them to your dev box with a single line command).

(more…)