PowerShell Not Your Father’s Command Line Part 22 of 31: Good PowerShell Things Come in Nifty Packages

Have you found yourself writing PowerShell objects that you’d love to share with others? What’s the best way to get these things distributable? Well… with PowerShell 2.0, you have two different types of packaging – snap-ins and modules.


Snap-ins were available in PowerShell 1.0 and are still supported in PowerShell 2.0. In order for these to be used on a machine, they typically need to be installed first. Once the snap-in is installed on the machine, then it should be in a spot where PowerShell can see it. The best way to tell if it’s there is using the following command:

      Get-PSSnapIn -Registered

This will show all snap-ins that PowerShell can see, with the exception of those snap-ins that came with PowerShell. If the snap-in that you’ve installed doesn’t appear, then you may need to use the Installer Tool that comes with the .NET Framework to register the DLL.

Once the snap-in appears in the list, then you can bring it into the PowerShell session with the Add-PSSnapIn cmdlet. So let’s say you were installing the IIS 7.0 PowerShell snap-in,downloadable from IIS.net. Once the MSI file was run, the IIS snap-in should be installed on the computer. At this point, you should be able to run the following command:

   Add-PSSnapIn WebAdministration

While good things are already packaged in snap-ins, what if you have your own things to package in a snap-in? How do you create your own snap-in? MSDN covers this in depth.

You can also use the Import-Module cmdlet to bring in a snap-in into the PowerShell session. Tome Tanasovski covered this – including why you would choose Import-Module versus Add-PSSnapIn – in a Hey, Scripting Guy! blog post.


Modules are the newer, improved way of packaging PowerShell goodies for redistribution. Some of the goodies may include are providers, cmdlets, functions, scripts, dependent assemblies, and help files.

To see what modules are available on your machine, use the following command:

    Get-Module -ListAvailable

Unlike snap-ins, modules do not necessarily need to be installed. They need to have a certain folder structure and live within one of the directories listed in the PSModulePath environment varible.
To bring a module into your PowerShell session, use the Import-Module command. For example, if you downloaded the Windows Installer PowerShell module to use PowerShell to investigate MSI files, then you would import this module with the following command:

     Import-Module MSI

If you’re writing custom cmdlets in C#, then you’ll create a binary module – this is the DLL you create when you build your class library. If you’re writing scripts, simple functions, and advanced functions in PowerShell then you’ll create a script module, in the form of a .psm1 file. See my 4/26 presentation recap for my custom script module that is bundled with a module manifest, making it a manifest module.

The custom module that I had created shows the structure of a module, especially when help files are included. If you download the custom module, you’ll notice that the help files are simply text files. If I am redistributing a module, I typically go to the module’s folder and zip it at that level, so that the module just needs to be unzipped to one of the modules folders listed in the PSModulePath environment variable.

Matt and I have mentioned a variety of snap-ins and modules in our series so far, but there are plenty of others out there that may be useful for you. If you do a search in your favorite search engine for “PowerShell snap-in” or “PowerShell module”, you’ll be able to see what else is out there.

Seeing What’s In These Packages

While I explained how to import these snap-ins and modules into your PowerShell session, I didn’t tell you how to see what you get with them. Once your snap-in or module is in your PowerShell session, then you can use the following command to learn more about that module or snap-in:

     Get-Command -Module ModuleOrSnapInName

As always, Matt and I enjoy getting feedback on the series. If there’s something you want to see us cover, please get in touch with us. You can email me at sarah at codinggeekette dot com.

Get-ChooChoo -Type Chattanooga

I’ve recently found out that I’ve been selected to speak at devLink 2011. This is my 3rd year in a row speaking at devLink, and I’m incredibly honored to have been selected.

This year, I have 2 talks, and they are both on PowerShell! Tech editing and writing a PowerShell book really inspired me to continue to talk about it and get the word out. I used to spend a bit of time at the command prompt, and I love that I can bring .NET objects into a command prompt environment thanks to PowerShell.

My talks for devLink are:

