3

Here is an example of what I am trying to do.

Function Get-Parameters { Echo $SomeMagicMethod.Get("Name"); }

Get-Parameters -Name "John Doe"

$SomeMagicMethod is an automatic variable or any other method to get named undeclared parameters.

Is that possible in Powershell?

3 Answers 3

4

You can define a special parameter to catch all unbound arguments:

Function Get-Parameters {
    Param(
        [Parameter(Mandatory=$true)]
        $SomeParam,

        [Parameter(Mandatory=$false)]
        $OtherParam = 'something',

        ...

        [Parameter(Mandatory=$false, ValueFromRemainingArguments=$true)]
        $OtherArgs
    )

    ...
}

However, that will give you an array with the remaining arguments. There won't be an association between -Name and "John Doe".

If your function doesn't define any other parameters you could use the automatic variable $args to the same end.

If you want some kind of hashtable with the unbound "named" arguments you need to build that yourself, e.g. like this:

$UnboundNamed   = @{}
$UnboundUnnamed = @()
$OtherArgs | ForEach-Object {
    if ($_ -like '-*') {
        $script:named = $_ -replace '^-'
        $UnboundNamed[$script:named] = $null
    } elseif ($script:named) {
        $UnboundNamed[$script:named] = $_
        $script:name = $null
    } else {
        $UnboundUnnamed += $_
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

This is already available using the automatic variable $Arg
@LaboratoryGuy The variable is $args, and it's only identical if your function doesn't have any other parameters.
3

You'll have to parse the unbounded arguments yourself and find the argument that's right after whatever parameter name you're looking for.

I'd abstract it away in a separate function (you could also pass $args, but this is cleaner):

function Get-InvocationParameter
{
    param(
        [Parameter(Mandatory = $true, Position = 0)]
        [System.Management.Automation.InvocationInfo]
        $Invocation,

        [Parameter(Mandatory = $true, Position = 1)]
        [string]
        $ParameterName
    )

    $Arguments = $Invocation.UnboundArguments

    $ParamIndex = $Arguments.IndexOf("-$ParameterName")

    if($ParamIndex -eq -1){
        return
    }

    return $Arguments[$ParamIndex + 1]
}

Then use it like this:

function Get-Parameter
{
    Get-InvocationParameter -Invocation $MyInvocation -ParameterName "Name"
}

And you should be able to see the arguments right after -Name (or nothing):

PS C:\> Get-Parameter -Name "John Doe"
John Doe
PS C:\> Get-Parameter -Name "John Doe","Jane Doe"
John Doe
Jane Doe
PS C:\> Get-Parameter -ID 123
PS C:\>

Comments

3

If you truly want a function with no parameters, $args is the way to go. (Why you would want such a thing is a different question.) Anyway, code like the following will parse the $args array into a hashtable of parameter/argument pairs which you can use in the rest of the function body.

function NoParams
{
    $myParams = @{}
    switch ($args)
    {
        -Foo {
            if (!$switch.MoveNext()) {throw "Missing argument for Foo"} 
            $myParams.Foo = $switch.Current 
        }
        -Bar {
            if (!$switch.MoveNext()) {throw "Missing argument for Bar"} 
            $myParams.Bar = $switch.Current 
        }
        -Baz {
            if (!$switch.MoveNext()) {throw "Missing argument for Baz"} 
            $myParams.Baz = $switch.Current 
        }
        default { throw "Invalid parameter '$_'" }
    }
    $myParams
}

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.