625

Is there a built-in IsNullOrEmpty-like function in order to check if a string is null or empty, in PowerShell?

I could not find it so far and if there is a built-in way, I do not want to write a function for this.

3
  • 3
    hop this helps rkeithhill.wordpress.com/2007/01/06/…
    – gofor.net
    Commented Dec 6, 2012 at 7:13
  • 15
    Well you're using .NET, so can't you call String.IsNullOrEmpty?
    – Jon Skeet
    Commented Dec 6, 2012 at 7:17
  • 1
    It's 2024 and the answer is still as Jon Skeet said: [string]::IsNullOrEmpty($myString) works in PowerShell v7.4.0 Commented Jan 22 at 15:46

16 Answers 16

875
+50

You guys are making this too hard. PowerShell handles this quite elegantly e.g.:

> $str1 = $null
> if ($str1) { 'not empty' } else { 'empty' }
empty

> $str2 = ''
> if ($str2) { 'not empty' } else { 'empty' }
empty

> $str3 = ' '
> if ($str3) { 'not empty' } else { 'empty' }
not empty

> $str4 = 'asdf'
> if ($str4) { 'not empty' } else { 'empty' }
not empty

> if ($str1 -and $str2) { 'neither empty' } else { 'one or both empty' }
one or both empty

> if ($str3 -and $str4) { 'neither empty' } else { 'one or both empty' }
neither empty
10
  • 42
    @pencilCake Yes, that what I'm saying and the example above shows it in action. What the test won't check for is IsNullOrWhitespace().
    – Keith Hill
    Commented Dec 7, 2012 at 16:06
  • 8
    @VertigoRay See my first comment above where I recommend using IsNullOrWhitespace() for that scenario. But after 11 years of scripting with PowerShell, I find I need that string test very rarely. :-)
    – Keith Hill
    Commented Mar 23, 2016 at 4:04
  • 3
    This is the dangerous practice in both Powershell and Javascript if the variable type is not restricted. Consider this: $str1=$false or $str1=@(0)
    – dmitry
    Commented May 20, 2016 at 8:11
  • 8
    "KeithHill. Sorry that is still unsafe, since your intention is not clear. When you use [string]::IsNullOrEmpty, you are absolutely clear. IMO, Powershell is a strangest creation - most of the times it is overabundantly rich, but still missing essentials. -isNullOrEmpty predicate is one of them...
    – dmitry
    Commented May 24, 2016 at 12:43
  • 2
    @dmitry nailed it with understanding what you want. And often "truthy" or "falsy" is good enough, and you can wave away a lot of other things in a bounded context. A string array could have 0 in it, but if it's not supposed to, it's not necessarily your method's job to care. (But also, the potential bug could be bad enough to justify being extra defensive.) Commented Feb 15, 2021 at 17:59
697

You can use the IsNullOrEmpty static method:

[string]::IsNullOrEmpty(...)
5
  • 12
    I like this way more as it is obvious what it does regardless of your Powerhsell knowledge -which would make sense for non-Powershell programmers.
    – pencilCake
    Commented Dec 10, 2012 at 6:07
  • 31
    I guess you can just do !$var
    – Shay Levy
    Commented Jun 14, 2013 at 11:50
  • 6
    One thing to be aware of with PowerShell is that null strings passed to a commandlet or function don't stay null. They get converted to empty strings. See the Microsoft Connect bug at connect.microsoft.com/PowerShell/feedback/details/861093/….
    – JamieSee
    Commented Dec 11, 2014 at 17:59
  • 57
    Consider [String]::IsNullOrWhiteSpace(...) for validating empty spaces as well.
    – Sai
    Commented May 4, 2015 at 22:12
  • 4
    @ShayLevy Careful with the !. That only works in newer versions of PowerShell. ! is an alias for -not Commented Jun 23, 2017 at 0:03
60

In addition to [string]::IsNullOrEmpty in order to check for null or empty you can cast a string to a Boolean explicitly or in Boolean expressions:

$string = $null
[bool]$string
if (!$string) { "string is null or empty" }

$string = ''
[bool]$string
if (!$string) { "string is null or empty" }

$string = 'something'
[bool]$string
if ($string) { "string is not null or empty" }

Output:

False
string is null or empty

False
string is null or empty

