In this post, I would like to provide a detailed explanation of the Get-Command -Syntax output. While the output is documented (the format used is actually called a syntax diagram) I found parts of it rather confusing.
As an example throughout this post, we will use the output of the command:
Get-Command Select-Object -Syntax
The output looks quite cryptic and terse (maybe even intimidating). I promise that you will (most likely) prefer this dense output over the more verbose output from Get-Help for Cmdlets you already know but just don’t remember the exact syntax if you stick around until the end of this post.
Ok, as a first step we might want to make the output a bit more readable. I copied this from Staffan Gustafsson while watching the recording of his excellent presentation on the Extended Type System during the European 2018 PowerShell Conference. Staffan’s idea is to split and indent the -Syntax output using regular expressions (If you read through the end your reward is a more advanced version of this):
(Get-Command -syntax Select-Object) -split ' (?=\[*-)' -replace '^[\[-]', ' $0'
Nice! This looks already much less scary.
Now let’s work through the details. Why do we see three separate outputs for one Cmdlet? While I don’t want to go into all the nitty gritty details about this sub-topic here and now, I would like to say as much as that those three outputs represent three separate Parameter-Sets. Parameter-Sets enable control over which parameters can be used together and allow you to write a Cmdlet that can perform different actions for different scenarios (where each scenario is covered by a separate Parameter-Set). Some good resources on Parameter-Sets can be found here, here, and here.
Looking at the first syntax line of the first Parameter-Set within the Select-Object output.:
- The whole line describes the syntax of a parameter.
- “Property” is the parameter name. Parameter names are always preceded by hyphens (same as if you use the Cmdlet).
- The part of the syntax surrounded by angle brackets (“<Object >“) represents a parameter value. A parameter value is a placehholder for the input that the parameter takes. Parameter values are represented by their (.NET) type (when using the Cmdlet you need to provide an actual argument in place of the .Net type). The brackets after the type name “<Object >” qualify the type as an array type.
- Whole parameters and/or parameters names can be mandatory or optional.
- A parameter (name + value) surrounded by brackets indicates an optional parameter. All of Select-Object’s parameters are optional.
#works just fine Get-Process | Select-Object
#by position (0) Get-Process | Select-Object Handles #and by name both work Get-Process | Select-Object -Property Handles
In general there are 4 + 1 (for a Switch) possible variations:
|1||[[-PARAMNAME] ]||An optional parameter that can be used by position or name.|
|2||[-PARAMNAME ]||An optional parameter that can only be used by name.|
|3||[-PARAMNAME]||A required parameter that can be used by position or name.|
|4||-PARAMNAME||A required parameter that can be used only by name:|
|5||[PARAMNAME]||A switch parameter (switches are always optional and can only be used by name)|
Applying the above to the first line of Select-Object’s syntax translates:
- “Property” is an optional parameter
- Its parameter name is also optional (works by name and position)
- The position of the parameter is 0 (the first unnammed argument to the Cmdlet will be assigned to this parameter
You can double-check this by using Get-Help:
Get-Help Select-Object -Parameter Property
And finally here is the code for the syntax “prettifier”: