将ValueFromRemainingArguments作为哈希表获取

时间:2015-01-04 10:03:28

标签: powershell

使用[parameter(ValueFromRemainingArguments=$true)]可以将传递给函数的所有剩余参数作为列表传递给变量。

如何将其余参数作为哈希表类型,例如Function -var1 value1 -var2 value2等输入?

4 个答案:

答案 0 :(得分:10)

有多种方法可以实现这一目标。以下解决方案支持以下参数:

  • 简单值(单项)
  • 数组值
  • 空值(开关)

脚本:

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

答案 1 :(得分:3)

根据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 

答案 2 :(得分:1)

这很棘手,因为使用[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}         

这是你想要实现的目标吗?

答案 3 :(得分:0)

这种方法有很多警告,但我只是想表明ConvertFrom-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在另一个答案中提到的作品中间的破折号)。然后我们将第一个单词后的第一个空格转换为等号。这将产生ConvertFrom-StringData期望的一串键值对。

已知警告

  1. 如果您尝试发送像Frode的答案中的数组,则无效。他可以处理那些。