My goal is to have a parameter for a powershell functions that supports both
I was able to achieve #1, but looks like #2 fails.
Here's a simplified example of my code: initially i had a simple function that prints all parameter names that were supplied to the function. the ValidateSet was static and not generated at runtime. the function is defined as following:
Function Test-Static {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true, ValueFromPipeline = $true, Position=1)]
[ValidateSet("val1","val2")]
$Static
)
begin {}
process {
Write-Host "bound parameters: $($PSBoundParameters.Keys)"
}
}
when running the following code
"val1" | Test-Static
the output is
bound parameters: Static
I then moved on to try to do the exact same thing with a dynamic parameter, but it looks like $PsBoundParameters
is empty. note that if i'm supplying the value as an argument and not via the pipeline, it does show up in $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 {
}
}
when running
"val1" | test-Dynamic
i'm getting the following result:
bound parameters:
which basically means that no parameters are bound.
What am i doing wrong? How can i achieve my original goal?
@CB has the right idea here.
You can't access the pipeline data from the begin
block; only from the process
block.
The begin
block will have access to the parameter if it's passed as a named or positional parameter, but not via the pipeline.
This is true whether you're using dynamic parameters or not.