True
string is not null or empty
2
  • 6
    Nice point. If clause internally converts everything inside the parenthesis to single boolean which means if($string){Things to do for non-empty-nor-null} or if(!$string){Things to do for empty-or-null} without explicit conversion [bool] would be enough.
    – Ch.Idea
    Commented Jan 20, 2016 at 17:22
  • 1
    These implicit conversions are the most dangerous thing. You need to make sure that you have exactly string type. Consider $string=@(0) - quite possible to occur...
    – dmitry
    Commented Jul 23, 2021 at 13:42
27

If it is a parameter in a function, you can validate it with ValidateNotNullOrEmpty as you can see in this example:

Function Test-Something
{
    Param(
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string]$UserName
    )

    #stuff todo
}
1
  • This is by far better approach. Although, it is not exactly a solution to the question asked.
    – dmitry
    Commented Jul 23, 2021 at 13:33
27

Personally, I do not accept a whitespace ($STR3) as being 'not empty'.

When a variable that only contains whitespaces is passed onto a parameter, it will often error that the parameters value may not be '$null', instead of saying it may not be a whitespace, some remove commands might remove a root folder instead of a subfolder if the subfolder name is a "white space", all the reason not to accept a string containing whitespaces in many cases.

I find this is the best way to accomplish it:

$STR1 = $null
IF ([string]::IsNullOrWhitespace($STR1)){'empty'} else {'not empty'}

Empty

$STR2 = ""
IF ([string]::IsNullOrWhitespace($STR2)){'empty'} else {'not empty'}

Empty

$STR3 = " "
IF ([string]::IsNullOrWhitespace($STR3)){'empty !! :-)'} else {'not Empty :-('}

Empty!! :-)

$STR4 = "Nico"
IF ([string]::IsNullOrWhitespace($STR4)){'empty'} else {'not empty'}

Not empty

1
  • .Net has String::IsNullOrEmpty for your purpose.
    – dmitry
    Commented Jul 23, 2021 at 13:46
15

Many good answers here; let me offer a pragmatic summary with PowerShell-idiomatic solutions:

Given a variable $str that may contain $null or a string (or any scalar):

# Test for $null or '' (empty string).
# Equivalent of: [string]::IsNullOrEmpty($str)
$str -like ''

# Test for $null or '' or all-whitespace.
# Equivalent of: [string]::IsNullOrWhitespace($str)
$str -notmatch '\S'  

Note: If $str can be a collection (array), use the type-agnostic solutions at the bottom.

  • Using the string-only -like operator implicitly coerces the LHS to a string, and since [string] $null yields the empty string, both '' -like '' and $null -like '' yield $true.

  • Similarly, the regex-based -match / -notmatch operators, as string-only operators, coerce their LHS operand to a string, and $null is treated like '' in this conversion.

    • \S is a regex escape sequence that matches any non-whitespace character (it is the negated form of \s).

    • -match / -notmatch perform substring matching by default (and only ever return one match), so if \S matches, the implication is that at least one character that isn't a whitespace character is present.


Caveat:

Given PowerShell's dynamic typing, you may not know the type of the value stored in a given variable ahead of time.

While the techniques above work predictable with $null, [string] instances, and other types that are non-enumerable, enumerable values (other than strings) may yield surprising results, because if the LHS of -like and -notmatch are enumerables (loosely speaking: collections), the operation is applied to each element, and instead of returning a single Boolean value, the sub-array of matching elements is returned.

In the context of a conditional, the way an array is coerced to a Boolean is somewhat counterintuitive; if the array has just one element, that element itself is coerced to a Boolean; with two or more elements, the array is always coerced to $true, irrespective of the element values - see the bottom section of this answer. For instance:

# -> 'why?', because @('', '') -like '' yields @('', ''), which
# - due to being a 2-element array - is $true
$var = @('', '')
if ($var -like '') { 'why?' }

if you cast a non-string enumerable LHS to [string], PowerShell stringifies it by space-concatenating its (stringified) elements. This is also what happens implicitly when you call [string]::IsNullOrEmpty() or [string]::IsNullOrWhiteSpace(), because their parameter is [string]-typed.

Thus, the type-agnostic equivalents of the above - using the stringification rules described - are:

# Test for $null or '' (empty string) or any stringified value being ''
# Equivalent of: [string]::IsNullOrEmpty($var)
[string] $var -eq ''

# Test for $null or '' or all-whitespace or any stringified value being ''
# Equivalent of: [string]::IsNullOrWhitespace($var)
([string] $var).Trim() -eq ''
0
14

PowerShell 2.0 replacement for [string]::IsNullOrWhiteSpace() is string -notmatch "\S"

("\S" = any non-whitespace character)

