Introduction
Having good help is vital to the construction of a module. It explains not only how to use a function, but the purpose of the module and even more.
Naturally I’ve included good help text in the ArcaneBooks module, but as I was going over the construction of the ArcaneBooks module I realized I’d not written about how to write help in PowerShell. So in this post and the next I’ll address this very topic.
Two Types of Help
There are two ways of creating help for functions in PowerShell modules. The newer method is to create XML files with the help text. I’ll be honest, I’m not a big fan of this method.
The XML is more difficult to author and read in plain text format as the help is surrounded by XML tags. To be able to effectively author it a third party tool is needed.
There is one advantage to the XML format, if you wish to internationalize your module you can write individual XML help files for each language you need. These can all be bundled with your module. In my case I’m only going to use English, so this isn’t of benefit to my ArcaneBooks module.
I’ll admit that I may be a bit old fashioned, but I still prefer the original comment based help when authoring help. It keeps the help text with the function, and is easier to read when looking at the raw code.
Comment Blocks
As its name implies, comment based help is created by placing specially crafted comment blocks beside the function declarations of the functions in your module.
As you may know, a normal comment in PowerShell begins with a #
, commonly called a pound sign or hash tag. Some examples:
# This is a comment
$x = 1 # Set X equal to 1
A comment block allows you to create comments that are multiple lines. They begin with a <#
and end with #>
. An example would be:
<#
Here is a comment block
More text here
#>
You can add text after and before the #
characters. I often use these to creeate dividers in my code.
<#-----------------------------------------------
Do some interesting stuff in this section
-----------------------------------------------#>
I’ll dive a bit deeper into the structure of the comment help block, but first lets talk about placement.
Placement of Comment Help
To associate a help block with a function, it needs to be positioned right before or right after the function declaration.
<#
Comment based help here
#>
function DoSomething()
function DoSomething()
<#
Comment based help here
#>
$x = 1
Either of these are valid, but I much prefer the first version. It keeps the function declaration close to its code.
Contents of Comment Based Help
There is a defined template of what needs to be in comment based help.
<#
.SYNOPSIS
A short one liner that describes the function
.DESCRIPTION
Detailed description of the function
.PARAMETER ParamName
Information about the parameter.
Add additional .PARAMETER tags for more parameters
.INPUTS
What inputs are allowed, useful for when a function allows input to be piped in.
.OUTPUTS
Explanation of what the function outputs.
Can also include sample data
.EXAMPLE
Code example
.EXAMPLE
Additional examples, just add more .EXAMPLE tags as needed
.NOTES
Notes here like author name
.LINK
Link to online help
.LINK
Additional link(s)
#>
As you can see, it uses a series of tags to describe what is in the section. Each tag is preceded by a period.
The SYNOPSIS
and DESCRIPTION
are both required. In the synopsis you place a short description of the function. One, no more than two sentences go here.
In the description you can place an expanded explanation of the function. You can go into detail of its purpose. It doesn’t need to be a novel, but two to three paragraphs are not uncommon.
Next comes the parameters. Each parameter should be listed individually, getting a PARAMETER
tag followed by the name of the parameter. In the accompanying text you can include details to the nature of the parameter, whether it is required, and if appropriate the data type.
Again, you should include one parameter tag for each of your functions parameters.
In the INPUTS
area you can give an overall description of the data that will be input to the function. It is also a good place to describe data that can be input to the function through the pipeline.
The OUTPUTS
is the place to describe what data is returned from the function. This may be a single value, or an object with multiple values. When returning an object I like to list each property along with a sample value for each.
You should include at least one EXAMPLE
section in your help. Include a small code sample of calling your function.
It’s a good idea though to include multiple example sections. For instance, if your function allows for input through the pipeline, have one example for passing data in normally, than a second for using the pipeline. Include as many as you need to give the reader a good set of examples on how to use your function.
NOTES
is for just what it says, an area to include any additional notes about the function. In here I often include information such as the author name, copyright notices, and any other information I’d like to have included.
Finally is the LINK
section. If you have online help, the first link tag should point to the online help web address that will be used with the -Online
switch of the Get-Help
cmdlet. You can include as many links as needed, I usually include at least one more pointing to the project website, such as a github site, or back to my own blog.
A Real World Example
Here is a real world example from the ArcaneBooks project I’ve been developing. This is the help for the Get-ISBNBookData
function.
<#
.SYNOPSIS
Gets book data from OpenLibrary.org based on the ISBN
.DESCRIPTION
Uses the more advanced API at OpenLibrary to retrieved detailed information
based on the 10 or 13 character ISBN passed in.
.PARAMETER ISBN
A 10 or 13 digit ISBN number. The passed in value can have spaces or dashes,
it will remove them before processing the request to get the book data.
.INPUTS
Via the pipeline this cmdlet can accept an array of ISBN values.
.OUTPUTS
The cmdlet returns one or more objects of type Class ISBNBook with the
following properties. Note that not all properties may be present, it
depends on what data the publisher provided.
ISBN | The ISBN number that was passed in, complete with an formatting
ISBN10 | ISBN as 10 digits
ISBN13 | ISBN in 13 digit format
Title | The title of the book
LCCN | Library of Congress Catalog Number
Author | The author(s) of the book
ByStatement | The written by statement provided by the publisher
NumberOfPages | Number of pages in the book
Publishers | The Publisher(s) of this book
PublishDate | The publication date for this edition of the book
PublisherLocation | The location of the publisher
Subject | Generic subject(s) for the work
LibraryOfCongressClassification | Specialized classification used by Library of Congress
DeweyDecimalClass | Dewey Decimal number
Notes | Any additional information provided by the publisher
CoverUrlSmall | URL link to an image of the book cover, in a small size
CoverUrlMedium | URL link to an image of the book cover, in a medium size
CoverUrlLarge | URL link to an image of the book cover, in a large size
.EXAMPLE
# Pass in a single ISBN as a parameter
$ISBN = '0-87259-481-5'
$bookData = Get-ISBNBookData -ISBN $ISBN
$bookData
.EXAMPLE
# Pipe in a single ISBN
$ISBN = '0-87259-481-5'
$bookData = $ISBN | Get-ISBNBookData
$bookData
.EXAMPLE
# Pipe in an array of ISBNs
$ISBNs = @( '0-87259-481-5'
, '0-8306-7801-8'
, '0-8306-6801-2'
, '0-672-21874-7'
, '0-07-830973-5'
, '978-1418065805'
, '1418065803'
, '978-0-9890350-5-7'
, '1-887736-06-9'
, '0-914126-02-4'
, '978-1-4842-5930-6'
)
$bookData = $ISBNs | Get-ISBNBookData -Verbose
$bookData
$bookData | Select-Object -Property ISBN, Title
.NOTES
ArcaneBooks - Get-ISBNBookData.ps1
Author: Robert C Cain | @ArcaneCode | arcane@arcanetc.com
This code is Copyright (c) 2023 Robert C Cain All rights reserved
The code herein is for demonstration purposes.
No warranty or guarantee is implied or expressly granted.
This module may not be reproduced in whole or in part without
the express written consent of the author.
.LINK
https://github.com/arcanecode/ArcaneBooks/blob/1ebe781951f1a7fdf19bb6731487a74fa12ad08b/ArcaneBooks/Help/Get-ISBNBookData.md
.LINK
http://arcanecode.me
#>
When I use the command Get-Help Get-ISBNBookData -Full
this is the output.
SYNTAX
Get-ISBNBookData [-ISBN] <String> [<CommonParameters>]
DESCRIPTION
Uses the more advanced API at OpenLibrary to retrieved detailed information
based on the 10 or 13 character ISBN passed in.
PARAMETERS
-ISBN <String>
A 10 or 13 digit ISBN number. The passed in value can have spaces or dashes,
it will remove them before processing the request to get the book data.
Required? true
Position? 1
Default value
Accept pipeline input? true (ByValue)
Accept wildcard characters? false
<CommonParameters>
This cmdlet supports the common parameters: Verbose, Debug,
ErrorAction, ErrorVariable, WarningAction, WarningVariable,
OutBuffer, PipelineVariable, and OutVariable. For more information, see
about_CommonParameters (https://go.microsoft.com/fwlink/?LinkID=113216).
INPUTS
Via the pipeline this cmdlet can accept an array of ISBN values.
OUTPUTS
The cmdlet returns one or more objects of type Class ISBNBook with the
following properties. Note that not all properties may be present, it
depends on what data the publisher provided.
ISBN | The ISBN number that was passed in, complete with an formatting
ISBN10 | ISBN as 10 digits
ISBN13 | ISBN in 13 digit format
Title | The title of the book
LCCN | Library of Congress Catalog Number
Author | The author(s) of the book
ByStatement | The written by statement provided by the publisher
NumberOfPages | Number of pages in the book
Publishers | The Publisher(s) of this book
PublishDate | The publication date for this edition of the book
PublisherLocation | The location of the publisher
Subject | Generic subject(s) for the work
LibraryOfCongressClassification | Specialized classification used by Library of Congress
DeweyDecimalClass | Dewey Decimal number
Notes | Any additional information provided by the publisher
CoverUrlSmall | URL link to an image of the book cover, in a small size
CoverUrlMedium | URL link to an image of the book cover, in a medium size
CoverUrlLarge | URL link to an image of the book cover, in a large size
NOTES
ArcaneBooks - Get-ISBNBookData.ps1
Author: Robert C Cain | @ArcaneCode | arcane@arcanetc.com
This code is Copyright (c) 2023 Robert C Cain All rights reserved
The code herein is for demonstration purposes.
No warranty or guarantee is implied or expressly granted.
This module may not be reproduced in whole or in part without
the express written consent of the author.
-------------------------- EXAMPLE 1 --------------------------
PS > # Pass in a single ISBN as a parameter
$ISBN = '0-87259-481-5'
$bookData = Get-ISBNBookData -ISBN $ISBN
$bookData
-------------------------- EXAMPLE 2 --------------------------
PS > # Pipe in a single ISBN
$ISBN = '0-87259-481-5'
$bookData = $ISBN | Get-ISBNBookData
$bookData
-------------------------- EXAMPLE 3 --------------------------
PS > # Pipe in an array of ISBNs
$ISBNs = @( '0-87259-481-5'
, '0-8306-7801-8'
, '0-8306-6801-2'
, '0-672-21874-7'
, '0-07-830973-5'
, '978-1418065805'
, '1418065803'
, '978-0-9890350-5-7'
, '1-887736-06-9'
, '0-914126-02-4'
, '978-1-4842-5930-6'
)
$bookData = $ISBNs | Get-ISBNBookData -Verbose
$bookData
$bookData | Select-Object -Property ISBN, Title
RELATED LINKS
https://github.com/arcanecode/ArcaneBooks/blob/1ebe781951f1a7fdf19bb6731487a74fa12ad08b/ArcaneBooks/Help/Get-ISBNBookData.md
http://arcanecode.me
See Also
The ArcaneBooks Project – An Introduction
Conclusion
As you can see, implementing comment based help is quite easy. It’s also important, as users rely on help to understand how to use the functions you author. You’ll also find it helpful as a reminder to yourself about the functionality of your own code down the road.
Another useful feature for help is to create about_
help for your modules. You’ve likely seen these before, Microsoft provides a long list of about topics for PowerShell itself.
You can create your own set of about help for your module, and in the next post I’ll show you how.