Search code examples
powershellpowershell-cmdletparameter-setsvalidateset

Conditional Mandatory in PowerShell


I'm trying to make a parameter mandatory, but only if another parameter uses certain ValidateSet values. It seems that using a code block on Mandatory doesn't work as expected.

function Test-Me {
    [CmdletBinding()]
    Param (
        [Parameter()]
        [ValidateSet("NameRequired", "AlsoRequired")]
        [string]
        $Type = "NoNameRequired",

        [Parameter(Mandatory = {-not ($Type -eq "NoNameRequired")})]
        [string]
        $Name
    )

    Process {
        Write-Host "I ran the process block."
        Write-Host "Type = '$Type'"
        Write-Host "Name = '$Name'"
        Write-Host "Name Parameter Mandatory? = '$(-not ($Type -eq "NoNameRequired"))'"
    }
}

Solution

  • Set-StrictMode -Version Latest
    
    function Test-Me {
        [CmdletBinding(DefaultParameterSetName = "Gorgonzola")]
        Param (
    
            [Parameter(Mandatory)]
            [int]
            $Number,
    
            [Parameter(Mandatory, ParameterSetName = "NameNeeded")]
            [ValidateSet("NameRequired", "AlsoRequired")]
            [string]
            $Type = "NoNameRequired",
    
            [Parameter(Mandatory, ParameterSetName = "NameNeeded")]
            [string]
            $Name
        )
    
        Process {
            Write-Host "I ran the process block."
            Write-Host "Number = '$Number'"
            Write-Host "Type = '$Type'"
            Write-Host "Name = '$Name'"
            Write-Host "Name Parameter Mandatory = '$(-not ($Type -eq "NoNameRequired"))'"
        }
    }
    

    Parameter sets seem to help simulate conditional mandatory parameters.

    I can make it to where if either the Type or Name parameter is given, then they are both required. This can happen regardless of other parameters in the function, such as the sibling Number parameter above.

    I set the default parameter set name to something random; I usually specify "None". That parameter set name doesn't need to actually exist, again indicated by the Number parameter.

    All of this works regardless of your strict mode setting.