bernd_k
bernd_k

Reputation: 11966

How to validate PowerShell Function Parameters allowing empty strings?

Please try this:

function f1
{
    param(
    [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
    [string]
    $Text
    )
    $text
}

function f2
{
    param(
    [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
    #[string]
    $Text
    )
    $text
}

function f3
{
    param(
    [Parameter(Mandatory=$False,ValueFromPipelineByPropertyName=$true)]
    [string]
    $Text
    )
    $text
}

f1 ''
f2 ''
f3 ''

Here f1 throws an error. Now try

f2 $null 
f3 $null    

This time only f2 throws an error. What I want is a function f, so that

f '' # is accepted
f $null # returns an error

Upvotes: 48

Views: 49180

Answers (3)

Shay Levy
Shay Levy

Reputation: 126752

The Mandatory attribute blocks null and empty values and prompts you for a value. To allow empty values (including null) add the AllowEmptyString parameter attribute:

function f1
{
    param(
    [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
    [AllowEmptyString()]
    [string]$Text
    )
    $text
}

Upvotes: 94

Emiliano Poggi
Emiliano Poggi

Reputation: 24826

Just for the sake of completeness, if you want your input be validated against string type, you can do it afterward parameters declaration:

function f1
{
    param(
    [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
    $Text
    )
    if (!($text -eq '') -and !($text -as [string])) {write-host "wrong type"; return }
    $text
}

This function behaves as follows:

  • Throws "Cannot bind argument.." exception when input is $null
  • Passes when input is an empty string
  • Exits with message wrong type when input is not a string

Upvotes: 1

Roman Kuzmin
Roman Kuzmin

Reputation: 42033

Here is the solution that fits the requirements with a caveat.

function f1
{
    param(
    [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
    $Text
    )
    Write-Host 'Working'
    $text
}

f1 ''
f1 $null

Output:

Working
f1 : Cannot bind argument to parameter 'Text' because it is null.

Caveat

In order to fit the requirements we have to omit the explicit type declaration of [string]. The problem is that PowerShell tends to convert nulls to empty strings everywhere where the [string] type is specified. Thus, if we use the type declaration then null value actually never comes to the function.

P.S. Here is a related issue submitted: It isn't possible to pass null as null into a .NET method that has a parameter of type String

Upvotes: 7

Related Questions