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

Eri*_*eet 14 parameters powershell

我正在尝试找到一种从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!"
Run Code Online (Sandbox Code Playgroud)

我想获得的值$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!"
Run Code Online (Sandbox Code Playgroud)

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

更新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;
Run Code Online (Sandbox Code Playgroud)

Tre*_*van 23

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

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

码:

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;
Run Code Online (Sandbox Code Playgroud)

产量

命令的输出如下所示:

Name                           Value                                           
----                           -----                                           
Bar                            test                                            
Baz                                                                            
Asdf                           blah                                            
Run Code Online (Sandbox Code Playgroud)

  • 我认为你可以跳过 `$PSCmdlet` 和 `Get-Command`,只使用 `$MyInvocation.MyCommand.Parameters`,你可以循环遍历 `Parameters.Keys` 来获取参数名称。 (3认同)
  • 是的!这种方法正是我所寻找的。我最终不得不对脚本进行一些修改,因为我不断得到空值,但这绝对是正确的方法。谢谢! (2认同)
  • 还值得注意的是,`$PSCmdlet` 仅适用于显式的 `[CmdletBinding()]`,而 `$MyInvocation.MyCommand` 适用于所有函数。 (2认同)

Jar*_*Par 12

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

write-host (get-variable "foo")
Run Code Online (Sandbox Code Playgroud)

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

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

  • 很抱歉错过了,但看起来$ MyInvocation.BoundParameters.keys不包含$ bar和$ baz,只有实际有界参数.我真的很想获得可能已经设置了默认值的$ baz并且永远不会通过 (2认同)

csl*_*tty 5

我发现这对 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"
    }
}
Run Code Online (Sandbox Code Playgroud)


Jan*_*nos 5

希望有些人可能会发现这个单行有用:

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!"
Run Code Online (Sandbox Code Playgroud)

结果

Keys Value
---- -----
foo  foo! 
bar       
baz  baz  
Run Code Online (Sandbox Code Playgroud)


小智 5

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

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

$PSCommandPath 始终可用