Published Thursday, July 26, 2007 5:36 AM by martin

Writing your own commands for PowerShell

Anyone can write scripts that compose multiple PowerShell commands, but sometimes you want to create new functionality and expose it as a command inside PowerShell.  For example, you might decide that the administrative interface for your application is best exposed in this way.  How would you go about developing a new command...?

The MSDN documentation is here.  In short, you'll need the Windows SDK (which contains some PowerShell samples too), and you create a public class that inherits from Cmdlet.  Here's a ridiculously simple example...

    [Cmdlet(VerbsCommon.Get, "Hello")]
    public class Hello : Cmdlet
    {
        protected override void ProcessRecord()
        {
            WriteObject("Hello", false);
        }
    }

This is a command called Get-Hello and it simply returns the string "Hello".  Notice that I mark up my class with the Cmdlet attribute.  Commands in Powershell are all of the form verb-noun, and you can see that I'm provided with a set of verbs to choose from.  In my case I want VerbsCommon.Get.  To make this command available inside a shell, there are a couple of alternative approaches...

1. Build a new shell executable

In the Windows SDK, there's a tool called make-shell.  You can use this to create a new executable that launches PowerShell with certain specific configuration changes.  In particular, you can create a customized shell that has certain commands added to it.  Use the -reference option to specify the DLL that contains your cmdlet(s).

If you'll only ever want your commands to be available in a very constrained set of PowerShell instances, this is a valid approach.  On the other hand, if you want people to be able to install your commands for use in any PowerShell instance, you'd be better off building a snap-in...

2. Build a PowerShell snap-in

The more common approach is to build a snap-in.  Add a class to your project that inherits from PSSnapIn and mark up that class with [RunInstaller(true)].  Then you can use installutil.exe to install your snap-in.  When you've done that though, your commands aren't immediately available for use.

Inside a PowerShell window, you can execute Get-PSSnapIn -registered to find which snap-ins are registered and available on your machine.  You can then use Add-PSSnapIn to tell PowerShell to make the commands from a specific snap-in available inside your current shell.  Call Get-PSSnapIn with no parameters to find out which snap-ins are already available for use inside your current shell.

 

Whichever approach you choose, you build the commands in the same way.  To streamline the process of creating new commands, there is a set of VS2005 templates by David Aiken here.

So far I've said almost nothing about what you could or should do inside your command implementation.  It's a rich subject, which I'll leave for later posts.

 

Technorati tags:

Filed Under: