User Rating: 5 / 5

Star ActiveStar ActiveStar ActiveStar ActiveStar Active
 

Because dynamic parameters can be added to a command from multiple sources, the command author (who writes the help) cannot predict the dynamic parameters that might be available at runtime. Therefore, Get-Help expects dynamic parameters to be documented in the help file for the code that adds the dynamic parameters; not the code that has the dynamic parameters.

This makes sense in theory, but, in practice, it's not discoverable and it's very confusing for users.

To write help for the dynamic parameters that you add to cmdlets and functions, you need to sneak it into the description. I'll show you how. The article ends with suggestions for making this process easier. I welcome your suggestions, too.


Dynamic parameters -- parameters that are added to a command at runtime -- are a very powerful tool in Windows PowerShell. You might not know it, but I bet you're familiar with a few of them, including those that the FileSystem provider adds to Get-ChildItem.

PS C:\> (Get-Command Get-ChildItem).ParameterSets.Parameters | where IsDynamic | foreach Name | Sort -Unique

Attributes
Directory
File
Hidden
ReadOnly
System

 

In this case, a Windows PowerShell provider adds the dynamic parameters to a cmdlet. But, you can add dynamic parameters in many different ways, including external scripts, functions, and cmdlets. You can create dynamic parameters that are added only in certain sessions, or under conditions, or when a typical ("static") parameter has a certain value. You can even create dynamic parameters whose valid values that are determined at runtime.

For more information, see about_Functions_Advanced_Parameters or one of many great articles, like this one by Ben Ten: Dynamic Parameters in Powershell.

However, it's not easy to write help for dynamic parameters.

Why is this so hard?

You'd think this would be easy. You just add the dynamic parameter to the comment-based help or XML help and, when you run Get-Help -Full or Get-Help -Parameters, you see them. Well, no.

Before side-by-side versions, the PowerShell team realized that they were installing a single help file for each module, regardless of its version. When a new parameter was added to a cmdlet and to its help file, we didn't want help for the parameter to appear in previous versions, even though the module was using the same help file. So, Get-Help calls Get-Command (or its functional equivalent) and displays parameter help only for the parameters that actually appear in the cmdlet.

For example, I have a little Get-PhantomParameter function with Path and ID parameters. And, when I run Get-Help, it gets the help for the Path and ID parameters. But, if I add a parameter to the help that's not in the function, like the -Phantom parameter, Get-Help ignores it.

<#           ...  
	.PARAMETER Path
	A description of the Path parameter.

	.PARAMETER ID
	A description of the ID parameter.
	
	.PARAMETER Phantom
	A description of the Phantom parameter.
             ...
#>

And, when you run Get-Help, you get help only for the parameters that are actually in the cmdlet. You can't fool Get-Help.

PS C:\> Get-Help Get-PhantomParameter -Parameter *     
                                                              
-Path                                                 
    A description of the Path parameter.                      
                                                              
    Required?                    true                         
    Position?                    1                            
    Default value                                             
    Accept pipeline input?       false                        
    Accept wildcard characters?  false                        
                                                              
                                                              
-ID                                                    
    A description of the ID parameter.                        
                                                              
    Required?                    false                        
    Position?                    2                            
    Default value                0                            
    Accept pipeline input?       false                        
    Accept wildcard characters?  false

What about Dynamic Parameters?

But, Get-Command finds some dynamic parameters. In fact, the CommandParameterInfo class has an IsDynamic property. So, the "only-in-the-code" rule should not exclude dynamic parameters. But it does.

Because dynamic parameters can be added to a command by any PowerShell provider or by any other command, the command author (who is responsible for its help) wouldn't be able to predict the complete list of dynamic parameters of a command.

So, Get-Help excludes dynamic parameters from the parameter list it gets from Get-Command. And, if you include help for dynamic parameters, it treats them like our phantom parameter, and doesn't display the help.

Instead, help for dynamic parameters is supposed to be described in the help file for the provider or command that adds it. For example, the XML help for PowerShell providers has a Dynamic Parameters section that describes the dynamic parameters that the provider adds to the provider cmdlets.

