none
Understanding [ValidateNotNullOrEmpty()] RRS feed

  • Question

  • Here's my function:

    Function test([ValidateNotNullOrEmpty()] $Name)
    {
     "Name: $Name"
    }
    

    When I call it with no parameters ('test'), I see

    PS Z:\PowerShell> test
    Name:

    The [ValidateNotNullOrEmpty()] doesn't seem to do anything.  What am I missing?

    Thanks


    GregM
    Tuesday, June 28, 2011 6:08 PM

Answers

  • $obj = new-object system.object
    [bool]$obj
    True

    that makes more sense now... at least as to why its working the way it does... so does it return true because the object exists? I assume that’s the case because if I do

    [bool] $abc

    I get false..

    I find it odd, and it would be nice if there was some way to check for this since some times I want to be able to pass in a variety of types... but I agree, its not a bug..

    I've learned more about programming and .NET in this forum than I have in all the years I've been programming.

    Thanks Kazun


    Justin Rich
    http://jrich523.wordpress.com
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    • Marked as answer by Bruce-Liu Monday, July 11, 2011 7:56 AM
    Wednesday, June 29, 2011 5:11 PM

All replies

  • I think that you would need to make the param mandatory to get the test that you are really looking for.
    Tuesday, June 28, 2011 6:14 PM
  • No problem.  New script -

    Function test([Parameter(Mandatory=$true)]
           [ValidateNotNullOrEmpty()] $Name)
    {
     "Entered Name: $Name"
    }
    
    

    Results -

    PS Z:\PowerShell> . .\test.ps1
    PS Z:\PowerShell> test

    cmdlet test at command pipeline position 1
    Supply values for the following parameters:
    Name:
    Entered Name:

    Again, did not get the behavior I expected.  Any other ideas?


    GregM
    Tuesday, June 28, 2011 6:19 PM
  • Well I'm not sure what you expected, but that behavior is correct. You told it that the para was required. When the param was not provided it threw an error. The ValidateNotNullOrEmpty() validation just checks the supplied parameter to verify that it is not null or empty. If the parameter is not supplied at all there is nothing to check. Note that this is not the same thing as being null or empty.
    Tuesday, June 28, 2011 6:24 PM
  • From this article: http://blog.usepowershell.com/2011/05/parameter-validation/

     

    "

    ValidateNotNull(OrEmpty) vs. Mandatory

    Neither ValidateNotNull nor ValidateNotNullOrEmpty force a parameter to be declared.  The validations only have an impact if values (or lack thereof) are actually declared or passed in via the pipeline.  If you would like to make a parameter required, you can set the Mandatory flag in the Parameter attribute.

    param(
     [parameter(Mandatory=$true)]
     [string[]]
     $ComputerName
    )

    This will make the parameter required and does protect against both empty strings and empty arrays, so you will not need to use either of those validation attributes. "

    Tuesday, June 28, 2011 6:27 PM
  • It doesn't throw an error.  New script -

    Function test([Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()] $Name)
    {
     "Entered Name: $Name"
     if ([string]::IsNullOrEmpty($Name))
    {
     Throw "Hey, it's null or empty! What gives!"
    }
    "Life is good $Name"
    }
    
    
    


    And the results -

    PS Z:\PowerShell> . .\test.ps1
    PS Z:\PowerShell> test

    cmdlet test at command pipeline position 1
    Supply values for the following parameters:
    Name:
    Entered Name:
    Hey, it's null or empty!  What gives!
    At Z:\InstallMedia\PowerShell\Intelink Modules\Firewall\test.ps1:7 char:8
    +   Throw <<<<  "Hey, it's null or empty!  What gives!"
        + CategoryInfo          : OperationStopped: (Hey, it's null or empty!  What gives!:String) [], RuntimeException
        + FullyQualifiedErrorId : Hey, it's null or empty!  What gives!

    So, the [ValidateNotNullOrEmpty()] attribute let a null or empty value in, as demonstrated by the string test.

    This seems contrary to what you posted.


    GregM
    Tuesday, June 28, 2011 6:29 PM
  • It actually did not let anything in at all, null or otherwise.
    Tuesday, June 28, 2011 6:31 PM
  • To put it another way It only validates the input that is provided. So if no input is provided at all no validation is done at all. Madatory is what you use to make sure that input is provided and that input is not null or empty.
    Tuesday, June 28, 2011 6:33 PM
  • Sure it did.  The value of the $Name is null.

    Now, if the argument is that this attribute only works on items passed in through the pipeline (cause that's what the doc post you put in seems to say), I can buy that.

    I used both Mandatory and ValidateNotNullOrEmpty.


    GregM
    Tuesday, June 28, 2011 6:39 PM
  • Ok, so I understand the behavior that is confusing now. I'm beginning to think bug. Apparently not giving anything for a mandatory param causes PS to request the mandatory information then bypasses all further validation even if you simply hit return at the input request. With your code, if you do:

     

    test -name

     

    You should see the behavior that I am familiar with. I did not know that once PS requests the required parameter, validation stops.

    Tuesday, June 28, 2011 6:50 PM
  • hmm interesting, I find it rather odd (probably a bug) that it doesn’t validate if powershell prompts for a mandatory param.


    Justin Rich http://jrich523.wordpress.com Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Tuesday, June 28, 2011 6:57 PM
  • Well thank goodness.

    I was thinking I didn't understand what you were trying to say.

    I did try 'test -name' and it does fail like one would expect.

    So, anyone know where MS keeps it's list of PS bugs?


    GregM
    Wednesday, June 29, 2011 11:55 AM
  • http://connect.microsoft.com/PowerShell


    Justin Rich
    http://jrich523.wordpress.com
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Wednesday, June 29, 2011 12:32 PM
  • I don't understand where is a  bug.
    function test {
    Param
         (
          [parameter(Mandatory=$true)]
          [String[]]
          [ValidateNotNullOrEmpty()]
          $UserName
         ) 
    $UserName
    }
    
    PS 35 # test
    
    cmdlet test at command pipeline position 1
    Supply values for the following parameters:
    UserName[0]:
    test : Cannot validate argument on parameter 'UserName'. The argument is null, empty, or an element of the argument co
    lection contains a null value. Supply a collection that does not contain any null values and then try the command agai
    .
    
    PS 36 # test -UserName
    test : Missing an argument for parameter 'UserName'. Specify a parameter of type 'System.String[]' and try again.
    At line:1 char:15
    + test -UserName <<<<
      + CategoryInfo     : InvalidArgument: (:) [test], ParameterBindingException
      + FullyQualifiedErrorId : MissingArgument,test
    
    PS 37 # test -UserName ""
    test : Cannot validate argument on parameter 'UserName'. The argument is null or empty. Supply an argument that is not
    null or empty and then try the command again.
    At line:1 char:15
    + test -UserName <<<< ""
      + CategoryInfo     : InvalidData: (:) [test], ParameterBindingValidationException
      + FullyQualifiedErrorId : ParameterArgumentValidationError,test
    
    PS 38 # test -UserName $null
    test : Cannot validate argument on parameter 'UserName'. The argument is null or empty. Supply an argument that is not
    null or empty and then try the command again.
    At line:1 char:15
    + test -UserName <<<< $null
      + CategoryInfo     : InvalidData: (:) [test], ParameterBindingValidationException
      + FullyQualifiedErrorId : ParameterArgumentValidationError,test
    
    PS 39 # test -UserName $isnotpresent
    test : Cannot validate argument on parameter 'UserName'. The argument is null or empty. Supply an argument that is not
    null or empty and then try the command again.
    

    • Proposed as answer by Vector BCO Monday, March 16, 2020 9:52 AM
    • Unproposed as answer by Vector BCO Monday, March 16, 2020 9:53 AM
    Wednesday, June 29, 2011 3:49 PM
  • hmm so why does it only work right if you specify a type?

    remove your [string[]] and it breaks.


    Justin Rich
    http://jrich523.wordpress.com
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Wednesday, June 29, 2011 3:58 PM
  • hmm so why does it only work right if you specify a type?

    remove your [string[]] and it breaks.


    Justin Rich
    http://jrich523.wordpress.com
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Nope.

    PS 8 > function test {
    >> Param
    >>   (
    >>    [parameter(Mandatory=$true)]
    >>    [ValidateNotNullOrEmpty()]
    >>    $UserName
    >>   )
    >> $UserName
    >> }
    >>
    PS 9 > test ""
    test : Cannot validate argument on parameter 'UserName'. The argument is null or empty. Supply an argument that is not
    null or empty and then try the command again.
    At line:1 char:5
    + test <<<< ""
      + CategoryInfo     : InvalidData: (:) [test], ParameterBindingValidationException
      + FullyQualifiedErrorId : ParameterArgumentValidationError,test
    
    PS 10 > test $null
    test : Cannot validate argument on parameter 'UserName'. The argument is null or empty. Supply an argument that is not
    null or empty and then try the command again.
    At line:1 char:5
    + test <<<< $null
      + CategoryInfo     : InvalidData: (:) [test], ParameterBindingValidationException
      + FullyQualifiedErrorId : ParameterArgumentValidationError,test
    
    PS 11 > test $isnotpresent
    test : Cannot validate argument on parameter 'UserName'. The argument is null or empty. Supply an argument that is not
    null or empty and then try the command again.
    At line:1 char:5
    + test <<<< $isnotpresent
      + CategoryInfo     : InvalidData: (:) [test], ParameterBindingValidationException
      + FullyQualifiedErrorId : ParameterArgumentValidationError,test
    
    PS 12 > test -UserName
    test : Missing an argument for parameter 'UserName'. Specify a parameter of type 'System.Object' and try again.
    At line:1 char:15
    + test -UserName <<<<
      + CategoryInfo     : InvalidArgument: (:) [test], ParameterBindingException
      + FullyQualifiedErrorId : MissingArgument,test
    
    PS 13 > test -UserName ""
    test : Cannot validate argument on parameter 'UserName'. The argument is null or empty. Supply an argument that is not
    null or empty and then try the command again.
    At line:1 char:15
    + test -UserName <<<< ""
      + CategoryInfo     : InvalidData: (:) [test], ParameterBindingValidationException
      + FullyQualifiedErrorId : ParameterArgumentValidationError,test
    
    PS 14 > test -UserName $null
    test : Cannot validate argument on parameter 'UserName'. The argument is null or empty. Supply an argument that is not
    null or empty and then try the command again.
    At line:1 char:15
    + test -UserName <<<< $null
      + CategoryInfo     : InvalidData: (:) [test], ParameterBindingValidationException
      + FullyQualifiedErrorId : ParameterArgumentValidationError,test
    


    Wednesday, June 29, 2011 4:01 PM
  • [11:57:04]D:\ps>function test {

    Param
         (
          [parameter(Mandatory=$true)]
          [ValidateNotNullOrEmpty()]
          $UserName
         )
    $UserName
    }

    [11:58:32]D:\ps>test hello
    hello
    [11:58:34]D:\ps>test

    cmdlet test at command pipeline position 1
    Supply values for the following parameters:
    UserName:     ##<<< just hit enter
        ##<< function ran with no error and no display
    [11:58:36]D:\ps>


    Justin Rich
    http://jrich523.wordpress.com
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Wednesday, June 29, 2011 4:14 PM
  • So it's a matter of perspective, perhaps.

    What is the official definition of the two parameter attributes.

    I'm looking for a way to guarantee that a parameter is supplied and it's not null.  I say it that way since you can supply a null parameter by name.

    If the PS team as MS decides that the current behavior is correct, then I would ask for an attribute to provide the needed behavior.


    GregM
    Wednesday, June 29, 2011 4:35 PM
  • $obj = new-object system.object
    [bool]$obj
    True

    that makes more sense now... at least as to why its working the way it does... so does it return true because the object exists? I assume that’s the case because if I do

    [bool] $abc

    I get false..

    I find it odd, and it would be nice if there was some way to check for this since some times I want to be able to pass in a variety of types... but I agree, its not a bug..

    I've learned more about programming and .NET in this forum than I have in all the years I've been programming.

    Thanks Kazun


    Justin Rich
    http://jrich523.wordpress.com
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    • Marked as answer by Bruce-Liu Monday, July 11, 2011 7:56 AM
    Wednesday, June 29, 2011 5:11 PM
  • ValidateNotNullOrEmpty attribute is mapped to the [System.String]::IsNotNullOrEmpty  method call. So if you are not passing a string PS will call $_.ToString() on the param and pass its result to the method. If you look at the about file on parameter validation, it clearly states that this Attribute is for validating string input by checking if the input is $null or "". Validation of an object would use ValidateNotNull. strings default state is empty, numbers default state is 0, and Objects default state is null. It is very important to know what validation is correct for the type of input you expect. Cool tip Use ValidateScript attribute and you can do any kind of validation you desire. the Attribute takes a scriptblock {} and it must return $true.

    These will do the same check as ValidateNotNullOrEmpty:

    [ValidateScript({ (($PsItem -ne $null) -and ($PsItem -ne [String]::Empty)) })]

    [ValidateScript({ -not ([System.String]::IsNotNullOrEmpty($PSItem)) } )]

    Enjoy! :)

    Good-Time and Get-Command


    • Edited by qa_warrior Tuesday, June 18, 2013 6:15 PM
    Tuesday, June 18, 2013 6:12 PM