PowerShell for Windows Admins

May 1 2017   3:33PM GMT

Positional parameters

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Tags:
Powershell

Positional parameters have been around since the beginning of PowerShell. Positional parameters assume the parameter you mean from the position of the value in the command you supply. For instance you can do this:

Get-ChildItem -Path C:\test\ -Filter *.xml

Path and filter are the 2 positional parameters for Get-ChildItem (cmdlets can have 0, 1 or many positional parameters) so you can also do this:

Get-ChildItem C:\test\  *.xml

If you reverse the values you get an error

PS> Get-ChildItem *.xml  C:\test\
Get-ChildItem : Second path fragment must not be a drive or UNC name.
Parameter name: path2
At line:1 char:1
+ Get-ChildItem *.xml  C:\test\
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (C:\Scripts:String) [Get-ChildItem], ArgumentException
    + FullyQualifiedErrorId : DirArgumentError,Microsoft.PowerShell.Commands.GetChildItemCommand

You can find the position parameters by looking in the help file

PS> Get-Help Get-ChildItem -Parameter path

-Path <String[]>
    Specifies a path to one or more locations. Wildcards are permitted. The default location is the current directory
    (.).

    Required?                    false
    Position?                    0
    Default value                Current directory
    Accept pipeline input?       True (ByPropertyName, ByValue)
    Accept wildcard characters?  false

PS> Get-Help Get-ChildItem -Parameter filter

-Filter <String>
    Specifies a filter in the provider's format or language. The value of this parameter qualifies the Path parameter.
    The syntax of the filter, including the use of wildcards, depends on the provider. Filters are more efficient than
    other parameters, because the provider applies them when retrieving the objects, rather than having Windows
    PowerShell filter the objects after they are retrieved.

    Required?                    false
    Position?                    1
    Default value                None
    Accept pipeline input?       False
    Accept wildcard characters?  false

Notice the position values. A parameter that has to be named i.e. non-positional will have Named as the value for position:

PS> Get-Help Get-ChildItem -Parameter include

-Include <String[]>
    Specifies, as a string array, an item or items that this cmdlet includes in the operation. The value of this parameter qualifies the Path parameter. Enter a path element or pattern, such as *.txt. Wildcards are permitted.

    The Include parameter is effective only when the command includes the Recurse parameter or the path leads to the contents of a directory, such as C:\Windows\*, where the wildcard character specifies the contents of the  C:\Windows directory.

    Required?                    false
    Position?                    named
    Default value                None
    Accept pipeline input?       False
    Accept wildcard characters?  false

You can also identify positional parameters from the syntax listing

Get-ChildItem [[-Path] <String[]>] [[-Filter] <String>] [-Attributes {ReadOnly | Hidden | System | Directory | Archive | Device | Normal | Temporary | SparseFile | ReparsePoint | Compressed | Offline | NotContentIndexed | Encrypted | IntegrityStream | NoScrubData}] [-Depth <UInt32>] [-Directory] [-Exclude <String[]>] [-File] [-Force]
[-Hidden] [-Include <String[]>] [-Name] [-ReadOnly] [-Recurse] [-System] [-UseTransaction] [<CommonParameters>]

The name of positional parameters are surrounded by square brackets

A question on the forum noted that the help file about_parameters states that positional parameters are numbers 1,2,3… and named parameters are effectively numbered 0 BUT the help file for Get-ChildItem numbers the positional parameters as 0 & 1

What’s happening?

If I remember correctly originally positional parameters were numbered from 1 but that was changed so 0 didn’t mean named. Looks like the about file didn’t get updated.

We can test this this with a function:

function test-pp {
 [CmdletBinding()]
 param (
   [Parameter(Position=0)]
   [int]$x,

   [Parameter(Position=1)]
   [string]$y
 )

 "$x is a number"
 "$y is a string"
}

PS> test-pp -x 2 -y abc
2 is a number
abc is a string

PS> test-pp 2 abc
2 is a number
abc is a string

So using position 0 works for positional parameters. What if we number them 1 & 2

function test-pp {
 [CmdletBinding()]
 param (
   [Parameter(Position=1)]
   [int]$x,

   [Parameter(Position=2)]
   [string]$y
 )

 "$x is a number"
 "$y is a string"
}

PS> test-pp -x 2 -y abc
2 is a number
abc is a string

PS> test-pp 2 abc
2 is a number
abc is a string

Works as well.

I’d recommend starting your positional parameter numbering from 0 and assume that about_parameters needs updating

 Comment on this Post

 
There was an error processing your information. Please try again later.
Thanks. We'll let you know when a new response is added.
Send me notifications when other members comment.

Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to:

Share this item with your network: