如何在 Powershell 中从管道获取 DynamicParam 的值

how to get Value from pipeline for a DynamicParam in powershell

我的目标是为支持两者的 powershell 函数提供一个参数

  1. 仅在运行时已知的集合的 ValidateSet(和制表符完成)
  2. 能够通过管道提供参数。

我能够实现#1,但看起来#2 失败了。

这是我的代码的一个简化示例: 最初我有一个简单的函数,它打印提供给该函数的所有参数名称。 ValidateSet 是静态的,不是在运行时生成的。函数定义如下:

Function Test-Static {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$true, ValueFromPipeline = $true, Position=1)]
        [ValidateSet("val1","val2")]
        $Static
    )

    begin {}
    process {
    Write-Host "bound parameters: $($PSBoundParameters.Keys)"
    }
}

当运行下面的代码

"val1" | Test-Static

输出是

bound parameters: Static

然后我继续尝试使用动态参数做完全相同的事情,但看起来 $PsBoundParameters 是空的。请注意,如果我将值作为参数而不是通过管道提供,它 确实 出现在 $PsBoundParameters.

Function Test-Dynamic {
    [CmdletBinding()]
    Param(
    )

    DynamicParam {
            # Set the dynamic parameters' name
            $ParameterName = 'Dynamic'

            # Create the dictionary 
            $RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary

            # Create the collection of attributes
            $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]

            # Create and set the parameters' attributes
            $ParameterAttribute = New-Object System.Management.Automation.ParameterAttribute
            $ParameterAttribute.Mandatory = $true
            $ParameterAttribute.Position = 1
            $ParameterAttribute.ValueFromPipeline = $true

            # Add the attributes to the attributes collection
            $AttributeCollection.Add($ParameterAttribute)

            # Generate and set the ValidateSet 
            $arrSet = "val1","val2"
            $ValidateSetAttribute = New-Object System.Management.Automation.ValidateSetAttribute($arrSet)

            # Add the ValidateSet to the attributes collection
            $AttributeCollection.Add($ValidateSetAttribute)

            # Create and return the dynamic parameter
            $RuntimeParameter = New-Object System.Management.Automation.RuntimeDefinedParameter($ParameterName, [string], $AttributeCollection)
            $RuntimeParameterDictionary.Add($ParameterName, $RuntimeParameter)
            return $RuntimeParameterDictionary
    }

    begin {
        # Bind the parameter to a friendly variable
        write-host "bound parameters: $($PsBoundParameters.Keys)"
        $Param = $PsBoundParameters[$ParameterName]
    }

    process {
    }

}

当 运行

"val1" | test-Dynamic 我得到以下结果:

bound parameters:

这基本上意味着没有参数绑定。

我做错了什么?我怎样才能实现我最初的目标?

@CB 在这里有正确的想法。

您无法从 begin 块访问管道数据;仅来自 process 块。

如果参数作为命名参数或位置参数传递,但不是通过管道传递,begin 块将有权访问该参数。

无论您是否使用动态参数,都是如此。