如何在 Powershell 中从管道获取 DynamicParam 的值
how to get Value from pipeline for a DynamicParam in powershell
我的目标是为支持两者的 powershell 函数提供一个参数
- 仅在运行时已知的集合的 ValidateSet(和制表符完成)
- 能够通过管道提供参数。
我能够实现#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
块将有权访问该参数。
无论您是否使用动态参数,都是如此。
我的目标是为支持两者的 powershell 函数提供一个参数
- 仅在运行时已知的集合的 ValidateSet(和制表符完成)
- 能够通过管道提供参数。
我能够实现#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
块将有权访问该参数。
无论您是否使用动态参数,都是如此。