Home > front end >  Function parameter validation in Powershell
Function parameter validation in Powershell

Time:09-21

Why does a [string] casted parameter with the 'value' $null in this example never throw an error (empty or $null), but a string with the value '$null' always throws? I would expect if passing a mandatory parameter, it is checked for $null/emptyness and thus an error is always thrown in these cases:

Function test_M_NoE ( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [string] $x ) {}

# test cases. Uncomment one:
[string]$x = [string]$null 
# $x = [string]$null
# [string]$x = $null
# $x = $null 

"1:"; test_M_NoE [string]$x # never error
"2:"; test_M_NoE $x         # always error

CodePudding user response:

The reason this works:

test_M_NoE [string]$x

Is that [string]$x is not being interpreted the way you expect.

Let's change your test function definition to help us better see what's actually going on:

function test_M_NoE {
  param(
    [Parameter(Mandatory=$true)]
    [ValidateNotNullOrEmpty()]
    [string]$x
  )

  Write-Host "Argument value passed was: '$x'"
}

Now, let's try again:

PS ~> $x = $null
PS ~> test_M_NoE [string]$x
Argument value passed was: '[string]'

Aha! The argument expression [string]$x did not result in an empty string - it resulted in the literal string value [string].

This is due to the fact that PowerShell attempts to parse command arguments differently from anything else. From the about_Parsing help topic:

Argument mode is designed for parsing arguments and parameters for commands in a shell environment. All input is treated as an expandable string unless it uses one of the following syntaxes: [...]

So really, PowerShell interprets our argument expression like a double-quoted string:

test_M_NoE "[string]$x"

At which point the behavior makes sense - $x is $null, so it evaluates to an empty string, and the result of the expression "[string]$x" is therefore just [string].

Enclose the argument expression in the $(...) subexpression operator to have it evaluated as a value expression instead of as an expandable string:

test_M_NoE $([string]$x)
  • Related