4

Given a script foo.ps1: param($x,$y) return $x/$y

Is it possible to enforce explicit parameter naming when calling it?

./foo.ps1 5 10 would generate an error ./foo.ps1 -x 5 -y 10 would be OK

4 Answers 4

4

This code works but it uses something not documented (I could not find anything about negative positions):

function Test
{
    param(
        [Parameter(Position=-1)]
        $x
        ,
        [Parameter(Position=-1)]
        $y
    )
    $x/$y
}

Test -x 1 -y 2
Test -y 2 -x 1
Test 1 2

Output:

0.5
0.5
Test : Cannot bind positional parameters because no names were given.
At C:\TEMP\_110127_170853\q1.ps1:15 char:5
Sign up to request clarification or add additional context in comments.

2 Comments

interesting. I almost like the idea of using -1 over a dummy param even it isn't documented. Voting your answer up.
I played around with this a little and it turns out to be somewhat unfriendly. The error displayed when you try to use positional parameters doesn't tell you what the parameter names are. Even worse, if you "get-help test", get-help displays an index out of range error.
4

If you specify a position using the PowerShell V2 advance function position property all parameters default to non-positional unless a position property is specified for other parameters (source: PowerShell In Action 2nd pg 296). So you could do this:

function Test-Args
{
    param(
    [parameter(Position=0)] $dummy,
    $x,
    $y
    )
    $x/$y
}

7 Comments

But can you pass the arguments to an advanced function in a called script through the script parameters and have the advanced function know if they were originally positional or named when passed to the script?
A script can also implement position property. If I turn the function into a script called test--arg1.ps1 (works the same: param( [parameter(Position=0)] $dummy, $x, $y ) $x/$y
OK. I still like mine better. I tried a script using the positional parameters, and ./foo -x 5 10 tries to run, but throws a divide by zero exception. Bracketing $x and $y with dummy params, and testing all 4 forces you to use -x and -y.
Unless I'm interpreting the original question incorrectly, that's exactly what he wants i.e. force -x and -y while positional will fail.
I guess a divide by zero exception qualifies as "failing".
|
1

You can specify this in the CmdletBinding argument. Even with PositionalBinding set to $false, you can still assign positions to your parameters. PowerShell will no longer automatically assign positions to your parameters, so all parameters are named, unless specified otherwise.

function foo {
    [CmdletBinding(PositionalBinding=$false)]

    param (

        [Parameter()]
        [String]$a,

        [Parameter(Position=0)]
        [String]$a,
    )
}

Comments

0

I'm going to go with this for foo.ps1. Unless somebody manages to explicitly use -dummy1 or -dummy2 to specify the arguments, it should work fine.

param($dummy1,$x,$y,$dummy2)
if (!$x -or !$y -or $dummy1 -or $dummy2){
"Error: specify -x and -y explicitly"
}
else {$x/$y}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.