从Powershell获取所有命名参数,包括空和设置参数

时间:2014-02-04 17:50:11

标签: powershell parameters

我正在尝试找到一种从powershell脚本获取所有参数信息的方法。前脚本:

function test()
{
    Param(
        [string]$foo,
        [string]$bar,
        [string]$baz = "baz"
    )

    foreach ($key in $MyInvocation.BoundParameters.keys)
    {
        write-host "Parameter: $($key) -> $($MyInvocation.BoundParameters[$key])"
    }
}
test -foo "foo!"

我想以动态的方式获取$bar$baz的值,而不知道参数的名称。

我查看了$MyInvocation属性和方法,但除了设置/传递的参数外,我没有看到任何内容。

更新1:

我接近了:

function test()
{
    Param(
        [string]$foo,
        [string]$bar,
        [string]$baz = "baz"
    )
    foreach($var in (get-variable -scope private))
    {
        write-host "$($var.name) -> $($var.value)"
    }
}
test -foo "foo!"

如果我可以过滤掉脚本参数和默认参数,我会很高兴。

更新2: 最终的工作解决方案如下所示:

function test {
    param (
          [string] $Bar = 'test'
        , [string] $Baz
        , [string] $Asdf
    )
    $ParameterList = (Get-Command -Name $MyInvocation.InvocationName).Parameters;
    foreach ($key in $ParameterList.keys)
    {
        $var = Get-Variable -Name $key -ErrorAction SilentlyContinue;
        if($var)
        {
            write-host "$($var.name) > $($var.value)"
        }
    }
}

test -asdf blah;

8 个答案:

答案 0 :(得分:21)

检查此解决方案。这使用CmdletBinding()属性,该属性通过使用$PSCmdlet内置变量提供一些额外的元数据。你可以:

  1. 使用$PSCmdlet
  2. 动态检索命令的名称
  3. 使用Get-Command
  4. 获取该命令的参数列表
  5. 使用Get-Variable cmdlet
  6. 检查每个参数的值

    代码:

    function test {
        [CmdletBinding()]
        param (
              [string] $Bar = 'test'
            , [string] $Baz
            , [string] $Asdf
        )
        # Get the command name
        $CommandName = $PSCmdlet.MyInvocation.InvocationName;
        # Get the list of parameters for the command
        $ParameterList = (Get-Command -Name $CommandName).Parameters;
    
        # Grab each parameter value, using Get-Variable
        foreach ($Parameter in $ParameterList) {
            Get-Variable -Name $Parameter.Values.Name -ErrorAction SilentlyContinue;
            #Get-Variable -Name $ParameterList;
        }
    }
    
    test -asdf blah;
    

    输出

    命令的输出如下所示:

    Name                           Value                                           
    ----                           -----                                           
    Bar                            test                                            
    Baz                                                                            
    Asdf                           blah                                            
    

答案 1 :(得分:12)

要动态读取值,请使用get-variable函数/ cmdlet

write-host (get-variable "foo")

要打印出所有参数,请执行以下操作

foreach ($key in $MyInvocation.BoundParameters.keys)
{
    $value = (get-variable $key).Value 
    write-host "$key -> $value"
}

答案 2 :(得分:3)

我发现这对PS4最有用(Windows 2012 R2) - 它包含默认值/可选参数:

$cmdName = $MyInvocation.InvocationName
$paramList = (Get-Command -Name $cmdName).Parameters
foreach ( $key in $paramList.Keys ) {
    $value = (Get-Variable $key -ErrorAction SilentlyContinue).Value
    if ( $value -or $value -eq 0 ) {
        Write-Host "$key -> $value"
    }
}

答案 3 :(得分:2)

对于那些不想使用cmdletbinding()的人来说,这是我在上面找到的一种衬纸的变体:

(Get-Command -Name $PSCommandPath).Parameters | Format-Table -AutoSize @{ Label = "Key"; Expression={$_.Key}; }, @{ Label = "Value"; Expression={(Get-Variable -Name $_.Key -EA SilentlyContinue).Value}; }

$ PSCommandPath始终可用

答案 4 :(得分:1)

我在这个帖子中玩了我喜欢的2个解决方案,它们都有效。 但是我需要在构建脚本的缺失参数上产生错误

   $cmdName = $MyInvocation.InvocationName 
   $paramList = (Get-Command -Name $cmdName).Parameters
     foreach ( $key in $paramList.Keys ) {
     $value = (Get-Variable $key -ErrorAction Stop)
     #Write-Host $value.Value #remove comment for error checking
        if ([string]::IsNullOrEmpty($value.Value)){ 
        $(throw ("$key is a mandatory value please declare with -$key <Required value> " ))
        }
       }

答案 5 :(得分:1)

希望有些人可能会觉得这个单行有用:

function test()
{
    Param(
        [string]$foo,
        [string]$bar,
        [string]$baz = "baz"
    )

    $MyInvocation.MyCommand.Parameters | Format-Table -AutoSize @{ Label = "Key"; Expression={$_.Key}; }, @{ Label = "Value"; Expression={(Get-Variable -Name $_.Key -EA SilentlyContinue).Value}; }
}
test -foo "foo!"

结果

Keys Value
---- -----
foo  foo! 
bar       
baz  baz  

答案 6 :(得分:1)

适用于 simple 和 advanced 函数和脚本的最简单的解决方案是使用 automatic $PSBoundParameter variable,这是一个包含绑定参数及其值(参数).

  • 注意:$PSBoundParameters包括由默认值绑定的参数,只包括那些参数明确的参数通过;对于您的用例,这实际上是可取的,但在应通过参数传递的情况下,可能需要包含默认值参数 - 请参阅 GitHub issue #3285
function test()
{
  param(
    [string]$foo,
    [string]$bar,
    [string]$baz = "baz"
  )

  # Process all explicitly bound parameters ...
  $PSBoundParameters.GetEnumerator().ForEach({
      # ... and output an object naming the parameter and its value.
      [pscustomobject] @{
        Parameter = $_.Key
        Value = $_.Value
      }
  })
 
}

test -foo "foo!" -bar none

以上结果如下:

Parameter Value
--------- -----
foo       foo!
bar       none

答案 7 :(得分:0)

如果我不知道将传递哪些参数或传递多少参数怎么办?例如,可以使用以下命令调用该函数:

test -foo "value1" -bar "value2" -baz "value3"

其他人可能会这样称呼它:

test -variable1 "somevalue" -variable2 "somevalue2" -variable3 "somevalue3" -variable4 "value4"

我查看了 $MyInvocation,参数作为 UnboundArguments 出现,因此理论上我可以将参数 0 与参数 1、2 与 3 等“配对”,并且如果 UnboundArguments 的数量为奇数,则会出错。< /p>