James W
James W

Reputation: 39

Can a Powershell parameter's valid set vary depending on a preceding parameter?

Suppose that I wanted to create a function, Make-Dinner. This function takes two parameters {food, variant}. The valid set for food is {pizza, chicken}. However, the valid set for variant depends on the type of food selected. If the user chooses pizza, then the valid set of variants is {cheese, pepperoni}. If the user chooses chicken, then the valid set of variation {fried, grilled}.

Can a PowerShell function be created that implements this?

SYNTAX
  Make-Dinner -Food {Pizza, Chicken}
  Make-Dinner -Food Pizza -Variant {Cheese, Pepperoni}
  Make-Dinner -Food Chicken -Variant {Fried, Grilled}

I would strongly prefer to use ValidateSet for the intellisense features.

Upvotes: 1

Views: 259

Answers (1)

qbik
qbik

Reputation: 5938

Powershell has this cool feature called Dynamic Parameters, which allows you to do exactly that - define parameters based on other parameters. The full code could look like this:

function Make-Dinner {
[CmdletBinding()]
param(
    [ValidateSet("Pizza","Chicken")]
    $food
)

DynamicParam
{
    $attributes = new-object System.Management.Automation.ParameterAttribute
    $attributes.ParameterSetName = "__AllParameterSets"
    $attributes.Mandatory = $false
    $attributeCollection = new-object -Type System.Collections.ObjectModel.Collection[System.Attribute]
    $attributeCollection.Add($attributes)

    $validvalues = switch($food)
    {
        "Pizza" { "Cheese","Pepperoni" }
        "Chicken" { "Fried","Grilled" }
        default { "" }
        #$dynParam1 
    }

    $validateset = new-object System.Management.Automation.ValidateSetAttribute -ArgumentList @($validvalues)
    $attributeCollection.Add($validateset)
    $dynParam1 = new-object -Type System.Management.Automation.RuntimeDefinedParameter("Variant", [string], $attributeCollection)

    $paramDictionary = new-object -Type System.Management.Automation.RuntimeDefinedParameterDictionary
    $paramDictionary.Add("Variant", $dynParam1)

    return $paramDictionary
}
Process {    
    $Variant = $PSBoundParameters["Variant"]
    write-host "will make you a $food of variant $Variant"
}
}

Intellisense Sample

Upvotes: 2

Related Questions