2

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?

1 Answer 1

3

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

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks @mathias-r-jessen! Very insightful (for someone fairly new at PS). What is the reason you include the begin{} and end{} blocks?
I've made some minor suggestions in your code. Most importantly the $TemplateFile var wasn't being populated when a valid file name was provided, hence the return path incomplete. I couldn´t get the ValidateSet and tab completion to work. -TemplateFile is hidden once I provide a -TemplateDir, no auto tab completion. However, it runs fine... Finally, the default file name is not being tested now. I can easily test this in the begin {} block, but I'd thought that the most appropriate way would be through the ValidateScript, where i also test the Dir path. Is this possible?
The edits were rejected, deviating from your original intent(?). Very little information to go on unfortunately, but would appreciate your feedback. Cheers

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.