Does a mandatory PowerShell parameter automatically reject null and empty strings?
Asked by
MellowCedar42
I noticed that PowerShell rejects null and empty values for a parameter declared as mandatory, even though I did not add the ValidateNotNullOrEmpty attribute. For example:
function Test {
param(
[Parameter(Mandatory = $true)]
[string[]] $a
)
$a
}
Calls such as Test '', Test @('', 'a'), Test $null, and Test ('a', $null) all fail with errors saying that the argument is null or an empty string. Calling Test without supplying the parameter also produces an error.
Does the Mandatory attribute implicitly apply ValidateNotNullOrEmpty? How do AllowNull and AllowEmptyString affect this behavior, especially for array parameters?
Answers
One subtle detail is that the restriction can apply when a parameter is mandatory in any parameter set, even if it is optional in the particular set selected for a call. In practice, an explicitly supplied null or empty value may still be rejected unless the parameter has the appropriate Allow* attribute. If blank values are valid for the function, it can also be clearer to make the parameter optional and handle them yourself with methods such as [string]::IsNullOrEmpty() or [string]::IsNullOrWhiteSpace().
Reply to this answer
Mandatory parameters receive a built-in null and empty-string check during parameter binding unless you explicitly allow those values. Use [AllowNull()], [AllowEmptyString()], or [AllowEmptyCollection()] when appropriate. For example:
function Test {
param(
[Parameter(Mandatory)]
[AllowNull()]
[AllowEmptyString()]
[string[]] $a
)
$a
}
The Allow* attributes are specifically intended to modify the restrictions that come with mandatory parameter binding.
Reply to this answer
This behaves similarly to ValidateNotNullOrEmpty, but it is not the same attribute. Mandatory performs the check once, while the parameter is being bound. After the function starts, the variable can still be assigned null or an empty string:
function Test {
param([Parameter(Mandatory)] [string[]] $a)
$a = $null
}
Test -a value
That assignment succeeds. If you add [ValidateNotNullOrEmpty()] explicitly, validation is attached to the variable and the later assignment fails as well. For collections, the binding check also examines the individual elements, which explains why an array containing both valid and empty or null entries is rejected.
Reply to this answer
Add your answer
Answers are reviewed before publication.
MellowCedar42: That distinction between parameter binding and validation for the lifetime of the variable clears up the confusion. The interaction with arrays and parameter sets is especially useful to know.