【问题标题】:Is there a way in powershell to catch ALL named parameters有没有办法在 powershell 中捕获所有命名参数
【发布时间】:2012-07-06 13:06:03
【问题描述】:

考虑一下:

Function Foo 
{
    param(
        #????
    )
}

我想这样称呼 Foo:

Foo -Bar "test"

如果我没有指定 $bar 参数,它不会爆炸。那可能吗? :)

更新:

我想让这个工作:

Function IfFunctionExistsExecute
{
    param ([parameter(Mandatory=$true)][string]$func, [parameter(Mandatory=$false)][string]$args)
    begin 
    {
        # ...
    }
    process
    {
        if(Get-Command $func -ea SilentlyContinue)
        {
            & $func $args   # the amperersand invokes the function instead of just printing the variable
        }
        else
        {
            # ignore
        }       
    }
    end
    {
        # ...
    }
}


Function Foo
{
    param([string]$anotherParam)
    process 
    {
        $anotherParam
    }
}

IfFunctionExistsExecute Foo -Test "bar"

这给了我:

IfFunctionExistsExecute : A parameter cannot be found that matches parameter name 'Test'.
At C:\PSTests\Test.ps1:35 char:34
+ IfFunctionExistsExecute Foo -Test <<<<  "bar"
    + CategoryInfo          : InvalidArgument: (:) [IfFunctionExistsExecute], ParameterBindingException
    + FullyQualifiedErrorId : NamedParameterNotFound,IfFunctionExistsExecute

【问题讨论】:

    标签: function powershell arguments


    【解决方案1】:

    我会建议两种选择。

    首先:您可能需要考虑将整个函数 + 它的参数作为脚本块参数传递给您的 ifFunction...

    或者:使用 ValueFromRemainingArguments:

    function Test-SelfBound {
    param (
        [Parameter(
            Mandatory = $true,
            HelpMessage = 'Help!'
        )]
        [string]$First,
        [Parameter(
            ValueFromRemainingArguments = $true
        )]
        [Object[]]$MyArgs
    )
    
    $Arguments = foreach ($Argument in $MyArgs) {
        if ($Argument -match '^-([a-z]+)$') {
            $Name = $Matches[1]
            $foreach.MoveNext() | Out-Null
            $Value = $foreach.Current
            New-Variable -Name $Name -Value $Value
            $PSBoundParameters.Add($Name,$Value) | Out-Null
        } else {
            $Argument
        }
    }
        $PSBoundParameters | Out-Default
        "Positional"
        $Arguments
    
    }
    
    Test-SelfBound -First Test -Next Foo -Last Bar Alfa Beta Gamma
    

    在这种情况下,我使用 $MyArgs 来存储除了我的强制参数“First”之外的所有内容。比一些简单的 if 会告诉我它是命名参数(-Next,-Last)还是位置(Alfa,Beta,Gamma)。这样,您可以同时拥有高级函数绑定的优势(整个 [Parameter()] 装饰)并为 $args 样式的参数留出空间。

    【讨论】:

    • 如果我调用Test-SelfBound -out foo 会收到错误:无法处理参数,因为参数名称“out”不明确。可能的匹配项包括: -OutVariable -OutBuffer 。如果我调用Test-SelfBound -d foo,它不会声明一个名为“d”的变量,而是一个名为“Debug”的变量:-(我想这会发生在所有common parameters 上:-(
    • True:函数定义使其成为高级函数(由[Parameter()]装饰触发),因此它总是定义了公共参数。
    • --$Argument -match '^-([\S]+)$'-- 会更好。我们只需要空白。最佳样品
    【解决方案2】:

    您可以在函数中使用 $args 变量,它是传递给函数的参数数组,例如

    function Foo()
    {
        Write-Output $args[0];
        Write-Output $args[1];
    }
    
    Foo -Bar "test"
    

    输出:

    -Bar
    test
    

    【讨论】:

    • 而不是包含传递给函数的所有参数 $args 将包含所有未绑定的参数
    猜你喜欢
    • 2013-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-30
    • 1970-01-01
    • 2015-11-09
    • 2011-02-12
    相关资源
    最近更新 更多