Reputation: 31
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?
Upvotes: 3
Views: 702
Reputation: 2639
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
}
Upvotes: 3
Reputation: 200353
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 += $_
}
}
Upvotes: 4
Reputation: 174690
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:\>
Upvotes: 3