Get-Parameter – Learn more about your cmdlets

May 3, 2010

9 comments

Back in 2007 I wrote a function as a learning tool to discover cmdlet parameters and their attributes. Since then the function has evolved and has much more information to offer. In my day-to-day scripting this is the function I use the most. It gives me a quick view of all I need to know about any cmdlet parameters, and much much more.

Here’s how the result of Get-Parameter looks when you query the Select-Object cmdlet (gprm is an alias for Get-Parameter).

PS > gprm Select-Object
ParameterSet: DefaultParameter


Name Type Pos BV BP Aliases Mandatory Dynamic
---- ---- --- -- -- ------- --------- -------
*ExcludeProperty String[] Named False False {exc} False False
*ExpandProperty String Named False False {exp} False False
*First Int32 Named False False {f} False False
InputObject PSObject Named True False {i} False False
*Last Int32 Named False False {l} False False
*Property Object[] 1 False False {p} False False
*Skip Int32 Named False False {s} False False
Unique SwitchParameter Named False False {u} False False




ParameterSet: IndexParameter


Name Type Pos BV BP Aliases Mandatory Dynamic
---- ---- --- -- -- ------- --------- -------
*Index Int32[] Named False False {ind} False False
InputObject PSObject Named True False {inp} False False
Unique SwitchParameter Named False False {u} False False

 

What you can do with Get-Parameter?

First let’s take a look at the function syntax:

Get-Parameter [-Command] <String> [[-Name] <String[]>] [-SortBy <String>] [-CommandType <String>] [-IncludeCommonParameters] [-Verbose] [-Debug] [-ErrorAction <ActionPreference>] [-WarningAction <ActionPreference>] [-ErrorVariable <String>] [-WarningVariable <String>] [-OutVariable <String>] [-OutBuffer <Int32>]

 

Short Parameters description:

  • Command: The cmdlet name or its alias. If the value is an alias Get-Parameter will resolve the cmdlet name.
  • Name: Optional. A list of parameter names to get, wildcards are permitted.
  • SortBy: Optional. The name of the column to sort on. Notice that the columns use short names so the output can fit in your shell. Values for this parameter must use the short names. For example:

    - Pos is a short name for Position.

    - BV  is a short name for ValueFromPipeline. It determine if the parameter accepts pipeline input by property name.

    - BP is a short name for ValueFromPipelineByPropertyName. It determine if the parameter accepts pipeline input by value .

  • Descending: Optional. Sorts the objects in descending order. The default is ascending order.
  • CommandType: Optional. Specifies the command type (cmdlet,function, etc) when there are more than one commands with the same name.
  • IncludeCommonParameters: Controls whether to display Common Parameters in the output.

One feature I wanted to add to the function is the ability to include/exclude output of common parameters. In previous versions of Get-Parameter, I created a collection of strings that contained all (v2) common parameter names and tested against it inside the function. That was OK but I was looking for a way to get the parameter names programmatically instead of hard coding them. Finally I’ve found a way with the CommonParameters Class.

PS > [System.Management.Automation.Internal.CommonParameters].GetProperties() | `
Select-Object -ExpandProperty Name







Verbose
Debug
ErrorAction
WarningAction
ErrorVariable
WarningVariable
OutVariable
OutBuffer

Another column I want to add is the DefaultValue (DV) for each parameter, working on it…

 

What can you learn from the output?

Before we continue let’s talk about Parameter Sets, In a nutshell:

‘Windows PowerShell uses the concept of parameter sets to enable you to write a single cmdlet that can perform different actions for different scenarios. Parameter sets allow you to expose different parameters to the user and to return different information based on the parameters specified by the user.’

More information about Parameter Sets and how to use them can be found HERE and HERE. Now let’s take a look at Get-Random:

PS > gprm Get-Random


ParameterSet: RandomNumberParameterSet

Name Type Pos BV BP Aliases Mandatory Dynamic
---- ---- --- -- -- ------- --------- -------
*Maximum Object 1 False False {ma} False False
*Minimum Object Named False False {mi} False False
SetSeed Nullable`1 Named False False {s} False False


ParameterSet: RandomListItemParameterSet

