Fun With PowerShell – Authoring Help

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.

Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s