Positional parameters allow you go use a function of cmdlet without specifying the parameter names. The values you supply are assigned to the correct parameters based on their position.

If you look at the documentation for PowerShell you’ll see some confusion as to whether position 0 or position 1 is the first assigned position. Hopefully, these experiments will explain it all.

By default parameters are positional. So values are assigned to parameters based on the order of parameter definition.

function pa {

param (

[int] $x,

[int] $y

)

“`$x = $x”

“`$y = $y”

$x * $y

}

PS> pa -x 2 -y 3

$x = 2

$y = 3

6

PS> pa 2 -y 3

$x = 2

$y = 3

6

PS> pa 2 3

$x = 2

$y = 3

6

PS> pa -x 2 3

$x = 2

$y = 3

6

When you assign a position to one of more parameters those parameters without a positional assignment become non-positional and need to be explicitly defined

PS> pb -x 2 -y 3

$x = 2

$y = 3

6

PS> pb 2 -y 3

$x = 2

$y = 3

6

PS> pb 2 3

pb : A positional parameter cannot be found that accepts argument ‘3’.

At line:1 char:1

+ pb 2 3

+ ~~~~~~

+ CategoryInfo : InvalidArgument: (:) [pb], ParameterBindingException

+ FullyQualifiedErrorId : PositionalParameterNotFound,pb

PS> pb -x 2 3

pb : A positional parameter cannot be found that accepts argument ‘3’.

At line:1 char:1

+ pb -x 2 3

+ ~~~~~~~~~

+ CategoryInfo : InvalidArgument: (:) [pb], ParameterBindingException

+ FullyQualifiedErrorId : PositionalParameterNotFound,pb

Alternatively

function pc {

param (

[Parameter(Position=1)]

[int] $x,

[int] $y

)

“`$x = $x”

“`$y = $y”

$x * $y

}

PS> pc -x 2 -y 3

$x = 2

$y = 3

6

PS> pc 2 -y 3

$x = 2

$y = 3

6

PS> pc 2 3

pc : A positional parameter cannot be found that accepts argument ‘3’.

At line:1 char:1

+ pc 2 3

+ ~~~~~~

+ CategoryInfo : InvalidArgument: (:) [pc], ParameterBindingException

+ FullyQualifiedErrorId : PositionalParameterNotFound,pc

PS> pc -x 2 3

pc : A positional parameter cannot be found that accepts argument ‘3’.

At line:1 char:1

+ pc -x 2 3

+ ~~~~~~~~~

+ CategoryInfo : InvalidArgument: (:) [pc], ParameterBindingException

+ FullyQualifiedErrorId : PositionalParameterNotFound,pc

So far it looks as position 0 or position 1 can be used as the first assigned position. What happens if we use both:

function pd {

param (

[Parameter(Position=0)]

[int] $x,

[Parameter(Position=1)]

[int] $y

)

“`$x = $x”

“`$y = $y”

$x * $y

}

PS> pd -x 2 -y 3

$x = 2

$y = 3

6

PS> pd 2 -y 3

$x = 2

$y = 3

6

PS> pd 2 3

$x = 2

$y = 3

6

So position 0 takes precedence over position 1

What if we have gaps in the position order:

function pe {

param (

[Parameter(Position=0)]

[int] $x,

[Parameter(Position=2)]

[int] $y

)

“`$x = $x”

“`$y = $y”

$x * $y

}

PS> pe -x 2 -y 3

$x = 2

$y = 3

6

PS> pe 2 -y 3

$x = 2

$y = 3

6

PS> pe 2 3

$x = 2

$y = 3

6

Numerical position order is used.

In the next case position 1 is assigned to the first parameter

function pf {

param (

[Parameter(Position=1)]

[int] $x,

[Parameter(Position=2)]

[int] $y

)

“`$x = $x”

“`$y = $y”

$x * $y

}

PS> pf -x 2 -y 3

$x = 2

$y = 3

6

PS> pf 2 -y 3

$x = 2

$y = 3

6

PS> pf 2 3

$x = 2

$y = 3

6

Note the order of positions

function pg {

param (

[Parameter(Position=2)]

[int] $x,

[Parameter(Position=1)]

[int] $y

)

“`$x = $x”

“`$y = $y”

$x * $y

}

PS> pg -x 2 -y 3

$x = 2

$y = 3

6

PS> pg 2 -y 3

$x = 2

$y = 3

6

PS> pg 2 3

$x = 3

$y = 2

6

x is assigned the first positional parameter because y is explicitly defined.

In the next case no parameter is given position 0 or 1

function ph {

param (

[Parameter(Position=4)]

[int] $x,

[Parameter(Position=2)]

[int] $y

)

“`$x = $x”

“`$y = $y”

$x * $y

}

PS> ph -x 2 -y 3

$x = 2

$y = 3

6

PS> ph 2 -y 3

$x = 2

$y = 3

6

PS> ph 2 3

$x = 3

$y = 2

6

PS> ph -x 2 3

$x = 2

$y = 3

6

When y is defined then x gets the first available positional value. When both x and y aren’t defined y gets the first positional parameter.

From the above.

Positional parameters are assigned a numeric position.

Defined parameters explicitly overrides positional order

Values are assigned in order of position

If a parameter isn’t defined it gets a value based on its position

Position ranking can start at any number – 0 and 1 are the defaults.

Lowest ranked undefined parameter gets the first positional value