Sunday, December 28, 2008

PowerShell CTP3 AutoHelp

I’ve been playing a lot with AutoHelp in PowerShell CTP3. Not sure if this is the official name, but Auto-Help enables you to decorate a script with help information. This information can then be read by Get-Help to provide help text back to a user of your script. From an enterprise, production scripting point of view, this is very cool and super useful. Production scripts should always be well documented. And for community generated scripts, having great help text will only aid other users trying to integrate these community scripts into their environment.

The auto-help information is specified inside a block comment at the start of your script. A bloc comment begins with  “<# “ and ends with “#>”- everything inside these two character blocks is considered to be a comment. Here’s a very simple auto-help block:

  1. <# 
  3.     Cool Script 
  5.     No really. It's really really cool" 
  6. .NOTES 
  7.     Author     : Thomas Lee - 
  8. .LINK 
  10. #> 
  12. "The meaning of life, the universe and everything is {0}" -f 42 

You can of course run this script, and it'll produce a predicable output. BUT, if you save it, say as truth.ps1, you can then run Get-Help against it, with output as follows:

PS C:\foo:\> Get-Help  c:\foo\truth.ps1


    Cool Script

    C:\Users\tfl\AppData\Local\Temp\Untitled19.ps1 [<CommonParameters>]

    No really. It's really really cool"


    To see the examples, type: "get-help C:\Users\tfl\AppData\Local\Temp\Untitled19.ps1 -examples".
    For more information, type: "get-help C:\Users\tfl\AppData\Local\Temp\Untitled19.ps1 -detailed".
    For technical information, type: "get-help C:\Users\tfl\AppData\Local\Temp\Untitled19.ps1 -full".

PS C:\foo> Get-Help C:\foo\truth.ps1 -Full


    Cool Script

    C:\Users\tfl\AppData\Local\Temp\Untitled19.ps1 [<CommonParameters>]

    No really. It's really really cool"

        This cmdlet supports the common parameters: -Verbose, -Debug,
        -ErrorAction, -ErrorVariable, -WarningAction, -WarningVariable,
        -OutBuffer and -OutVariable. For more information, type,
        "get-help about_commonparameters".




        Author     : Thomas Lee -


This is very useful, as I hope you can imagine.

I’ve been doing some digging into this feature. The CTP3 release notes make mention of the various sections that help reports. I’ve built a sample script with what I think to be all the section names used. The idea being that this basic script can be used to demonstrate get-help in all its glory. However, what I’ve discovered is a great idea, but with some challenges.

