Writing help is often the last thing you do for an advanced function. But, instead of treating it as a disposable chore, write your help first — in advance — before you write your advanced function. Then, use the help as a design specification. The result is a better designed function and a better user experience.
If you’re using a test framework, like Pester, you can also use your help examples as test cases.
In this post, I’ll write help for the New-ValidationDynamicParam function that Adam Bertram (@adbertram) shares in #PSBloggingWeek – Dynamic Parameters and Parameter Validation. But we’ll write the help as a spec and revise it for the end user later.
You can view Adam’s script, including the end-user version of function help, at Get-TheAwesomeWithHelp.zip.
This post is part of the PowerShell Blogging Week (#PSBlogWeek) series on Windows PowerShell Advanced Functions, a series of coordinated posts designed to provide a comprehensive view of a particular topic.
In this series:
- Standard and Advanced PowerShell Functions by Francois-Xavier Cat (@LazyWinAdm) (March 30, 2015)
- PowerShell Advanced Functions: Can we build them better? With parameter validation, yes we can! by Mike F. Robbins (@mikefrobbins) (March 31, 2015)
- #PSBloggingWeek – Dynamic Parameters and Parameter Validation by Adam Bertram (@adbertram) (April 1, 2015)
- Supporting WhatIf and Confirm in Advanced Functions by Jeffery Hicks (@JeffHicks) (April 2, 2015)
- Advanced Help for Advanced Functions by June Blender (@juneb_get_help) (April 3, 2015)
- A Look at Try/Catch in PowerShell by Boe Prox (@proxb) (April 4, 2015)
To suggest a PowerShell Blogging Week topic, leave a comment or tweet it to us with the #PSBlogWeek hashtag.
Description: Describe the function UI
Begin your spec with a description of the function UI. Command-line tools, like advanced functions, don’t have a GUI, but they certainly have a user interface. Use the Description section of your help topic to describe what the function does for the user and how to use it.
Do not explain how the functions works. If you need to describe any aspect of the implementation, such as a security or performance issue, save it for the Notes section.
This is also the place to disclose anything unexpected. Help should help users predict and avoid errors, so be generous with your warnings.
Let’s describe the user experience of Adam Bertram’s New-ValidationDynamicParam function.
- This is a really advanced function that is designed for function/script authors, not end-users, so I’ll mention the audience immediately.
- I want to associate this new thing with something familiar to this audience, like ValidateSet.
- Adam’s function to be called in the DynamicParam block, which is novel, so I’ll explain that and remind users that they need the function in scope.
- Finally, this has a limited use-case, so I’ll explain that this function doesn’t create other types of dynamic parameters.
Examples: Show how to use it
Help is really show and tell. The description is the “tell”. The examples are the “show.” And, the examples are really the most important part of help.
When writing help as a spec, write examples before parameters, because the examples really reveal which parameters you need and what names they should have. Write several examples for different use cases and think about using the parameters in combination.
Also, to use the examples as test cases, include expected output in the example.
To make the examples useful to readers, focus on one element in each example. For Adam’s function, the first example uses only the mandatory parameters, the second (shown below) uses several optional parameters, the third explains how to structure the DynamicParam block, and the final one explains how to refer to the dynamic parameter and its value outside of the DynamicParam block.
Write examples in complexity order beginning with the simplest. And, to encourage users to try the examples, use resources that all users have in their system, such as the C:\Windows directory.
Here is a relatively simple example. To see all the examples, see the help at Get-TheAwesomeWithHelp.zip.
When you feel comfortable with the examples, add the parameter descriptions. Each parameter description should tell you:
- The effect of the parameter, that is, how it changes the function behavior.
- Information about the parameter values and how to enter them, including syntax.
(Think about your parameter validation, then tell users everything they need to know to avoid errors.)
- If the parameter is optional, tell the default value.
Inputs and Outputs
Inputs and outputs are typically useful only to advanced users, but they’re critical in a spec.
- Inputs lists the .NET types that you can pipe to the function by value. There’s no need to pipe to New-ValidationDynamicParam, so the value of Input is “none”.
- Outputs tells the type of object the function returns. Adam’s function should return a RuntimeDefinedParameter value.
Revise for the end-user
That’s the extent of the spec version of help: a description, examples, parameters, inputs, and outputs. Defining these elements in advance forces you to think about and design an efficient and pleasing user experience for your function.
Before you write that first line of code, you’ll know that you need a few extra parameters, and maybe another parameter set. By writing examples, you discover that the ability to pipe input to the function is worth the extra time it takes to write a process block. By writing tests, you avoid coding an obvious error and you add extra error checking to the function.
The result is a well-designed function that is regarded as an asset to the community.
After the function is written and tested, add the synopsis, related links, etc. Also, consider deleting some of the input and output in the examples, so each example is focused on a single idea.
In the end, you’ll realize that when you write it in advance, the help that you once regarded as a chore is a vital tool for designing and testing advanced functions.
To view Adam Bertram’s function with comment-based help, see Get-TheAwesomeWithHelp.zip.