Powershell 以哈希表形式从RemainingArguments获取值
使用Powershell 以哈希表形式从RemainingArguments获取值,powershell,Powershell,使用[参数(ValueFromRemainingArguments=$true)]可以将传递给函数的所有剩余参数作为列表放入变量中 如何将剩余的参数作为哈希表类型获取,例如对于输入,如函数-var1 value1-var2 value2?根据Ansgars注释更新 一种可能是在函数中构建哈希表。以下是一个例子: function MyFunction { [CmdletBinding()] param([parameter(ValueFromRemainingArguments=
[参数(ValueFromRemainingArguments=$true)]
可以将传递给函数的所有剩余参数作为列表放入变量中
如何将剩余的参数作为哈希表类型获取,例如对于输入,如
函数-var1 value1-var2 value2
?根据Ansgars注释更新
一种可能是在函数中构建哈希表。以下是一个例子:
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
}
}
我们使用for循环解析参数$allparams中的参数,并检索键/值对以形成哈希表,然后在结束块中显示它
MyFunction -var1 10 -var2 30 -var3 hello
Name Value
---- -----
var1 10
var3 hello
var2 30
实现这一点有多种方法。以下解决方案支持具有以下参数的参数:
- 简单值(单个项目)
- 数组值
- 空值(开关)
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
输出:
Name: Frode
Vars count: 5
Vars:
Name Value
---- -----
arraypar {value2, value3}
switchpar
simplepar value1
这很棘手,因为使用[Parameter(ValueFromRemainingArguments=$true)]意味着这是一个高级函数,而$args不能在高级函数中使用 但是,如果您想要一个包含所有指定参数及其值的哈希表,只需使用$PSBoundParameters即可,如下所示:
function foo {
[cmdletbinding()]
param(
[Parameter(Position=0)]
$Name,
[Parameter(Position=1,ValueFromRemainingArguments=$true)]
$LastName
)
"PSBoundParameters : "
$PSBoundParameters
}
foo -Name Mike Jordan Jones
其结果如下:
PSBoundParameters :
Key Value
--- -----
Name Mike
LastName {Jordan, Jones}
这就是您想要实现的吗?此方法有许多警告,但我只是想说明,这里也可以考虑从StringData转换
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"
上面的输出将是
Name Value
---- -----
var2 value2 or 3
var1-5 value1
我们将所有剩余参数作为单个字符串。然后我们在-
上拆分出现在行首或空格后的字符串。(这是Ansgar在另一个答案中提到的作品中的破折号)。然后我们将第一个单词后面的第一个空格转换成等号。这将生成一个从StringData转换而来的所需的键值对字符串
已知注意事项
如果您尝试像Frode的回答中那样发送数组,那么这将不起作用。他能处理这些李>
我会改变两件事:a)使用($allparams[$I]-替换“^-+”)
而不是。替换('-','')
,因为后者会将一个参数-一些东西
变成一些东西
,而不是一些东西
,b)使用$myhash[$key]=$value
而不是$myhash.Add($key,$value)
,因为后者会在参数多次出现时抛出错误,而前者会更新其值。我将其改编为一个助手函数Get ParamHash
,该函数需要[string[]]$ParamArray
。当在一个递归函数中调用它时,这个递归函数定义了它自己的[参数(ValueFromRemainingArguments=$true)][string[]]$ParamArray
来传递到Get-ParamHash
,我必须在-replace'^-+'
之后添加-replace':$'
,以防止冒号堆叠。似乎在散列哈希表中添加了冒号来保持一致性。这是一个很好的解决方案,但它只支持“已知参数”,而且他似乎想捕获一些聪明的It管理员可能会尝试的未知参数。:)我个人认为,他应该在“末端”(高位值)将每个可能的参数定义为可选参数。在某种程度上,他必须处理代码中的未知参数。