User Rating: 5 / 5

Star ActiveStar ActiveStar ActiveStar ActiveStar Active
 

Explains where the values of the parameter attributes originate and how to change them, including the little-known SupportsWildcards and PSDefaultValue attributes.

Tested on: Windows PowerShell 5.1.14393.206, PowerShell 6.0.0.11

 

Parameter attributes are the list of parameter properties that appear in a help file when you use the Full or Parameter parameters of Get-Help.

-Path                                       
    A description of the Path parameter.            
                                                    
    Required?                    false              
    Position?                    1                  
    Default value                C:\Windows         
    Accept pipeline input?       true (ByValue)     
    Accept wildcard characters?  false

They're actually NoteProperty members of the MamlCommandHelpInfo object that Get-Help returns.

Although they appear odd to beginners, most of us rely on them and assume that they're accurate. Unfortunately, they're not always that accurate. In particular, the Accept wildcard characters attribute often says 'false' when it should be true, especially when the command uses the comment-based help.

 

Where do the attributes get their values?

Comment-based help is pretty smart about the parameter attributes. Here are its sources. Note that the parameters that Get-Help returns get the default value from the code, even though the default value is missing from the parameters objects that Get-Command returns.

 

Required?                            

Mandatory parameter of the Parameter attribute

e.g. [Parameter(Mandatory)]

Default value 1) PSDefaultValue() attribute
2) Specified default value, e.g. $Path = Get-Location
Accept wildcard characters? [SupportsWildcards()] attribute
Position?

Position parameter of Parameter attribute

e.g. [Parameter(Position=0)]

Accept pipeline input?

ValueFromPipeline, ValueFromPipelineByPropertyName parameters

of Parameter attribute, e.g. [Parameter(ValueFromPipeline)]

 

When a command has no help, PowerShell uses Get-Command to auto-generate some help.

-Path                       
                                                
    Required?                    false          
    Position?                    0              
    Accept pipeline input?       true (ByValue) 
    Parameter set name           (All)          
    Aliases                      None           
    Dynamic?                     false

The parameter attributes in auto-generated help are missing Default Value and Accept Wildcard Characters, but they have three very useful properties that help doesn't normally display (but obviously could).

Parameter set name       ParameterSetName parameter of Parameter attribute
Aliases                   Alias attribute
Dynamic? DynamicParam declaration

 

How to Set 'Accept Wildcard Characters' to True?

Get-Help assumes that parameters don't accept wildcard characters. So, by default, the value of Accept wildcard characters? (Globbing property) is false. And, because there are so many ways to code the handling of wildcard characters and no language attribute or standard method, PowerShell can't tell (easily) whether a parameter accepts wildcard characters, so you have to tell it that it's true.

In XML help, it's pretty easy.

 XMLHelp

 

And even easier in PowerShell HelpWriter:

HelpWriter

 

