(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
0 comments