Correct usage of [Validatenotnullorempty]

This topic contains 5 replies, has 4 voices, and was last updated by Profile photo of touchstone_81 touchstone_81 2 years, 6 months ago.

  • Author
    Posts
  • #15844
    Profile photo of touchstone_81
    touchstone_81
    Participant

    Hi

    I have this function that accepts a directory fullname as inpu and just returns that and i would like it to throw an exception if a null or empty value is passed or when no value is passed at all.

    function test {
    Param
    (
    [Alias('FullName')]
    [parameter(Mandatory=$true,ValueFromPipeLine=$true,ValueFromPipeLineByPropertyName=$true)]
    [ValidateNotNullOrEmpty()]
    [string]$Path
    )
    $path
    }

    PS C:\> dir c:\ -Filter users | test
    C:\Users

    PS C:\> dir c:\ -Filter Idontexist| test

    Expecting an error saying a null or empty value was passed but no errors?

    Is this expected behavior. Could someone clarify?

  • #15845
    Profile photo of Daniel Krebs
    Daniel Krebs
    Participant

    Yes. You're using the pipeline which is good but your command "dir c:\ -Filter Idontexist" does not return any objects into the pipeline. Therefore your "test" function does not get invoked at all.

    If you run your function like below you'll see [ValidateNotNullOrEmpty()] in action.

    PS C:\> test -Path $null

    PS C:\> test -Path "

  • #15846
    Profile photo of Richard Siddaway
    Richard Siddaway
    Moderator

    The behaviour is expected.

    Try this

    £> test

    cmdlet test at command pipeline position 1
    Supply values for the following parameters:
    Path:
    test : Cannot validate argument on parameter 'Path'. The argument is null or empty. Provide an argument that is not
    null or empty, and then try the command again.
    At line:1 char:1
    + test
    + ~~~~
    + CategoryInfo : InvalidData: (:) [test], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,test

    You've called the function with an empty path & generated the error

    If you look at your dir command
    £> dir c:\ -Filter Idontexist

    Nothing is returned – which means that nothing is on the pipeline so your test function isn't called because no objects enter that part of the pipeline

    If you call the function like this

    £> test -Path (dir c:\ -Filter Idontexist)
    test : Cannot validate argument on parameter 'Path'. The argument is null or empty. Provide an argument that is not
    null or empty, and then try the command again.
    At line:1 char:12
    + test -Path (dir c:\ -Filter Idontexist)
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidData: (:) [test], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,test

    you'll see the error because you're passing in an empty path.

  • #15847
    Profile photo of touchstone_81
    touchstone_81
    Participant

    @daniel – thanks for the reply
    @Richard – thanks for the detailed explanation. certainly clears things up 🙂

  • #15880
    Profile photo of touchstone_81
    touchstone_81
    Participant

    @mike – I agree using validatescript that returns true\false is a nice trick. I had picked it up from a script posted by jeff hicks i think, cannot remember the link though but thanks for posting it; should be helpful to the community. Also i use write-warning instead of "throw" because it shows the message in a color that is easier on the eye 🙂
    of course there are people who would want to change the default color of the error message from red to something else but for my purposes the defaults work :).

  • #15848
    Profile photo of Mike F Robbins
    Mike F Robbins
    Participant

    You could also use ValidateScript to verify the path does exist instead of just validating it isn't null or empty. Although you'll run into the same issue with the scenario you've described (as Richard said in the previous comment, test is not invoked in your scenario).

    
    function test {
    
        param (
            [Alias('FullName')]
            [parameter(Mandatory=$true,
                       ValueFromPipeLine=$true,
                       ValueFromPipeLineByPropertyName=$true)]
            [ValidateScript({Test-Path $_ -PathType Container})]
            [string]$Path
        )
    
        $path
    
    }
    

    Any of these would generate the expected error:

    
    '' | test
    
    $null | test
    
    'C:\IDontExist' | test
    

    I have a blog where I used this method in a scripting games event.

    You could also do something like this for a customizable error message:

    
    function test {
    
        [CmdletBinding()]
        param (
            [Alias('FullName')]
            [parameter(Mandatory=$true,
                       ValueFromPipeLine=$true,
                       ValueFromPipeLineByPropertyName=$true)]
            [ValidateScript({
                If (Test-Path $_ -PathType Container) {
                    $True
                }
                else {
                    Throw "$_ is not a valid directory on the computer named: $env:COMPUTERNAME."
                }
            })]
            [string]$Path
        )
    
        $path
    
    }
    

You must be logged in to reply to this topic.