Name Type Pos BV BP Aliases Mandatory Dynamic
---- ---- --- -- -- ------- --------- -------
*Count Int32 Named False False {c} False False
*InputObject Object[] 1 True False {i} True False
SetSeed Nullable`1 Named False False {s} False False

We can see that Get-Random has two parameter sets: RandomNumberParameterSet and RandomListItemParameterSet, each with its own set of parameters. To quickly identify unique parameters in each set, each unique parameter name starts with ‘*’. All other parameters belongs to all parameter sets.

One important thing to keep in mind about parameter sets is that they are mutually exclusive. What does that mean? It means that you cannot write a command that combines ‘unique’ parameters from multiple parameter sets. With the above Get-Random output, you cannot write a command that use’s both the ‘Maximum’ and ‘Count’ parameters. You’ll get an error:

Get-ChildItem : Parameter set cannot be resolved using the specified named parameters.

Below is an explanation of each column Get-Parameter produces. You can get more information about parameter attribute declaration HERE.

 

Type

This property tells us the parameter .NET type. If a parameter has ‘[]’ at the end of its name, we know that it accepts a collection of values of that type. For example, the Include parameter can take a collection of strings so we can specify them at the command line (delimited by a comma):

PS > Get-ChildItem –Path d:\temp\* –Include *.ps1,*.txt

 

Position (Pos)

The Position column tells us if the parameter is a named parameter or positioned. If the position is a number we can write its value without the parameter name otherwise (Named) the parameter must be referenced by its name . The Path (Position 1) and Filter (Position 2) parameters are both positioned so we can write the command like so:

PS > Get-ChildItem d:\temp *.ps1


Which is the same as:

PS > Get-ChildItem –Path d:\temp –Filter *.ps1

 

BV and BP

The next two columns are BV (ValueFromPipeline) and BP (ValueFromPipelineByPropertyName). These attributes (Boolean) controls whether the parameter accepts pipeline input.

ValueFromPipeline – If the value is set to $true the parameter binds the value from the incoming pipeline object (not just a property of the object).

ValueFromPipelineByPropertyName – If the value is set to $true the parameter binds the value from the incoming pipeline object that has the same name or the same alias as this parameter. For example, if the cmdlet/function has a Name parameter and the pipeline object also has a Name property, the value of the Name property is assigned to the Name parameter.

One neat technique you can use with these attributes is when you need to bind values from incoming pipeline objects that do not necessarily have corresponding property names nor aliases. Here’s an example, you want to ping a list of server names and you want to pipe the list to the Test-Connection cmdlet: 

PS > “Server1″,”Server2″,”Server3″ | Test-Connection

Test-Connection : The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.

 

So, attempting to pipe the names directly to Test-Connection fails, let’s take a look at the ComputerName parameter:

PS > gprm Test-Connection -Name com*


ParameterSet: Default

Name Type Pos BV BP Aliases Mandatory Dynamic
---- ---- --- -- -- ------- --------- -------
ComputerName String[] 1 False True {CN, IPAddress, __SERVER, Dest…} True False 

 

The ‘ComputerName’ parameter is required (Mandatory), it’s positioned as the first parameter and it accepts pipeline input ByPropertyName. The values we’re piping doesn’t have a property named ‘ComputerName’. The typical way to handle these kind of situations is to use the Foreach-Object cmdlet:

PS > "Server1","Server2","Server3" | Foreach-Object { Test-Connection -ComputerName $_} 

 

And here comes the trick. We can get the same result without the intermediate cmdlet. If the ‘ComputerName’ parameter accepts pipeline input, either by property name or by value, then we can take advantage of that and ‘force’ the cmdlet to bind the ‘ComputerName’ value for the incoming object by using ScriptBlock Parameters.

PS > "Server1","Server2","Server3" | Test-Connection -ComputerName {$_}

Source Destination IPV4Address IPV6Address Bytes Time(ms)
------ ----------- ----------- ----------- ----- --------
PC1 Server1 192.168.1.1 {} 32 0
(...)

 

Pretty cool, ah?

Aliases

The Aliases property contains parameter built-in aliases. Parameters can also have aliases. You can use the aliases instead of the parameter names when you type or specify the parameter in a command. For example, most cmdlets that support the –ComputerName parameter defines ‘Cn’ as an alias for this parameter:

PS > gprm gwmi -name comp*



ParameterSet: query


Name Type Pos BV BP Aliases Mandatory Dynamic
---- ---- --- -- -- ------- --------- -------
*ComputerName String[] Named False False {Cn, co} False False
(...)

In addition to the built-in parameter aliases Get-Parameter also adds another value (co). This value is the least amount of characters you need to type to disambiguate the parameter from other parameter names. If you see more than one value in the Aliases column then the last ones was added by Get-Parameter and all the previous are the built-in. More information on Parameter Aliases can be found in this page.

 

Mandatory

The Mandatory property indicates if the parameter is required. If a required parameter is not provided when the cmdlet is invoked, PowerShell prompts the user for a parameter value. Sometimes, all you need to know is the list of mandatory parameters for a given command without PowerShell prompting you for each one. If so, sort the output by this property and look for all $true values. The following example shows the necessary parameters you should use to create new mailbox on Exchange 2007 (Name,UserPrincipalName,Database and Password):

PS > gprm New-Mailbox -SortBy Mandatory -Descending



ParameterSet: User


Name Type Pos Aliases Mandatory Dynamic
---- ---- --- ------- --------- -------

*Password SecureString Named {p} True False
Database DatabaseIdParameter Named {da} True False
UserPrincipalName String Named {u} True False
Name String 1 {n} True False
(...)

 

Dynamic

Cmdlets, Providers and Advanced Functions can define parameters that are available to the user under special conditions, such as when the argument of another parameter is a specific value. These parameters are added at runtime and are referred to as dynamic parameters because they are added only when they are needed.

With this column you can identify the Dynamic parameters of the command in question. Keep in mind that the result is based on the shell’s provider location. See the ‘Dynamic Parameters’ section in the about_Functions_Advanced_Parameters help topic or read the updated online version or the ‘FINDING DYNAMIC PARAMETERS’ section in the about_providers file.

That’s all. There’s a lot to digest but as you can see there’s a lot to learn from the output. With Get-Parameter you can see the ‘Big Picture’. As always, there’s plenty of room for improvements and I’m open for suggestions.

Get-Parameter is available at PoshCode.org.

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

9 comments

  1. Jason HMay 6, 2010 ב 19:35

    This looks extremely useful, Shay. Thanks. I copied it from PoshCode for my profile but the following error when opening a new PS 1.0 session:

    Missing closing ‘)’ in expression.
    At C:\WINDOWS\system32\WindowsPowerShell\v1.0\profile.ps1:9 char:3
    + [ <<<< String]$Command,

    Any idea what I’m doing wrong?
    Jason

    Reply
  2. ScriptFanaticMay 9, 2010 ב 11:14

    Jason

    The function was written for PowerShell v2.

    Reply
  3. Laurent DardenneJuly 18, 2010 ב 12:23

    Hi,
    I get an exception ( NullArrayIndex ) when I use Get-Parameter with Exit-PSSession.

    Reply
  4. ScriptFanaticJuly 18, 2010 ב 12:51

    Thanks for reporting it! It happens when a cmdlet doesn’t have any built-in parameters (except for CommonParameters). You won’t get the error if you specify the -IncludeCommonParameters switch.

    I’ve fixed it and published the updated code at poshcode,you can get it here: http://poshcode.org/1979.

    Reply
  5. ScriptFanaticJuly 18, 2010 ב 14:21

    Laurent, I had some issues with the updated version. Please check the latest version: http://poshcode.org/1980.

    Reply
  6. Laurent DardenneJuly 18, 2010 ב 19:00

    Thanks you, but now i get a exception for Write-Warning (only one parameter)

    >Get-Parameter Write-Warning
    “The specified cmdlet (‘Write-Warning’) has no parameters.

    Reply
  7. ScriptFanaticJuly 18, 2010 ב 22:43

    I hope the following version ends the saga :)

    http://poshcode.org/1981

    Reply
  8. Laurent DardenneJuly 19, 2010 ב 12:01

    Thank you.
    >>I hope the following version ends the saga :)
    The last episode :)

    ValidateScript attribut must contain ‘Filter ‘
    > Get-Parameter -command Invoke-Ternary -commandtype filter

    And for this call, I think that this error message is ambiguous :
    > Get-Parameter -command Invoke-Ternary -commandtype function
    ‘*’ is not a Cmdlet,Function,Filter,Alias or ExternalScript

    Reply
  9. ScriptFanaticJuly 19, 2010 ב 16:08

    Nice catch, keep them coming :)
    It seems I’ve missed ‘Filter’ in the ValidateSet attribute. New Version: http://poshcode.org/1982.

    Reply