May 28th, 2009

Adding Custom Cmdlet Help for Providers

PowerShell Team
PowerShell Team

A new feature of Windows PowerShell 2.0 lets you write custom cmdlet help for Windows PowerShell providers. This blog explains how to do it. (The topic will also be covered in excruciating detail in MSDN, but we don’t want you to wait.)

 

What’s a Provider?

A Windows PowerShell provider is a C# program that exposes a data store to Windows PowerShell through a Windows PowerShell drive (PSDrive). When users view the PSDrive, the data in the data store appears to be organized like a file system drive. The drive has a path and users can navigate through the data store by using file system navigation commands like CD and DIR.

For more information about designing a Windows PowerShell provider, see How to Create a Windows PowerShell Provider (http://go.microsoft.com/fwlink/?LinkID=152037).

If you’re a provider author (or the lucky writer), this feature is for you!

 

Custom cmdlets?

No, custom help topics for the provider cmdlets that your provider supports. Each provider supports a subset of the provider cmdlets that come with Windows PowerShell, such as Get-Item and Set-Location. You can find the complete list of provider cmdlets in about_Providers (http://go.microsoft.com/fwlink/?LinkID=113274).

A custom cmdlet help topic explains how the provider cmdlet works in your provider. You can specify different help files for different paths in your provider. And you can include examples of using the cmdlet in the paths of your provider drive.

 

How do users get custom cmdlet help?

When users are in a provider drive and they type “get-help” for a provider cmdlet, they get the custom cmdlet help for that provider (if it exists), instead of our generic cmdlet help topic.

C:\PS>  cd wsman:\localhost\ClientCertificate   

PS WSMAN:\localhost\ ClientCertificate>  get-help new-item

 

NAME

    New-Item

 

SYNOPSIS

    Creates a new item. In this location, the New-Item command creates a new client certificate.

 

 

 

Users can also get custom cmdlet help by using the (new) Path parameter of Get-Help. Set the value of Path to a location in the provider drive.

C:\PS>  get-help new-item -path wsman:\localhost\ClientCertificate

 

NAME

    New-Item

 

SYNOPSIS

    Creates a new item. In this location, the New-Item command creates a new client certificate.

 

 

 

What problem does this feature solve?

It solves a big problem and a small problem.

The small problem is that the help topics for the provider cmdlets are very generic. We couldn’t anticipate all of the ways that the cmdlets might be used in a provider drive, so we say correct, but not particularly useful, things like “gets the items in the drive.” Custom cmdlet help lets you say more useful things like “gets the files and folders ” or “gets the registry keys and entries.” More importantly, it lets you include examples of using the provider in your provider drive.

The big problem is that documentation of dynamic parameters is now too hard to find. Dynamic parameters that providers add to the provider cmdlets are described in the provider help topics. But because the dynamic parameters look just like the static ones, users don’t know where to look for parameter descriptions. It just looks like we forgot to doc a parameter.

(Guess where the Encoding parameter of Set-Content is documented? Yes, it’s in the FileSystem provider help topic.)

Custom cmdlet help allows us to document dynamic parameters along with the static parameters. For example, here’s the documentation of the Plugin and FileName parameters that the WSMAN provider adds to the New-Item cmdlet.

C:\PS>  cd wsman:\localhost\plugin

 

PS WSMan:\localhost\Plugin> get-help new-item -parameter *

 

-Plugin <string>

    Specifies the display name to use for the plug-in. If an error is returned by the plug-in, the display name

    will be put in the error XML that is returned to the client application. The name is not locale specific.

 

    Required?                    true

    Position?                    named

    Default value

    Accept pipeline input?       false

    Accept wildcard characters?  false

 

 

-FileName <string>

    Specifies the file name of the operations plug-in. Any environment variables that are put in this entry will

    be expanded in the users’ context when a request is received. Because each user could have a different version

    of the same environment variable, each user could have a different plug-in. This entry cannot be blank and must

    point to a valid plug-in.

 

    Required?                    true

    Position?                    named

    Default value

    Accept pipeline input?       false

    Accept wildcard characters?  false

 

 

 

How does it work?

When a user types “get-help” for a cmdlet, the help system gets the generic cmdlet help. But before returning it, it asks the provider if it wants to override the generic help. The provider should return null or it should return custom cmdlet help XML (for the MAML schema). If the provider returns cmdlet help, the help system merges the custom help with the generic help and returns it to the user.

Many providers have different objects in each path of their provider drive. To accommodate this variation, the custom cmdlet help design lets you write different help topics for each path of the drive. If your provider has the same objects in all paths, you can omit the path-specific elements of the custom cmdlet help design.

 

How do you do it?

Custom cmdlet help requires a few changes to the provider and to the provider help topic.

n  Provider Changes

The provider must implement the new ICmdletProviderSupportsHelp interface. Instructions are in MSDN (http://go.microsoft.com/fwlink/?LinkID=152386).

public interface ICmdletProviderSupportsHelp

{

    string GetHelpMaml(string cmdletName, string providerPath);

}

When Get-Help calls the GetHelpMaml() method for the provider with the cmdlet name and a friendly name for the provider path, the method returns the custom cmdlet help for that cmdlet help topic in the provider path. If the providerPath is null, GetHelpMaml() returns the first custom help topic that it finds for the specified cmdletName.

n  Help File Changes

To add custom cmdlet help to an XML-based help file (dll-help.xml), you imbed standard cmdlet help (MAML) in the provider help XML, with the help of a few new XML tags.

Conceptually, it looks like this:

<providerHelp>

    … # Provider Help Content 

 

    <CmdletHelpPaths>

 

        < CmdletHelpPath id=”providerPath“>

            <command:command>

                <command:details>

                    <command:name>

                             cmdletName

                    </command:name>

                  # Custom cmdlet help content …

            </command:command>

        </CmdletHelpPath>

 

    </CmdletHelpPaths>

 

</providerHelp>

 

New XML Tags

Many providers have different objects in each path of their provider drive. To accommodate this variation, the custom cmdlet help design lets you write different help topics for each path of the drive. If your provider has the same objects in all paths, you can omit the path-specific elements of the custom cmdlet help design.

There are two new XML tags for custom cmdlet help.

n  CmdletHelpPaths: Contains all custom cmdlet help topics (for all provider paths).

n  CmdletHelpPath: Contains the cmdlet help topics for a particular provider path. If your provider has the same objects in all paths, you need only one instance of this tag.

o   ID attribute: [Optional] Specifies a friendly name for the provider path. If you are not specifying multiple paths, omit the attribute or use an empty string as the value (“”).

 

Here’s the XML skeleton of a help file that includes provider help. We’ll use the WSMAN provider help file as an example.

<?xml version=”1.0″ encoding=”utf-8″ ?>

<helpItems schema=”maml”>

# Standard cmdlet help #

<providerHelp>

    <Name>

      WSMan

    </Name>

       # Standard provider help #

    </RelatedLinks>

 

    <CmdletHelpPaths> 

 

        <CmdletHelpPath ID=’ClientCertificate‘>

<command:command>

          <command:details>

               <command:name>

                  New-Item

               </command:name>

               … # Custom cmdlet help …

</command:command>

        </CmdletHelpPath>

 

       <CmdletHelpPath ID=’Listener‘>

<command:command>

          <command:details>

               <command:name>

                  New-Item

               </command:name>

               … # Custom cmdlet help …

</command:command>

        </CmdletHelpPath>

 

 

    </CmdletHelpPaths>

</providerHelp>

</helpItems>

 

 

 

Merged Help Content

To save you from having to rewrite an entire cmdlet help topic, the custom cmdlet help topic is actually a combination of the generic help topic and the elements that you add.

Some of the cmdlet help topic elements that you write replace the generic elements. Others are appended to the generic elements. The following table shows the rules. (You cannot change them.)

Notice that dynamic parameters appear before the static ones (they’re prepended), but your custom examples replace the generic examples in the help file and your custom descriptions of static parameters replace the generic parameter descriptions.

Field

Action

Name

None

Synopsis

Replace

Syntax

Append

Detailed Description

Append

Parameters

Prepend

Parameter Description

Replace

Input Type

Replace

Return Type

Replace

Notes

Append

Examples

Replace

Related Links

Replace

Remarks

None

Role

Replace

Functionality

Replace

Component

Replace

 

Okay, JuneB, where are yours?

If custom cmdlet help is such a great idea, then where is the custom cmdlet help for the core providers, such as FileSystem, Registry, and Certificate?

Well, let’s just say that we were really busy. The core providers have not yet implemented the ICmdletProviderSupportsHelp interface, so we can’t display custom cmdlet help. But we’ll be working on it for a future release of Windows PowerShell.

In the meantime, feel free to ask questions. You can submit them by adding comments to this blog and I’ll update with answers if necessary.

 

June Blender [MSFT]
juneb@microsoft.com
Get-Help -online:  http://technet.microsoft.com/en-us/library/bb978525.aspx

Author

PowerShell Team
PowerShell Team

PowerShell is a task-based command-line shell and scripting language built on .NET. PowerShell helps system administrators and power-users rapidly automate tasks that manage operating systems (Linux, macOS, and Windows) and processes.

0 comments

Discussion are closed.