Using [parameter(ValueFromRemainingArguments=$true)]
one can get all the remaining arguments passed to the function into a variable as a list.
How can I
There are a number of caveats with this method but I just wanted to show that ConvertFrom-StringData
could also be considered here.
function Convert-StringToHashTable {
param(
[parameter(ValueFromRemainingArguments=$true)]
[string]$string
)
$string -replace "(^| )-","`r`n" | ForEach-Object{$_ -replace "(\w+) (.*)",'$1=$2'} | ConvertFrom-StringData
}
Convert-StringToHashTable -var1-5 value1 -var2 "value2 or 3"
Output from above would be
Name Value
---- -----
var2 value2 or 3
var1-5 value1
We take the all the remaining arguments as a single string. Then we split the string on -
that occur at the beginning of the line or after a space. ( This accounts for dashes in the middle of works like Ansgar mentioned in another answer). Then we convert the first space after the first word into an equal sign. That will make a string of key value pairs that ConvertFrom-StringData
expects.
Known Caveats
There are multiple ways to achieve this. The following solution supports parameters with:
Script:
function testf {
param(
$name = "Frode",
[parameter(ValueFromRemainingArguments=$true)]
$vars
)
"Name: $name"
"Vars count: $($vars.count)"
"Vars:"
#Convert vars to hashtable
$htvars = @{}
$vars | ForEach-Object {
if($_ -match '^-') {
#New parameter
$lastvar = $_ -replace '^-'
$htvars[$lastvar] = $null
} else {
#Value
$htvars[$lastvar] = $_
}
}
#Return hashtable
$htvars
}
testf -simplepar value1 -arraypar value2,value3 -switchpar
Output:
Name: Frode
Vars count: 5
Vars:
Name Value
---- -----
arraypar {value2, value3}
switchpar
simplepar value1
Updated per Ansgars comment.
One possibility is to build the hash-table within the function. Here is an example:
function MyFunction
{
[CmdletBinding()]
param([parameter(ValueFromRemainingArguments=$true)] $allparams)
process
{
$myhash = @{}
for ($i = 0; $i -lt $allparams.count; $i+=2)
{
$myhash[($allparams[$i]-replace '^-+')] = $allparams[$i+1]
}
}
end
{
$myhash
}
}
We parse through the params in the parameters $allparams using a for loop, and retrieve the key/value pairs to form the hash table, then in the end block we display it.
MyFunction -var1 10 -var2 30 -var3 hello
Name Value
---- -----
var1 10
var3 hello
var2 30
This is tricky because using [Parameter(ValueFromRemainingArguments=$true)] means this is an advanced function, and $args cannot be used in advanced functions.
But if you want a hashtable of all the specified parameters and their values, you could simply use $PSBoundParameters, like so :
function foo {
[cmdletbinding()]
param(
[Parameter(Position=0)]
$Name,
[Parameter(Position=1,ValueFromRemainingArguments=$true)]
$LastName
)
"PSBoundParameters : "
$PSBoundParameters
}
foo -Name Mike Jordan Jones
This results in the following :
PSBoundParameters :
Key Value
--- -----
Name Mike
LastName {Jordan, Jones}
Is this what you are trying to achieve ?