Writing XML Help for Advanced Functions
- Details
- Written by June Blender
- Last Updated: 28 September 2016
- Created: 01 April 2015
- Hits: 20649
SAPIEN's PowerShell HelpWriter has made writing XML help files as easy – actually easier – than writing comment-based help. XML help is more robust and less error-prone than comment-based help. It supports updatable help and help in multiple languages, and it lets you separate help files from script and modules files, which is a real advantage when you’re working with many people in a shared coding environment, like GitHub.
PowerShell HelpWriter makes it easy to create XML help files for all commands in a module, including the functions in a manifest module or script module: just click New/New Help File (from Module). But, you’re not quite done. It takes a few more steps to associate a function with the XML help file.
Tested On: PowerShell 3.0, 4.0, 5.0, 5.1, 6.0.0.9, 6.0.0.10
What do I name the XML help file?
You need to give your XML help file a name that Get-Help expects. Otherwise, Get-Help won’t find your help file. Instead, it displays only auto-generated help.
In Windows PowerShell 3.0, the XML help files for cmdlets, providers, and CIM commands must be named for the file in which the commands are defined.
The name syntax is:
<SourceFileName>-help.xml
For example:
MyModule.dll-help.xml
There are no requirements for the names of function help files, but, as a best practice, they are usually named for the .psm1 file in which they are defined plus “-help.xml”.
The best practice syntax is:
<FunctionSourceFileName>-help.xml
For example:
MyModule.psm1-help.xml
But, this best practice isn’t required. If your module includes cmdlets, providers, workflows, and/or CIM commands, along with functions, it’s sometimes easier to add the XML help topics for functions to the existing help file. For example, if you have a cmdlet/provider help file called MyModule.dll-help.xml, you can add your function help topics to that XML help file.
For modules that run only in Windows PowerShell 4.0 and later, you can put XML files for all command types in one file that is named for the module. This technique is much easier for the help author to maintain, but Get-Help on Windows PowerShell 3.0 and earlier will not find help for commands in a module with this naming technique.
The name syntax is:
<ModuleName>-help.xml
For example:
MyModule-help.xml
For information about naming Windows PowerShell help files, see Naming Help Files.
Where do I put the XML help file?
Get-Help looks for the XML help file in the root of the module directory and in language-specific sub-directories of the module directory. If it can’t find the XML help file, Get-Help searches in sub-directories of the module directory, but this is a risky strategy that doesn’t work for all module types.
You have two options for placing an XML help file:
- In the module directory, that is, the value of the ModuleBase property of your module. For example, if the module directory of MyModule is:
PS C:> (Get-Module MyModule –ListAvailable).ModuleBase $home\Documents\WindowsPowerShell\Modules\MyModule
You can place the XML help file for commands in my module here:
$home\Documents\WindowsPowerShell\Modules\MyModule\MyModule.psm1-help.xml
- In a language-specific sub-directory of the module directory. This is the preferred location, because it lets you support help topics in multiple languages. Even if you have help in only one language today, a friend or colleague might translate your help for you in the future. For example, you can place the US English XML help files for commands in my module in the en-US subdirectory:
$home\Documents\WindowsPowerShell\Modules\MyModule\en-US\MyModule.psm1-help.xml
Special for functions: # .ExternalHelp
Because Get-Help doesn’t have any naming standards for XML help files for functions, you need to tell it where to find the help for a function. To associate a function with the XML help file that contains its help topic, use the .ExternalHelp comment keyword (for details, see about_Comment_Based_Help).
The value of the .ExternalHelp comment keyword is the name of the help file that contains the help topic. Do not include any variables in the file name; they will be interpreted as literals. Also, do not specify a path. Get-Help looks for the help file in the module directory, language-specific sub-directory of the module directory, or (risky) other sub-directories of the module directory.
For example, this ExternalHelp comment tells Get-Help that the help topic for MyFunction is in the MyModule.psm1-help.xml file.
# .ExternalHelp MyModule.psm1-help.xml
function MyFunction {...}
It's comment-based help, so you can put the .ExternalHelp comment in any position in which comment-based help is valid, like this one.
function MyFunction {
# .ExternalHelp MyModule.psm1-help.xml
... }
Be really careful here. The syntax is critical. If you have any syntax errors, Get-Help ignores the entire comment-based help block. For example, if the help file name is on the line below the ExternalHelp keyword, the keyword is ignored.
When is .ExternalHelp required?
- Windows PowerShell 3.0, ExternalHelp is required. Get-Help requires the ExternalHelp comment keyword to associate functions with an XML help file. Without ExternalHelp, Get-Help in PowerShell 3.0 will not find help for a function in an XML help file.
- Windows PowerShell 4.0 and later, ExternalHelp is required only when BOTH are true:
- Module is a script module, not a manifest module.
-AND- - Help file is named for the source file, not for the module. That is, the help file name is MyModule.psm1-help.xml, not MyModule-help.xml.
- Module is a script module, not a manifest module.
To be safe (and backwards compatible), I add the .ExternalHelp comment keyword to every function that has an XML help file. The keyword also reminds me that the function has XML help so I don’t write comment-based help for it by mistake.
Precedence and XML Help
Just a quick word about precedence.
When a function has both comment-based help and an XML help file, Get-Help displays the comment-based help. But, if the comment-based help includes an ExternalHelp keyword, Get-Help ignores the comment-based help content and displays the XML help.
In fact, if the ExternalHelp keyword is present, Get-Help ignores the rest of comment-based help, even if it cannot find an XML help file that matches the value of the ExternalHelp keyword. Instead, it displays auto-generated help.
Also, if the comment-based help is invalid for any reason, like a typo in a comment keyword name, Get-Help ignores the comment-based help. For manifest modules, it gets XML help, if it exists, or displays auto-generated help. For script modules, it displays auto-generated help.
When writing a function, select comment-based help (x)or XML help. Including both is inviting errors. They’re bound to get out of sync and you’ll struggle to figure out why a new example isn’t displaying, only to find that you added the example to the format that isn’t being displayed.
Testing XML Help
To test an XML help file for a function, use Get-Help. When the module and the help are in the right place with the right name, Get-Help should find the help topic for the function even when the module is not imported into the session.
If you find an error, you can view the raw XML. A single function help topic consists of all content and elements within the <command:command> elements in the XML file.
To get the help topics in an XML help file, use the XML accelerator and the Get-Content cmdlet. For example, this command gets the help topics in Bitlocker.psm1-help.xml, the XML help file for the Bitlocker module.
[xml]$xml = Get-Content -Path $pshome\modules\Bitlocker\en-us\BitLocker.psm1-help.xml
To verify that a help topic is in the file, get the topic names. This command gets the names of topic in the Bitlocker.psm1-help.xml file.
PS C:\> $xml.HelpItems.command.Details.Name Add-BitLockerKeyProtector Backup-BitLockerKeyProtector Clear-BitLockerAutoUnlock Disable-BitLocker Disable-BitLockerAutoUnlock Enable-BitLocker Enable-BitLockerAutoUnlock Get-BitLockerVolume Lock-BitLocker Remove-BitLockerKeyProtector Resume-BitLocker Suspend-BitLocker Unlock-BitLocker
You can also examine the XML help topic in the raw XML. This command gets the help topic for the Disable-Bitlocker function and saves it in the $disableBitlocker variable.
PS C:\> $disableBitlocker = $xml.helpItems.command | where {$_.details.Name -eq "Disable-Bitlocker"}
Now, you can get the details, like the related links:
PS C:\ps-test> $disableBitlocker.relatedLinks.navigationLink linkText uri -------- --- Online Version: http://go.microsoft.com/fwlink/?linkid=287650 Enable-BitLocker Lock-BitLocker Resume-BitLocker Suspend-BitLocker Unlock-BitLocker Get-BitLockerVolume
This command verifies that each function help topic has an online version link. It returns a custom object with the name and online version URI for each help topic.
PS C:\> $xml.helpItems.command | Select-Object @{Label ="Name"; Expression ={$_.Details.Name}}, @{Label="OnlineLink"; Expression={($_.relatedLinks.NavigationLink | where LinkText -eq "Online Version:").uri}} Name OnlineLink ---- ---------- Add-BitLockerKeyProtector http://go.microsoft.com/fwlink/?linkid=287647 Backup-BitLockerKeyProtector http://go.microsoft.com/fwlink/?linkid=287648 Clear-BitLockerAutoUnlock http://go.microsoft.com/fwlink/?linkid=287649 Disable-BitLocker http://go.microsoft.com/fwlink/?linkid=287650 Disable-BitLockerAutoUnlock http://go.microsoft.com/fwlink/?linkid=287651 Enable-BitLocker http://go.microsoft.com/fwlink/?linkid=287652 Enable-BitLockerAutoUnlock http://go.microsoft.com/fwlink/?linkid=287653 Get-BitLockerVolume http://go.microsoft.com/fwlink/?linkid=287654 Lock-BitLocker http://go.microsoft.com/fwlink/?linkid=287655 Remove-BitLockerKeyProtector http://go.microsoft.com/fwlink/?linkid=287656 Resume-BitLocker http://go.microsoft.com/fwlink/?linkid=287657 Suspend-BitLocker http://go.microsoft.com/fwlink/?linkid=287658 Unlock-BitLocker http://go.microsoft.com/fwlink/?linkid=287659
I hope this helps. If you have a question about Windows PowerShell Help, post it in the Windows PowerShell forum or tweet it to me at @juneb_get_help. If you have a question about PowerShell HelpWriter, post it in the PowerShell HelpWriter forum or, for trial users, the Trial Software Questions forum.
June Blender is a technology evangelist at SAPIEN Technologies, Inc. and a Microsoft Cloud & DataCenter MVP. You can reach her at This email address is being protected from spambots. You need JavaScript enabled to view it. or follow her on Twitter at @juneb_get_help.
For licensed customers, use the forum associated with your product in our Product Support Forums for Registered Customers.
For users of trial versions, please post in our Former and Future Customers - Questions forum.