Huddled Masses
You can do more than breathe for free...
Browse: Home / Getting Started with PowerShell 2 – Part 2

Getting Started with PowerShell 2 – Part 2

By Joel 'Jaykul' Bennett on 30-Jun-2008

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.

[new] Edit: I should take a moment here to point out, in case you’re really new to PowerShell, that the first thing you’ll have to do is fix the error “File … cannot be loaded because the execution of scripts is disabled on this system.” I originally was just assuming you would have figured that out — it tells you to read the about_signing help, so you can just execute get-help about_signing and it explains in there what you need to do. In case you haven’t gotten that far, before you can execute the New-CodeSigningCert you’re going to need to run PowerShell as administrator (“elevated”) and execute this command: Set-ExecutionPolicy RemoteSigned … that will let you execute most scripts that you have saved locally without having signed them. You may want to tighten that up later and set it to “AllSigned,” but first you have to be able to sign scripts.

Generating a code-signing certificate

[new] Edit: I’ve simplified this a bit, and modified the script to import the certificate to the Current User certificate store if you aren’t running in an elevated console (in Vista) — which should work fine if you’re the only user on your machine that needs to run the scripts — if you need them in the Local Machine store, you need to be running as administrator. The script will let you know which it does, so you’ll know, one way or another.

Step 1. Download my PoshCerts package and unpack it in your WindowsPowerShell folder — lets say in, WindowsPowerShell\PoshCerts\bin.

Step 2. Run the New-CodeSigningCert script to generate into the Certs folder. So if you’re in the WindowsPowerShell directory, you can just run it and you’ll be prompted for a few pieces of information that the certificates require, plus two passwords — and all of the keys will be generated into the Certs folder as files, and imported to your local store. Make sure you make a note of those passwords.


cd (Split-Path $Profile)\PoshCerts\
.\bin\New-CodeSigningCert.ps1 $pwd "[Your Name]" "[Your Email]" -ImportAll

[new] Edit: I came up with a Step 3. Under most circumstances (that is, unless you were planning on running a corporate Certificate Authority), you’ll have no further use for the CA certificate, If you want to make sure that nobody can abuse your root CA … you can and should just delete the private certificates, like so: Remove-Item *Root-CA.* -exclude *.crt

Signing Scripts

You can now sign scripts at will using the pfx file generated in step 2 with the Get-PfxCertificate cmdlet, or the Cert: provider (you have use -ImportAll when you call New-CodeSigningCert, not just -Import — that causes the import of your code-signing certificate to the “My” store … then you can do Get-ChildItem "Cert:\CurrentUser\My\$thumbprint" where $thumbprint is your certificate’s thumbprint).

Let’s rename our Profile.ps1 script and then sign it. We’ll create create a folder called “AutoModules” to stick your PSCX profile (and any future such scripts) in. If you’re still on PowerShell 1, you’ll just put the .ps1 files into that folder, and we’ll dot-source them.


cd (Split-Path $Profile)
mkdir AutoModules
# Sign it (you'll reuse this exact code in a moment)
Set-AuthenticodeSignature -Cert (
    # You'll be prompted for your code-signing cert password here:
    Get-PfxCertificate .\PoshCerts\*Code-Signing.pfx
    ) .\Profile.ps1
# Now move it (the signature doesn't care about the file name).
mv .\Profile.ps1 .\AutoModules\PSCX.ps1
 

[new] Edit: The simplest

Checking for valid signatures

Once you’ve got that set up, we need to create the new profile script and modify it to load not just the PSCX module, but any other signed scripts we put in there. Paste this into your new Profile.ps1, and don’t forget to sign it.


$ProfileDir = Split-Path $MyInvocation.MyCommand.Path

## If we're on version two, we need to set the PsPackagePath (it doesn't hurt anything anyway)
$ENV:PSPACKAGEPATH = "$ProfileDir\AutoModules"

## Now, preload any script in AutoModules that is signed ...
##### Problem 1:  There's a bug which prevents signing or checking psm1 files
##### I'll show you how to work around that in Part 3
##### For now you don't have any, so this is quite simple:
Get-ChildItem $ProfileDir\AutoModules\* -include *.ps1 -recurse |
   Get-AuthenticodeSignature |
   Where-Object {$_.Status -eq "Valid"} |
   Get-ChildItem | &{ PROCESS {
      switch -regex ($_) {
         ".*\.ps1$"    { . $_.FullName; Write-Verbose "Loaded $_" }
         ".*\.ps1xml$" { Update-TypeData -PrependPath $_.FullName  }
         default        { Write-Verbose "Not sure what to do with: $($_.Name)" }
      }
   } }

If you’re testing PowerShell 2, you’ll want to treat these scripts as Modules … SnapIns themselves can be loaded as modules in PowerShell 2, but so can any script which needs to be dot-sourced. In this case, the easiest thing is to create a subfolder for each one and then use Add-Module with the folder name. There are some problems with that, which I’ll go into in “Part 3”:http://huddledmasses.org/getting-started-with-powershell-2-part-3/.

Similar Posts:

  • Working with multiple versions of PowerShell Modules
  • PowerShell Scripting Best Practices: Prefix A
  • How to Import Binary Modules from Network Shares
  • Rich formatting for PowerShell help
  • PowerShell 3 – Finally on the DLR!

Posted in Huddled | Tagged CodeSigning, GettingStarted, Modules, PowerShell, WalkThrough

« Previous Next »

Lijit Search

Tags

.Net .Net 2008 Scripting Games Automation Bugs Design Development Funny Gadgets GeoShell GUI Huddled Masses Internet licensing Microsoft Modules My Software News Personal PInvoke Pipeline Politics PoshCode PoshConsole PowerBoots PowerShell PowerShell Functions PowerTips Rants Recommender Repository Scripting ShowUI Software Solutions Textile Tips User Group UserInterface WalkThrough WebHosting Windows 7 WordPress WPF Xml

About Huddled Masses

This is web site is dedicated to the musings of Joel Bennett (aka Jaykul) about technology, software, software development, the web, and the world.

Any resemblance of the views expressed and the views of my employer, my terminal, or the view out my window are purely coincidental. The resemblance between them and my own views is non-deterministic. The question of the existence of views in the absence of anyone to hold them is left as an exercise for the reader.

P.S.: I occasionally link to things I think are great. When I do, I occasionally find a "referral code" so I can make a little cash. I promise that I don't link to anything just because of that cash (I wouldn't cross the street for the amount of cash those links bring in, never mind write a whole blog post) ... but I do not promise that things I link to will stay great as time passes, nor that you will agree with me about their greatness!

Archives

  • January 2012
  • October 2011
  • August 2011
  • July 2011
  • June 2011
  • March 2011
  • February 2011
  • January 2011
  • November 2010
  • August 2010

Copyright © 2012 Joel Bennett.

Powered by WordPress and Hybrid.