PowerShell Dynamic Validate Set

When writing advanced PowerShell functions you may have to add a parameter with a validate set that is created dynamically. Let me use an example to make thing clearer.

I was writing a function that has the ability to query different Active Directory forests. That function is actually a wrapper for the Find-LDAPObject cmdlet and provides a better interface by saving the configuration of each directory in a csv file. Each row of the csv file contains the name of the directory, the server and port to connect, the root DN of the directory and the credentials to use.

What I wanted to achieve was to create a validate set that would contain all the names of directories in the csv file, so that the user would be able to choose amongst them.

Martin Schvartzman has posted a great article on dynamic validate sets that proved to be very helpful! The way to create a dynamic validate set is to create the entire parameter in the function code.

We'll start with the standard advanced function code:
function Test-DynamicValidateSet {
    [CmdletBinding()]
    Param(
        # Any other parameters can go here
    )
Next we are going to add a script block that is going to be the parameter:
DynamicParam {
    # Set the dynamic parameters' name
    $ParameterName = 'Path'
    
    # 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
 
    # Add the attributes to the attributes collection
    $AttributeCollection.Add($ParameterAttribute)
 
    # Generate and set the ValidateSet 
    $arrSet = Get-ChildItem -Path .\ -Directory | Select-Object -ExpandProperty FullName
    $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
}
The key part here is the "$arrSet" variable. This is the variable that has to contain the values for the validate set. I've changed my code here to import the csv and select the values from the respective column.

Finally, we'll add the new parameter in the begin block in order for it to be available:
begin {
        # Bind the parameter to a friendly variable
        $Path = $PsBoundParameters[$ParameterName]
    }
There's nothing else you need to add, just continue with the function code:
process {
        # Your code goes here
        dir -Path $Path
    }
}

Popular posts from this blog

Domain Controller Machine Password Reset

Configuring a Certificate on Exchange Receive Connector

Running Multiple NGINX Ingress Controllers in AKS