Develop IT: Intro to PowerShell
This session is good for both developers and IT pros who want to get started with PowerShell but have not worked with it at all. In this session, we will look at the basics of PowerShell – from installation to grammar, aliases, piping, functions and profiles. We will use examples that are practical from both a developer’s point of view and from an IT professional’s point of view.

Develop IT: Extending PowerShell with Custom Cmdlets and Modules
This is the talk that debuted on 4/26 and will be custom tailored for devLink. PowerShell is a scripting language that takes advantage of working in a shell and being able to access .NET libraries. In this session, you will learn how you can write your own cmdlets to extend PowerShell to meet your business needs and distribute them in PowerShell 2.0, using your C# skills and Visual Studio 2010.

I hope to see some of you in Chattanooga at devLink 2011 this summer!

Extending PowerShell – Notes from my 4/26 Presentation

This past Tuesday, I was privileged to speak at the Cleveland C#/VB.NET SIG on extending PowerShell. Since I knew that my audience wasn’t necessarily familiar with PowerShell (except a few), I spent the first half of the session introducing PowerShell and many of its key concepts with the help of a custom module, built specifically for this presentation.

The only PowerPoint slides that were used were Sam’s slides to announce upcoming user group meetings, events, and sponsor information. Otherwise, I chose not to use PowerPoint and took a page from my friend Matt Casto‘s book, using a technology to present the technology. (He had done a presentation on Silverlight at a Central Ohio Day of .NET using a Silverlight app to show “slides”. I thought this was a cool technique and figured I could use PowerShell to explain PowerShell.)

The custom module is a manifest module, as I generated a PSD1 file for the module. However, if you remove the PSD1 file, the module is then considered to be a script module, as was covered in the talk.

To give you some background, my $profile has the following setup:

Set-Alias alias Set-Alias

function Get-Home{
    cd ~

$PSModulePath = $env:psmodulepath

I use the alias example because it irritates me to no end that there are some Linux commands that are already aliased, but the obvious alias alias was left out.

The function Get-Home is referenced in one of my help files. There’s a story behind this one. Again, this goes back to my Linux/Unix background. While Matt and I were working on the book, he had an example of a custom function that would get the user’s home directory. He used some long, convoluted path after the cd command. Of course, I had to come back and explain to him what the ~ meant, as I used to type cd ~ a lot when I spent time in the Unix labs on campus in my college days. It wouldn’t be until later on, as I was preparing for this talk, that I found the ~ explained in a PowerShell help file. (It’s in the help text for Resolve-Path.)

Finally, I included the $PSModulePath variable for two reasons. One, there’s improper documentation that this variable is a pre-defined variable. There are community comments that point out this flaw. The other reason is so that I can use the environment variables as a good segue into the providers topic.

I noted that I was not really going to get into covering creating custom providers, as there is a lot of detail behind that. However, if you want to talk providers, Oisin Grehan is a PowerShell provider master. He is also the guy behind the PowerShell Script Provider, to allow writing PowerShell providers in PowerShell scripting language and not necessarily in C#.

The other recommendation that was mentioned was to use the #PowerShell hashtag on Twitter, as there are many awesome PowerShell MVPs and notable people who work with it who are gratiously answering questions and helping as needed, providing direction for learning more on PowerShell.

You can download the custom ClevSIG2011 module here.

If you have PowerShell already installed, then here are the steps for using the module:
1. Extract the zip file into one of the Modules folders in $env:PSModulePath. Since this is unique to me, I put mine in my DocumentsWindowsPowerShellModules folder.
2. Start PowerShell (ISE or console).
3. Run the following command: Import-Module ClevSIG2011
4. Getting started with the module, run: Get-Help about_KeyTerms for more information.

The second half of my presentation involved creating custom cmdlets. In our book, I wrote about cmdlets to work with the Windows 7 Libraries feature – the feature that deals with Documents, Music, Video, Pictures, Contacts, and Downloads. The code that I used for that part will most likely be included in supplemental materials for our book. You can pre-order the Automating Microsoft® Windows Server 2008 R2 Administration with Windows® PowerShell 2.0 book through a variety of vendors.

I had a lot of fun presenting to such a lively crowd, and I especially enjoyed talking with others at Mavis Winkle’s afterwards! Thanks to all who came out for it!