Writing PowerShell Cmdlets vs. Writing PowerShell Providers

A question that sometimes comes up is, "When do I write a PowerShell provider instead of a cmdlet?" To explain that, it is useful to understand how PowerShell distills management concepts for administrators.

In the pre-PowerShell world, the command-line management experience is fairly fractured. You have a huge number of awkwardly named commands, with no way to quickly determine what they mean. Many of them perform nearly identical actions, but have very different names. The image above illustrates a chaotic mix of commands that work primarily on files and directories.

The first approach that PowerShell uses to distill management concepts is to name commands with a Verb-Noun (Action, Item) pattern.

To make it easier for an administrator to learn the actions available for a new noun (such as Service or Process,) we provide strong guidance that verbs come from a standard set. The image above shows how you might name the earlier commands, while paying attention to the standardized verbs.

Now, what happens if you want to make these cmdlets work on the Registry?  How would you name them in that situation? Some of them apply exactly (but operate on a RegistryKey rather than a File,) some of them may not apply (such as the content of a registry key,) and some of them definitely do not apply (such as the list of running processes.)

Notice that some of the nouns share a lot in common, and converge to a few basic concepts. From the examples given above, you can perform actions on items, content, and locations.

The first set is clearly unmanageable, and makes life difficult for administrators.

The second set provides the main benefit of cmdlets. Consistent naming, and discoverability. Administrators can say, "I have a <Noun>, so already have a pretty good idea of what I can do with it."

The third set provides the main benefits of providers. For the major noun sets that we know about (items, content, properties, and navigation,) we make it as easy as possible for you to implement all related commands for that set. When you do, Administrators can say, "This provider supports navigation and items, so I already have a pretty good idea of what commands work with it."

So, if you want to support any of the major noun sets, you should write a provider.

As PowerShell matures, so should its list of provider types. For example, the *-Process cmdlets and *-Service cmdlets are strikingly familiar, and suggest the need for a standard lifecycle set of cmdlets.  It should also be noted that you can implement any or all of the standard provider types. For any that you implement, you get all related cmdlets for free.

[Edit: Resized images]

4 Responses to “Writing PowerShell Cmdlets vs. Writing PowerShell Providers”

  1. Maxim Mesilov writes:

    Old-style Windows scripting supports creating
    script-ActiveX (WSC). So I can write functions using VBScript or JScript, add special header to this textfile – and use it the same way
    as I use DLLs. Does MSH supports the same technology? How to create ActiveX using MSH-scripts and CMDLets?

  2. Lee writes:

    Hi Maxim;

    The .NET Framework comes with a utility that lets you create Com-Callable Wrappers (CCW) for managed code. It wouldn’t make must sense to call a cmdlet through COM, but you could definitely write in a language you are comfortable with (i.e.: C#) to make something accessible through COM.

  3. Maxim Mesilov writes:

    Thank you, Lee. More details:

    We have a domain controller, which is managed programmatically. In short, we have a table on MS SQL server, which consists of information about domain users accounts. When some changes are applied to this table, triggers call script-ActiveX written on JScript and stored in WSC-file (with common XML-header). Now we want to do the same but use MSH-script (with its powerful features) instead of JScript.

    There are a lot of articles in the Internet which describes the way to use external COM-objects from the MSH code. But it’s difficult to find information about how to prepare MSH-code for using it via ActiveX from applications i.e. T-SQL or ASP.

    We shall be very thankful if you point us to a howto.

  4. Lee writes:

    Maxim;

    Is this from SQL Server 2005? If it is, then you have a lot of options by hosting PowerShell. For example, see the following series of articles that demonstrates the technique:

    https://www.leeholmes.com/blog/MonadHostingAnIntroduction.aspx
    https://www.leeholmes.com/blog/MSHLogoOurDesignStrategy.aspx
    https://www.leeholmes.com/blog/MSHLogoAGUIDisaster.aspx
    https://www.leeholmes.com/blog/MSHLogoAllowingUsersToExtendItsFunctionality.aspx

    If this is an older version that doesn’t support interaction with the CLR, maybe you could write a "bridge" for a WSC file. Expose one method ("RunPowerShellScript") that will use VBScript to launch PowerShell this way:

    powershell.exe -command "& ‘scriptfile.ps1’"

    Lee

Leave a Reply