> $null  -notmatch "\S"
True
> "   "  -notmatch "\S"
True
> " x "  -notmatch "\S"
False

Performance is very close:

> Measure-Command {1..1000000 |% {[string]::IsNullOrWhiteSpace("   ")}}
TotalMilliseconds : 3641.2089

> Measure-Command {1..1000000 |% {"   " -notmatch "\S"}}
TotalMilliseconds : 4040.8453
8

I have a PowerShell script I have to run on a computer so out of date that it doesn't have [String]::IsNullOrWhiteSpace(), so I wrote my own.

function IsNullOrWhitespace($str)
{
    if ($str)
    {
        return ($str -replace " ","" -replace "`t","").Length -eq 0
    }
    else
    {
        return $TRUE
    }
}
2
  • Couldn't you use .Trim() instead of listing types of whitespace? So it would be $str.Trim().Length -eq 0
    – HackSlash
    Commented May 13, 2021 at 21:33
  • $str -notmatch '\S' should suffice and covers all types of whitespace, not just spaces and tabs.
    – mklement0
    Commented Aug 6, 2022 at 2:32
7
# cases
$x = null
$x = ''
$x = ' '

# test
if ($x -and $x.trim()) {'not empty'} else {'empty'}
or
if ([string]::IsNullOrWhiteSpace($x)) {'empty'} else {'not empty'}
6

When a boolean is expected, PowerShell will use $true for variables not null, zero or empty.

Hence, the cleanest approach to validating whether a string is not Null or Empty is:

if ($str) { }

Or the opposite condition to validate a string is Null or Empty:

if (!$str) { }

Reference: https://learn.microsoft.com/en-us/powershell/scripting/learn/deep-dives/everything-about-null?view=powershell-7.4#simple-if-check

Example 1:

$str = $null
if ($str) { "1: String = $str" } else { '1: Null or Empty' }

$str = ""
if ($str) { "2: String = $str" } else { '2: Null or Empty' }

if ($undeclaredVar) { "$undeclaredVar" } else { '3: Null or Empty' }

$str = 0
if ($str) { "4: String = $str" } else { '4: Null or Empty' }

$str = 1
if ($str) { "5: String = $str" } else { '5: Null or Empty' }

$str = -1
if ($str) { "6: String = $str" } else { '6: Null or Empty' }

$str = "Gold"
if ($str) { "7: String = $str" } else { '7: Null or Empty' }

output:
1: Null or Empty
2: Null or Empty
3: Null or Empty
4: Null or Empty
5: String = 1
6: String = -1
7: String = Gold

To take a similar approach when using ForEach-Object (%), use a script block with just the variable. This could be the current object ($_ / $PSItem), another variable or a parameter.

Example 2:

"a", -1, 0, $null, 1, 2, , '', "", 3 | ? { $_ }

output:
a
-1
1
2
3

Validating whether a property is Null or Empty is even easier. Just use ? + property name:

[PSCustomObject]@{ Name = 'Gold' } | ? Name | % { "Valid name = $_" }

If you need to avoid whitespace, surround your variable with double quotes and Trim() it:

if ("$str".Trim()) { }

Most of the time, worrying about whitespace is not necessary, and the above Trim() is something I rarely use. If the above will run in high repetition, you can reduce your memory usage by using one of these instead:

If(([string]$str).Trim()) { }

# The below requires PowerShell 4 or above
if([System.String]::IsNullOrWhiteSpace($str)) { }

Example 3:

$str = $null
if ("$str".Trim()) { "1: String = $str" } else { '1: Null or Empty' }

$str = ""
if ("$str".Trim()) { "2: String = $str" } else { '2: Null or Empty' }

if ($undeclaredVar) { "$undeclaredVar" } else { '3: Null or Empty' }

$str = 0
if ("$str".Trim()) { "4: String = $str" } else { '4: Null or Empty' }

$str = 1
if ("$str".Trim()) { "5: String = $str" } else { '5: Null or Empty' }

$str = -1
if ("$str".Trim()) { "6: String = $str" } else { '6: Null or Empty' }

$str = "Gold"
if ("$str".Trim()) { "7: String = $str" } else { '7: Null or Empty' }

$str = " "
if ("$str".Trim()) { "8: String = $str" } else { '8: Null or Empty' }

output:
1: Null or Empty
2: Null or Empty
3: Null or Empty
4: String = 0
5: String = 1
6: String = -1
7: String = Gold
8: Null or Empty
3

