July 16th, 2007

Get-Help Can't Find My Help File!

PowerShell Team
PowerShell Team

(or How to Define the Help File Name in a Custom Windows PowerShell Snap-in)

 

We’ve discovered an error in our instructions for creating a custom Windows PowerShell snap-in. This error prevents Get-Help from finding the help files for cmdlets in the snap-in. We’d like to come clean about our mistake and to warn you about the effects of copying it.

 

This error also revealed that custom snap-in developers determine the names of the help files for their cmdlets. As such, we need to revise our previous instructions for naming help files, because they apply only to standard snap-ins.

 

 

The Bug:

 

Where?  In the Write a Custom Windows PowerShell Snap-in topic of the Windows PowerShell Programmer’s Guide.

 

In a custom snap-in, you use a CmdletConfigurationEntry constructor to specify the cmdlets in the snap-in. The constructor has three parameters, and the third parameter defines the name of the help file for the cmdlets in the snap-in.

 

However, in our example, we show a null value for the third parameter. This is incorrect. If the value is null, no help file name is defined, the value of the HelpFile property of CmdletInfo objects (the ones generated by Get-Command) is null, and Get-Help will not find a help file for the cmdlets.

 

/// <summary>

  /// Specify the cmdlets that belong to this custom PowerShell snap-in.

  /// </summary>

  private Collection<CmdletConfigurationEntry> _cmdlets;

  public override Collection<CmdletConfigurationEntry> Cmdlets

  {

    get

    {

      if (_cmdlets == null)

      {

        _cmdlets = new Collection<CmdletConfigurationEntry>();

        _cmdlets.Add(new CmdletConfigurationEntry(“test-customsnapintest”, typeof(TestCustomSnapinTest), null));

        _cmdlets.Add(new CmdletConfigurationEntry(“test-helloworld”, typeof(TestHelloWorld), null));

      }

 

      return _cmdlets;

    }

  }

 

 

The value of the third parameter should be the name of the help file. By convention, the name of the help file for a PowerShell snap-in is the name of the snap-in DLL with a dll-help.xml file name extension. When you create a standard Windows PowerShell snap-in, the name is created for you in this format.

 

For example, if the sample snap-in is CustomPSSnapinTest.dll, the help file name should be CustomPSSnapinTest.dll-help.xml, as shown in the corrected example below. Please note that the file name appears within quotation marks.

 

/// <summary>

  /// Specify the cmdlets that belong to this custom PowerShell snap-in.

  /// </summary>

  private Collection<CmdletConfigurationEntry> _cmdlets;

  public override Collection<CmdletConfigurationEntry> Cmdlets

  {

    get

    {

      if (_cmdlets == null)

      {

        _cmdlets = new Collection<CmdletConfigurationEntry>();

        _cmdlets.Add(new CmdletConfigurationEntry(“test-customsnapintest”, typeof(TestCustomSnapinTest),“CustomPsSnapinTest.dll-help.xml”));

        _cmdlets.Add(new CmdletConfigurationEntry(“test-helloworld”, typeof(TestHelloWorld),“CustomPsSnapinTest.dll-help.xml”));

      }

 

      return _cmdlets;

    }

  }

 

 

 

 

The Symptoms:

 

When the third parameter of the CmdletConfigurationEntry constructor is null, Get-Help cannot find the help file for the cmdlets, and (the smoking gun!) the value of the HelpFile property of the CmdletInfo object generated by Get-Command is not populated.

 

The following example shows that the HelpFile property of affected CmdletInfo objects is blank ($null). The example uses the Get-Command cmdlet to get the first cmdlet in the snap-in. The resulting CmdletInfo object is piped to Format-List (with a value of * for -property) to show the values of all properties of the object.

 

PS C:\> (get-command -pssnapin test*)[0] | fl *

 

 

DLL              : c:\program files\cmdlets\testpowershell.dll

Verb             : Copy

Noun             : Thing

HelpFile         :

PSSnapIn         : TestPowerShellSnapIn

ImplementingType : Microsoft.Test.PowerShell.Commands.CopyThing

ParameterSets    : {__AllParameterSets}

Definition       : Copy-Thing [-thingname <String>]

Name             : Copy-Thing

CommandType      : Cmdlet

 

And the return from Get-Help is as expected. Get-Help cannot find a help file for the cmdlet, even though a help file with the correct DLL-based name was installed in the same directory as the DLL.

 

PS C:\> get-help copy-thing

Get-Help : Cannot find Help for topic “copy-thing”.

At line:1 char:9

+ get-help <<<<  copy-thing

 

 

The Scope:

 

This issue only affect Windows PowerShell custom snap-ins. When you create a standard snap-in, the help file names for the cmdlets are defined correctly for you.

 

 

Discussion:

 

We will fix our custom snap-in doc errors, but we also need to qualify the instructions for naming actual help files.

 

We recommend that custom snap-in developers follow the help file naming guidelines established for Windows PowerShell; the ones that are applied to standard snap-ins by default. However, we do not enforce it. And while we understand completely why you might want to name your help file “PowerShellRocks.xml”, we must warn you that non-conforming names will create problems for help authors and, potentially, for users.

 

The new help file naming instructions will include something like this:

 

The names of cmdlet help files for Windows PowerShell snap-ins must match the value of the HelpFile property of the cmdlets in the snap-in.” To find this name, register the snap-in, add it to your console, and type the following command at the Windows PowerShell prompt:

 

            get-command -pssnapin <snapin-name> | format-table name, helpfile

 

 

For example:

 

       get-command -pssnapin *security* | format-table name, helpfile

 

 

Name                      HelpFile

—-                      ——–

ConvertFrom-SecureString  Microsoft.PowerShell.Security.dll-Help.xml

ConvertTo-SecureString    Microsoft.PowerShell.Security.dll-Help.xml

Get-Acl                   Microsoft.PowerShell.Security.dll-Help.xml

Get-AuthenticodeSignature Microsoft.PowerShell.Security.dll-Help.xml

Get-Credential            Microsoft.PowerShell.Security.dll-Help.xml

Get-ExecutionPolicy       Microsoft.PowerShell.Security.dll-Help.xml

Get-PfxCertificate        Microsoft.PowerShell.Security.dll-Help.xml

Set-Acl                   Microsoft.PowerShell.Security.dll-Help.xml

Set-AuthenticodeSignature Microsoft.PowerShell.Security.dll-Help.xml

Set-ExecutionPolicy       Microsoft.PowerShell.Security.dll-Help.xml

 

 

And if, by chance, the value of HelpFile is $null, check the custom snap-in code for errors.

 

This method will work for standard snap-ins, too, but help file authors can reliably assume that the help file will match the DLL name, but have a dll-help.xml file name extension.

 

June Blender [MSFT]

Windows PowerShell Documentation

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.