Powershell non-positional, optional params Powershell non-positional, optional params powershell powershell

Powershell non-positional, optional params


How about this?

function test{   param(      [string] $One,      [string] $Two,      [Parameter(Mandatory = $true, Position = 0)]      [string] $Three   )   "One = [$one]  Two = [$two]  Three = [$three]"}

One and Two are optional, and may only be specified by name. Three is mandatory, and may be provided without a name.

These work:

test 'foo'    One = []  Two = []  Three = [foo]test -One 'foo' 'bar'    One = [foo]  Two = []  Three = [bar]test 'foo' -Two 'bar'    One = []  Two = [bar]  Three = [foo]

This will fail:

test 'foo' 'bar'test : A positional parameter cannot be found that accepts argument 'bar'.At line:1 char:1+ test 'foo' 'bar'+ ~~~~~~~~~~~~~~~~    + CategoryInfo          : InvalidArgument: (:) [test], ParameterBindingException    + FullyQualifiedErrorId : PositionalParameterNotFound,test

This doesn't enforce that your mandatory arg is placed last, or that it's not named. But it allows for the basic usage pattern you want.

It also does not allow for more than one value in $Three. This might be what you want. But, if you want to treat multiple non-named params as being part of $Three, then add the ValueFromRemainingArguments attribute.

function test{   param(      [string] $One,      [string] $Two,      [Parameter(Mandatory = $true, Position = 0, ValueFromRemainingArguments = $true)]      [string] $Three   )   "One = [$one]  Two = [$two]  Three = [$three]"}

Now things like this work:

test -one 'foo' 'bar' 'baz'  One = [foo]  Two = []  Three = [bar baz]

Or even

test 'foo' -one 'bar' 'baz'    One = [bar]  Two = []  Three = [foo baz]