First, here’s my sample auto-help demo script:

  1. <# 
  3.     A summary of what this script does 
  4.     In this case, this script documents the auto-help text in PSH CTP 3 
  5.     Appears in all basic, -detailed, -full, -examples 
  7.     A more in depth description of the script 
  8.     Should give script developer more things to talk about 
  9.     Hopefully this can help the community too 
  10.     Becomes: "DETAILED DESCRIPTION" 
  11.     Appears in basic, -full and -detailed 
  12. .NOTES 
  13.     Additional Notes, eg 
  14.     File Name  : Get-AutoHelp.ps1 
  15.     Author     : Thomas Lee - 
  16.     Appears in -full  
  17. .LINK 
  18.     A hyper link, eg 
  20.     Becomes: "RELATED LINKS"  
  21.     Appears in basic and -Full 
  22. .EXAMPLE 
  23.     The first example - just text documentation 
  24.     You should provide a way of calling the script, plus expected output 
  25.     Appears in -detailed and -full 
  26. .EXAMPLE 
  27.     The second example - more text documentation 
  28.     This would be an example calling the script differently. You can have lots 
  29.     and lots, and lots of examples if this is useful. 
  30.     Appears in -detailed and -full 
  32.    Documentary text, eg: 
  33.    Input type  [Universal.SolarSystem.Planetary.CommonSense] 
  34.    Appears in -full 
  36.    Documentary Text, eg: 
  37.    Output type  [Universal.SolarSystem.Planetary.Wisdom] 
  38.    Appears in -full 
  40.    Not sure how to specify or use 
  41.    Does not appear in basic, -full, or -detailed 
  42.    Should appear in -component 
  43. .ROLE  
  44.    Not sure How to specify or use 
  45.    Does not appear in basic, -full, or -detailed 
  46.    Should appear with -role 
  48.    Not sure How to specify or use 
  49.    Does not appear in basic, -full, or -detailed 
  50.    Should appear with -functionality 
  51. .PARAMETER foo 
  52.    The .Parameter area in the script is used to derive the contents of the PARAMETERS in Get-Help output which  
  53.    documents the parameters in the param block. The section takes a value (in this case foo, 
  54.    the name of the first actual parameter), and only appears if there is parameter of that name in the 
  55.    params block. Having a section for a parameter that does not exist generate no extra output of this section 
  56.    Appears in -det, -full (with more info than in -det) and -Parameter (need to specify the parameter name) 
  57. .PARAMETER bar 
  58.    Example of a parameter definition for a parameter that does not exist. 
  59.    Does not appear at all. 
  60. #> 
  62. # Note above section does not contain entries for NAME, SYNTAX and REMARKS sections of in get-help output 
  63. # These sections appear as follows: 
  64. # NAME - generated from the name passed to get-help.  
  65. # SYNTAX - generated from param block details. 
  66. # REMARKS - generated based on script name (e.g. what's shown in NAME) inserted into some static text. 
  67. # 
  68. # Not sure how to generate/document -component, -role, -functionality 
  69. # Not sure how to generate/use  -category 
  71. param
  72. [Parameter(ParameterSetName='Wisdom')] 
  73. [int64] $foo=42 
  74.  $foo=42 
  75.  "The meaning of life is $foo!" 

If you take this script (I’ll post it shortly to and save it away as get-autohelp, you can then run auto-help against it.

While this works really well, there are a number of issues with CTP3:

1. Put a #Requires –Version 2.0 at the top of the script and the script does not work with get-help. You just get the syntax block and nothing else.

2. In get-help’s output In the REMARKS section, the 1st line says: To see the examples..." but the examples are there just above? Maybe this should say: “To just see the Examples look above or type -examples”

3 There is no blank line in the output before “REMARKS”- sloppy output.

4. Running Get-help – in the output in the remarks section says ‘to get more informaiton used –detailed. Well – DUHH – I just did!

5. Get-Help adds two extra blank lines between the mini-header and an example – for each example.

6. Get-Help’s –online parameter seems to not work.

7. You can not specify a .NAME section in auto-help. If you do, then the output returned by get-help is heavily truncated. You should enable the developer to specify a name section, with Get-Help then supplementing this with the file name that the script lived in.

8. Two sections change name from script file to output by Get-Help. The ".DESCRIPTIION" section becomes "Detailed Description" in get-help output. And .LINK befomes "RELATED LINKS. This is inconsistent. Either make Get-Help produce the section names in the file, or change what sections you can specify in the file to match what get-help produces.

9. The links in the .LINK section are shown in basic get-help output, and with -FULL, but not -Detailed. This is inconsistent - anything shown in basic output should be shown with -full AND -detailed.

10. It's not clear how to use .COMPONENT, .ROLE and .FUNCTIONALITY sections. These do not appear to be output in any use of get-help. If nothing else, there needs to be more details on these sections.

11. Adding any new section into the comment block, and the get-help output is truncated as in 1.

Auto-Help is a great feature. But it needs some more work.


Bernd Kriszio said...

Thanks Thomas.
Good work.

Another issue:
The generated full help displays default values for parameters,
but ignores the usual way to provide default values like
[int64] $foo=42. said...

For the record, the #requires line can be anywhere in your script, so you should just move it to the bottom or something. Make sure there's at least a line of code between the "auto-help" and the:

#requires -version 2.0

However, you're right that in order for the help comments to be parsed, they must be the FIRST comments in the function or script.

MediaAndMicrocode said...

You can also use inline help to generate blog posts automatically:

Details @:

D'scribe said...

Great post, Thomas. The help this feature, which we call "comment-based-help" is in about_Comment_Based_Help in PowerShell. You can find it online here:

You can use it to doc functions, scripts, and modules. Details are in the help topic.