Adding Help to PowerShell Scripts

The Scripting Version of “Be Kind, Rewind”

There’s two hard parts to writing a script:

  1. Getting the silly thing to work correctly
  2. Showing people who aren’t you how to use it correctly

The first one is, I maintain, the easier. By far. Getting someone who isn’t you to see what you mean is significantly harder. This is one area where most scripting languages fall down, in that they don’t have a built-in help system available. So you have to add some home-built thing, which you then have to maintain. Man pages are okay, but they’re a separate set of files from the script, requiring additional work, and we all know how much coders love writing documentation.

No one can do much about the tediousness of writing docs, but PowerShell has an awesome built-in help system that not only applies to PowerShell binaries, but that you can build into literally any PowerShell script. The basic documentation is available as always from Microsoft:

There’s a lot of really good info, but you can build a simple help system for a script without having to try real hard. Basically, it’s all comments, but specific comments. Here’s one for my Get-MacInfo script:

<#
.SYNOPSIS
This is a powershell script for macOS that replicates, or tries to, the "Get-ComputerInfo" command for Windows Powershell

.DESCRIPTION
It's not a 1:1 replication, some of it wouldn't make any sense on a Mac. Also, it does check to make sure it's running
on a mac. This pulls information from a variet of sources, including uname, sysctl, AppleScript, sw_ver, system_profiler,
and some built-in powershell functions. It shoves it all into an ordered hashtable so there's some coherency in the output.
If you run the script without any parameters, you get all the items in the hashtable. If you provide one key as a parameter, 
you get the information for that key. You can provide a comma-separated list of keys and you'll get that as a result.

Note: the keys labled "Intel Only" don't exist for Apple Silicon.

Current keys are:
macOSBuildLabEx
macOSCurrentVersion
macOSCurrentBuildNumber
macOSProductName
macOSDarwinVersion
SystemFirmwareVersion
OSLoaderVersion
HardwareSerialNumber
HardwareUUID
ProvisioningUDID
HardwareModelName
HardwareModelID
ActivationLockStatus
CPUArchitecture
CPUName
CPUSpeed (Intel Only)
CPUCount (Intel Only)
CPUCoreCount
CPUL2CacheSize (Intel Only)
CPUBrandString
L3CacheSize (Intel Only)
HyperThreadingEnabled (Intel Only)
RAMAmount
AppMemoryUsedGB
VMPageFile
VMSwapInUseGB
BootDevice
FileVaultStatus
EFICurrentLanguage
DSTStatus
TimeZone
UTCOffset
DNSHostName
LocalHostName
NetworkServiceList
CurrentUserName
CurrentUserUID
CurrentDateTime
LastBootDateTime
Uptime

.EXAMPLE
Get-MacInfo by itself gives you all the parameters it can output

.EXAMPLE
Get-MacInfo TimeZone gives you the current timezone for the computer

.EXAMPLE
Get-MacInfo TimeZone,FileVault status gives you the current timezone and the filevault status for the computer

.NOTES
This can be used as a Powershell module or as a standalone script. 

.LINK
https://github.com/johncwelch/Get-MacInfo
#>

As you can see, it’s one really long block comment, with specific headers (.SYNOPSIS, .EXAMPLE, etc) that work when someone enters Get-Help <module or script name>. So if you have my Get-MacInfo script or module, and you enter Get-Help Get-MacInfo (tab completion works here, because PowerShell’s tab completion is TOTAL R0XX0RZ), you see:

Get-Help Get-MacInfo                                

NAME
    Get-MacInfo
    
SYNOPSIS
    This is a powershell script for macOS that replicates, or tries to, the "Get-ComputerInfo" command for Windows 
    Powershell
    
    
SYNTAX
    Get-MacInfo [[-keys] <Object>] [<CommonParameters>]
    
    
DESCRIPTION
    It's not a 1:1 replication, some of it wouldn't make any sense on a Mac. Also, it does check to make sure it's 
    running
    on a mac. This pulls information from a variet of sources, including uname, sysctl, AppleScript, sw_ver, 
    system_profiler,
    and some built-in powershell functions. It shoves it all into an ordered hashtable so there's some coherency in 
    the output.
    If you run the script without any parameters, you get all the items in the hashtable. If you provide one key as a 
    parameter, 
    you get the information for that key. You can provide a comma-separated list of keys and you'll get that as a 
    result.
    
    20221001 added code for Apple Silicon
    
    Note: the keys labled "Intel Only" don't exist for Apple Silicon.
    
    Current keys are:
    macOSBuildLabEx
    macOSCurrentVersion
    macOSCurrentBuildNumber
    macOSProductName
    macOSDarwinVersion
    SystemFirmwareVersion
    OSLoaderVersion
    HardwareSerialNumber
    HardwareUUID
    ProvisioningUDID
    HardwareModelName
    HardwareModelID
    ActivationLockStatus
    CPUArchitecture
    CPUName
    CPUSpeed (Intel Only)
    CPUCount (Intel Only)
    CPUCoreCount
    CPUL2CacheSize (Intel Only)
    CPUBrandString
    L3CacheSize (Intel Only)
    HyperThreadingEnabled (Intel Only)
    RAMAmount
    AppMemoryUsedGB
    VMPageFile
    VMSwapInUseGB
    BootDevice
    FileVaultStatus
    EFICurrentLanguage
    DSTStatus
    TimeZone
    UTCOffset
    DNSHostName
    LocalHostName
    NetworkServiceList
    CurrentUserName
    CurrentUserUID
    CurrentDateTime
    LastBootDateTime
    Uptime
    

RELATED LINKS
    https://github.com/johncwelch/Get-MacInfo

REMARKS
    To see the examples, type: "Get-Help Get-MacInfo -Examples"
    For more information, type: "Get-Help Get-MacInfo -Detailed"
    For technical information, type: "Get-Help Get-MacInfo -Full"
    For online help, type: "Get-Help Get-MacInfo -Online"

As you go through the docs, you’ll see where you can do a lot more, but that’s how amazingly simple it is to write useful, accurate, updateable documentation for a PowerShell script or module that lives where it should live: in the script or module, and best of all, that’s the standard PowerShell way to add help.

It doesn’t take much to write a decent help system for a PowerShell script or module, and if you do, you save yourself a lot of tech support time, which is way more annoying than writing documentation. So really, there’s not excuse not to.

Advertisement