Addressing the tangential shortcoming with @KeithHill's answer not covering the IsNullOrWhitespace case, in PowerShell 7.1 and later we can use the null-conditional member operator to gracefully check if a string is null or whitespace without needing to first check that the string isn't $null ourselves, while avoiding the use of [string]::IsNullOrWhitespace(string).

Note: You can also do this with PowerShell 7.0 if you enable the PSNullConditionalOperators experimental feature:

Enable-ExperimentalFeature -Name PSNullConditionalOperators

To use the $str3 example from Keith's answer (and pretending the ternary operator doesn't also exist since 7.0 for clarity):

$str3 = ' '
if ( ${str3}?.Trim() ) {
  'not empty or whitespace'
} else {
  'empty or whitespace'
}
empty or whitespace

.Trim() is only invoked if $str3 is a non-null value, otherwise $null is returned instead.


One thing to remember is that a question mark ? is valid as part of a variable name. This is why we must first disambiguate the variable name by before applying the conditional-access operator like so: ${str3}


Since I did mention the ternary operator earlier, and since this answer already centers around PowerShell 7.1 and later, you can simplify the code block above by using the ternary operator, removing the boilerplate if/then/else statement almost entirely:

${str3}?.Trim() ? 'not empty or whitespace' : 'empty or whitespace'

The ternary operator is a simplified if/then/else statement for basic conditionals. I don't want to muddy the waters too much here with nuances around it, but read it as "if the left side of the lone question-mark ? is true, execute what is on the right side of the ?, or else execute what comes after the colon :".

You can read more about the ternary operator in the PowerShell documentation.

0
2

Another way to accomplish this in a pure PowerShell way would be to do something like this:

("" -eq ("{0}" -f $val).Trim())

This evaluates successfully for null, empty string, and whitespace. I'm formatting the passed value into an empty string to handle null (otherwise a null will cause an error when the Trim is called). Then just evaluate equality with an empty string. I think I still prefer the IsNullOrWhiteSpace, but if you're looking for another way to do it, this will work.

$val = null    
("" -eq ("{0}" -f $val).Trim())
>True
$val = "      "
("" -eq ("{0}" -f $val).Trim())
>True
$val = ""
("" -eq ("{0}" -f $val).Trim())
>True
$val = "not null or empty or whitespace"
("" -eq ("{0}" -f $val).Trim())
>False

In a fit of boredom, I played with this some and made it shorter (albeit more cryptic):

!!(("$val").Trim())

or

!(("$val").Trim())

depending on what you're trying to do.

2

You can use a conditional statement with both IsNullOrWhitespace() and isNullOrEmpty() static methods testing for white spaces or a null value. For example, before inserting into a MySQL database, I loop through the values I will enter and use the condition to avoid null or whitespace values.

// RowData is iterative, in this case a hashtable,
// $_.values targets the values of the hashtable

$rowData | ForEach-Object {
    if(-not [string]::IsNullOrEmpty($_.values) -and
        -not [string]::IsNullOrWhiteSpace($_.values)) {
            // Insert logic here to use non-null/whitespace values
    }
}
1

Another alternative adding 2 new Script Methods to the System.String instances using Update-TypeData:

Update-TypeData -MemberType ScriptMethod -MemberName IsNullOrEmpty -Value {
    return [string]::IsNullOrEmpty($this)
} -TypeName System.String

Update-TypeData -MemberType ScriptMethod -MemberName IsNullOrWhiteSpace -Value {
    return [string]::IsNullOrWhiteSpace($this)
} -TypeName System.String

'hello'.IsNullOrEmpty()  # => False
''.IsNullOrEmpty()       # => True
' '.IsNullOrEmpty()      # => False
' '.IsNullOrWhiteSpace() # => True
1

You could create a filter that converts empty strings to nulls, then you only would have to check for null.

filter nullif {@($_, $null)[$_ -eq '']}

Then you just need to pipe your value into it

('' | nullif) -eq $null
> True
('x' | nullif) -eq $null
> False

An even easier mrthod would be to use a regex

$null -match '^$'
> True
'' -match '^$'
> True
'x' -match '^$'
> False
0

An extension of the answer from Keith Hill (to account for whitespace):

$str = "     "
if ($str -and $version.Trim()) { Write-Host "Not Empty" } else { Write-Host "Empty" }

This returns "Empty" for nulls, empty strings, and strings with whitespace, and "Not Empty" for everything else.

Not the answer you're looking for? Browse other questions tagged or ask your own question.