DynamicParameters

From:   Function Provider, Version 5, https://technet.microsoft.com/en-us/library/hh847847.aspx

To see help for a PowerShell provider, including its Dynamic Parameters section, in Windows PowerShell 4.0 and earlier, type Get-Help <ProviderName>, for example, Get-Help FileSystem.

NOTE: Unfortunately, provider help is missing from the System.Management.Automation help file in Windows PowerShell 5.1 and later versions of 5.0, and custom cmdlet help for providers isn't working, even when present. But, you can use Get-Help Certificate to see the help for the Certificate provider in the Microsoft.PowerShell.Security module.

Quickly, we figured out that this didn't work. Help for dynamic parameters was almost undiscoverable. Users couldn't tell (and, frankly, didn't care) where a parameter came from. They just wanted to know how to use it. So, in PowerShell 3.0, the team extended the MAML schema for provider XML help to include custom cmdlet help for providers. This feature lets you override selected elements of cmdlet help with information from the provider.

But, that solution doesn't do anything for dynamic parameters that are added in other ways from other sources, including the same cmdlet.

Sneaking in Help for Dynamic Parameters

It's still true that command authors can't predict the full list of dynamic parameters that might be added to their command. But, they can certainly predict the dynamic parameters that it's adding to itself. And, it can explain them.

To sneak help for dynamic parameters into your help file, add a DYNAMIC PARAMETERS section to the end of the DESCRIPTION section of the help file. You can add it to the description of the last static parameter, but it appears indented and might be missed. If you add it to NOTES, it's displayed only with -Full.

For example, this Get-HelpFilesforModule function has a RequiredVersion dynamic parameter whose valid values are determined at runtime. It uses Adam Bertram's cool New-ValidationDynamicParam function.

DynamicParam
{
    New-ValidationDynamicParam -Name 'RequiredVersion' -ParameterSetName 'NameSet' `
        -ValidateSetOptions (Invoke-Command { if ($ModuleName) { (Get-Module -List -Name $ModuleName).Version | Sort-Object -Descending}
	else { return '0.0.0.0' } })
}

To describe it, I add a "DYNAMIC PARAMETERS" section with an entry for RequiredVersion, to the end of the .DESCRIPTION section of comment-based help or the <maml:description> section of XML help.

Important! There is no dot (.) before 'DYNAMIC PARAMETERS'. It isn't a comment keyword. If you add a dot, the help syntax is invalid, so Get-Help ignores it and displays auto-generated help.

DynamicParameter CommentBasedHelp

 

When you run Get-Help, the help for RequiredVersion isn't in the Parameters section, but it's nicely formatted and evident to the user.

DynamicParameter GetHelp

However, it's not perfect. If the user gets only the parameters of help, (Get-Help <command> -Parameter <Name or *>), the dynamic parameter, doesn't appear.

Fixing the Problem

To truly fix the problem, the PowerShell team needs to change Get-Help.

  • Get-Help needs a Version parameter to get the correct version of help for a command. This would resolve several problems, including this one.
  • Get-Help should display all help in the help file. Excluding help for some dynamic parameters because it can't predict all dynamic parameters doesn't help the user.
  • Redesign a help solution for help for dynamic parameters. When Get-Help detects a dynamic parameter, it should be able to find and display help for that parameter. This should include mechanisms for dynamic parameter authors to contribute help for their parameters.

 

In the meantime, you have a non-optimal, but satisfactory solution. If you have additional or better solutions, post them here and I'll include them.

June Blender is a technology evangelist at SAPIEN Technologies, Inc. and a Windows PowerShell MVP. You can reach her at This email address is being protected from spambots. You need JavaScript enabled to view it. or follow her on Twitter at @juneb_get_help.

If you have questions about our products, please post in our support forum.
For licensed customers, use the forum associated with your product in our Product Support Forums for Registered Customers.
For users of trial versions, please post in our Former and Future Customers - Questions forum.
Copyright © 2024 SAPIEN Technologies, Inc.