To set Accepts wildcard characters? to True in comment-based help, add the SupportsWildcards attribute to the parameter definition. SupportWildcards was introduced in Windows PowerShell 3.0 (but not documented because the writer didn't know about it!)

Param
(
    [Parameter(ValueFromPipeline, Position = 0)]
    [SupportsWildcards()]             # <----------
    [string[]]
    $Path = $PWD
)

Here's the result:

PS C:\> Get-Help Test-ParameterHelp -Parameter *                                                                             
-Path                                                     
    Specifies the path to the input files. Enter one or more paths. 
    Wildcards are supported. The default is the current directory.                   
                                                                  
    Required?                    false                            
    Position?                    1                                
    Default value                $PWD                             
    Accept pipeline input?       true (ByValue)                   
    Accept wildcard characters?  true           # <-----------

The SupportsWildcard attribute doesn't affect the default displays that Get-Command returns, but all attributes specified in code are saved in the Attributes property of the command.

So, you can detect it...

(Get-Command Test-ParameterHelp).ParameterSets.Parameters | Where {$_.Attributes.TypeID.Name -contains 'SupportsWildcardsAttribute'}

Name                            : Path                                                                         
ParameterType                   : System.String                                                                
IsMandatory                     : False                                                                        
IsDynamic                       : False                                                                        
Position                        : 0                                                                            
ValueFromPipeline               : True                                                                         
ValueFromPipelineByPropertyName : False                                                                        
ValueFromRemainingArguments     : False                                                                        
HelpMessage                     :                                                                              
Aliases                         : {}                                                                           
Attributes                      : {System.Management.Automation.SupportsWildcardsAttribute, __AllParameterSets, System.Management.Automation.ArgumentTypeConverterAttribute}

Display it...

(Get-Command Test-ParameterHelp).ParameterSets.Parameters | 
Format-Table Name, @{L = 'Globbing'; E = {$_.Attributes.TypeID.Name -contains 'SupportsWildcardsAttribute'}} Name Globbing ---- -------- Path True ID False Verbose False Debug False ErrorAction False WarningAction False InformationAction False ErrorVariable False WarningVariable False InformationVariable False OutVariable False OutBuffer False PipelineVariable False

And, even add a Globbing property to the parameter object.

(Get-Command Test-ParameterHelp).ParameterSets.Parameters | 
Add-Member -MemberType ScriptProperty -Name Globbing -Value {$this.Attributes.TypeID.Name -contains 'SupportsWildcardsAttribute'} -PassThru Globbing : True Name : Path ParameterType : System.String IsMandatory : False IsDynamic : False Position : 0 ValueFromPipeline : True ValueFromPipelineByPropertyName : False ValueFromRemainingArguments : False HelpMessage : Aliases : {} Attributes : {System.Management.Automat System.Management.Automati Globbing : False Name : ID ParameterType : System.Int32 IsMandatory : False IsDynamic : False ...

But, beware! Because this attribute is not verified by code, it can be inaccurate. You could add it to your parameter definition, but not implement it in the code. Or, accept wildcards, but omit the attribute.

So, trust, but verify. And, in your help description, let the user know if the parameter supports wildcards, even if you add/omit the SupportsWildcards attribute.

 

How to Specify a Custom Default Value

Unlike Get-Command, Get-Help gets the default value that you specify in your code. For example:

Param
(
    [Parameter(ValueFromPipeline, Position = 0)]
    [SupportsWildcards()]
    [string[]]
    $Path = $PWD    #

Here's the default value in the help display.

PS C:\> Get-Help Test-ParameterHelp -Parameter *                                                                             
-Path                                                     
    Specifies the path to the input files. Enter one or more paths. 
    Wildcards are supported. The default is the current directory.                   
                                                                  
    Required?                    false                            
    Position?                    1                                
    Default value                $PWD   #

But, the default value might be a complex expression or the result of a call to a helper function that has no meaning to the end-user.

To specify a custom default value, use the PSDefaultValue attribute with the Help property. PSDefaultValue also has a Value property, but Get-Help doesn't use it.

Param
(
    [Parameter(Mandatory = $false,
    ValueFromPipeline = $true, Position = 0)]
    [SupportsWildcards()]
    [PSDefaultValue(Help = 'Current location')]
    [string]
    $Path = $PWD
)

Here's the result:

PS C:\> Get-Help Test-ParameterHelp -Parameter *                
                                                                       
-Path                                                          
    A description of the Path parameter.                               
                                                                       
    Required?                    false                                 
    Position?                    1                                     
    Default value                Current location   #

And, of course, Get-Command has everything tucked away, including the unused Value property. You just need to claw at it a bit to get it.

Param
	(
		[Parameter(Mandatory = $false,
				   ValueFromPipeline = $true,
				   Position = 0)]
		[SupportsWildcards()]
		[PSDefaultValue(Help = 'Current location'; Value=$PWD)]
		[string]
		$Path = $PWD
)

(Get-Command Test-ParameterHelp).ParameterSets.Parameters | Select-Object Name,
   @{L = 'DefaultValue'; E = {($_.Attributes | Where-Object {$_.TypeID.Name -eq 'PSDefaultValueAttribute'}).Value}},
   @{L = 'DefaultValueHelpString'; E = {($_.Attributes | Where-Object {$_.TypeID.Name -eq 'PSDefaultValueAttribute'}).Help}}

Name                DefaultValue DefaultValueHelpString
----                ------------ ----------------------
Path                $PWD         Current location      
ID                                                     
Verbose                                                
Debug                                                  
ErrorAction                                            
WarningAction                                          
InformationAction                                      
ErrorVariable                                          
WarningVariable                                        
InformationVariable                                    
OutVariable                                            
OutBuffer                                              
PipelineVariable 

Again, be a bit cautious, because the PSDefaultValue help string is just a string; it's not validated in any way.

So, that's the current story of parameter attributes and their sources, although there might be changes as the open-source version of PowerShell on GitHub progresses. I encourage you to use the SupportsWildcards attribute to make the Accepts Wildcard Characters? parameter attributes accurate. And, use the PSDefaultValue attribute as needed.

June Blender is a Technology Evangelist at SAPIEN Technologies, Inc. and a Microsoft Cloud & DataCenter MVP. You can reach her at This email address is being protected from spambots. You need JavaScript enabled to view it. and 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 Trial Software Questions forum.
Copyright © 2017 SAPIEN Technologies, Inc.