Correct usage of [Validatenotnullorempty]

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?

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 ‘’

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: (:slight_smile: [test], ParameterBindingValidationException
    • FullyQualifiedErrorId : ParameterArgumentValidationError,test

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

@Daniel - thanks for the reply
@Richard - thanks for the detailed explanation. certainly clears things up :slight_smile:

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

}

@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 :slight_smile:
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 :).