Dynamic ValidateSet in a Dynamic Parameter

A colleague of mine needed a way to have a parameter accept only a specific set of paths. I told him this can be accomplished easily with the ValidateSet decoration on the parameter, but he then explained that what the actually needed, is to have the set dynamically defined by the sub folders in the current location, instead of a pre-defined set. This sent me out on a journey to explore the dynamic parameter world.

The result of that journey, and the answer to his request is the example function below:

function Test-DynamicValidateSet {
        # Any other parameters can go here
    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

            # 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

            # 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
        $Path = $PsBoundParameters[$ParameterName]

    process {
        # Your code goes here
        dir -Path $Path


and then you can use it:

Test-DynamicValidateSet -Path [the magic happens here]



Comments (17)

  1. David Wyatt says:

    You can do exactly the same in a C# Cmdlet. The IDynamicParameters.GetDynamicParameters() method can either return an object that has properties with Parameter attributes (as seen in the linked PowerShellMagazine article), or a RuntimeDefinedParameterDictionary,
    as seen here in the PowerShell code.

  2. @Anonymous, I agree it’s easier in PowerShell. That’s why I like it so much.
    Maybe this article can help you a bit:

  3. @Stephen Owen, unfortunately there is no way of doing what you ask.
    But you could combine both ways: Using the external xml or csv file you mentioned AND dynamically generating it’s content.
    In the DynamicParam block, check the file’s LastWriteTime, if it’s sufficiently new (X days / X Hours / X minutes), use it for the ValidateSet. If not, regenerate it and then use it.

  4. Great, this is really helpful!

  5. Stephen Owen says:

    This is sweet! Do you know of a method to trigger the auto-expansion of tab-completed fields?

    I’m in a situation where I’m using this technique to populate a list of OUs for an account migration tool, and it can take a very long time to the values to become available.

    Any tips? I could, of course, export the list of values as an .XML or CSV file and then use switching to provide an easy mechanism for the end user to select the appropriate field, but that gets me farther away from the realm of dynamic.

  6. Vasil Michev says:

    Awesome stuff!

  7. Anonymous says:

    Any idea how to do similar dynamic parameter validation, if the cmd-let was written in C#? IDynamicParameters interface doesn’t seem to be anywhere close to the capability above (available if function / cmdlet was written in Powershell instead of C#)

  8. I Love Pictures says:

    That was cool
    Put the function into a module named "Test Dynamic Parameters"
    Created a test folder with 3 folders in it (C:TestFolder1)
    I did not run the function but did manage to take a picture


  9. michal says:

    Do you know if there is possible to generate validateset for dynamic parameter depends on value of other dynamic parameter? For example I generate validateset for DynParam1. Next I check value of DynParam1 and then generate DynParam2 validateset.

    1. Cameron Ove says:

      I know this is really old but here is an article that explains exactly what you are asking for…


  10. alex says:

    Same question as Michal, already spent few days googling – no luck:(

  11. Dan Stevens says:

    How do you do this in a C# binary Powershell module?

  12. Torben Dohrn says:

    Hi Martin,

    thanks for this very helpful snippet. I wonder, if I can use your DynamicParam (in a modified version) in a contribution to a Open Source Project, which could use some Windows love. And if so, would you like to get mentioned?

  13. Martin,

    This is pretty awesome! I used an array on the $ValidateSetAttribute (I basically needed a single place to update my constant set where I have several functions using the same set.) I have two questions:

    1. Can the dynamic validate be set up in a way to run outside the function using it?
    2. How could this be utilized for multiple dynamic sets?

    Thank you.

Skip to main content