G684
G684

Reputation: 86

Validate parameter value using another parameter value

I'm trying to validate whether a path exists before running a function. There is no default for the folder path, but the file name default should be template.csv. Is there a way, through the ValidateScript attribute, to validate a parameter value based on another parameter value?

The below code returns the error that the variable $TemplateDir has not been set. I'm also not entirely sure if it would test for the default file name value.

function get-Template {   
    [CmdletBinding()]
    Param (
        [Parameter(Mandatory = $true, Position = 0)]
        [ValidateScript({Test-Path $_})]
        [string]$TemplateDir,

        [Parameter(Mandatory = $false)]
        [ValidateScript({Test-Path ($TemplateDir + "\" + $_)})]
        [string]$TemplateFile = "template.csv"
    )

    ...

}

Any advice?

Upvotes: 2

Views: 1653

Answers (1)

Mathias R. Jessen
Mathias R. Jessen

Reputation: 175065

You can set up a dynamic parameter with the DynamicParam block, that depends on the value of another mandatory parameter:

function Get-FilePath
{
    Param (
        [Parameter(Mandatory = $true, Position = 0)]
        [ValidateScript({Test-Path $_})]
        [string]$TemplateDir
    )

    DynamicParam {
        # Set up parameter attribute
        $fileParamAttribute = New-Object System.Management.Automation.ParameterAttribute
        $fileParamAttribute.Position = 3
        $fileParamAttribute.Mandatory = $false
        $fileParamAttribute.HelpMessage = "Please supply a file name"

        # Set up ValidateSet param with actual file name values
        $fileValidateParam = New-Object System.Management.Automation.ValidateSetAttribute @(Get-ChildItem $TemplateDir -File |Select-Object -ExpandProperty Name)

        # Add the parameter attributes to an attribute collection
        $attributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
        $attributeCollection.Add($fileParamAttribute)
        $attributeCollection.Add($fileValidateParam)

        # Create the actual $TemplateFile parameter
        $fileParam = New-Object System.Management.Automation.RuntimeDefinedParameter('TemplateFile', [string], $attributeCollection)

        # Push the parameter(s) into a parameter dictionary
        $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
        $paramDictionary.Add('TemplateFile', $fileParam)

        # Return the dictionary
        return $paramDictionary
    }

    begin{
        # Check if a value was supplied, otherwise set it
        if(-not $PSBoundParameters.ContainsKey('TemplateFile'))
        {
            $TemplateFile = 'template.csv'
        }

        $myPath = Join-Path $TemplateDir -ChildPath $TemplateFile
    }

    end {
        return $myPath
    }
}

This will also give you automatic tab completion for the arguments to -TemplateFile

You can read more about DynamicParam with Get-Help about_Functions_Advanced_Parameters

Upvotes: 3

Related Questions