The Scripting Version of “Be Kind, Rewind”
There’s two hard parts to writing a script:
- Getting the silly thing to work correctly
- 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:
- Get-Help command documentation with a LOT of useful links at the bottom of the page
- Tips on writing help docs
- Background on the help system
- Information on updateable help
- Tips on Comment-based help
- Adding help for parameters
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.