527

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.

Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
pencilCake
  • 48,449
  • 79
  • 219
  • 356

15 Answers15

740

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
anon
  • 4,502
  • 2
  • 33
  • 54
Keith Hill
  • 184,219
  • 38
  • 329
  • 358
  • 38
    @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 Dec 07 '12 at 16:06
  • I agree with your answer, but it is only correct in combination with @ShayLevy. When dealing with strings, `$null` is not the same as `''`. For most use cases you can assume that they are; this is the discretion of the programmer. You may also want to treat `' '` as empty/null, which can be done with `[string]::IsNullOrWhiteSpace(' ')` or `' '.Trim()` ... which one reads easier? I like the simplicity/elegance of coding with PowerShell, but sometimes you need to be more specific. ***Note:*** *Use `[string]::` + `` to "tab" through all the available methods of `[string]`* – VertigoRay Mar 22 '16 at 17:19
  • 5
    @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 Mar 23 '16 at 04:04
  • 2
    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 May 20 '16 at 08:11
  • 1
    @Dmitry That's a fair point . You can use restricted types in PowerShell fairly easily `[string]$str = $false` gives you `False`. So these test could be `if ([string]$str) { ... }` if you want to be sure. – Keith Hill May 20 '16 at 16:13
  • 5
    "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 May 24 '16 at 12:43
  • If this reply is correct, when i don't understand the following behaviour: `$minor=$matches['minor'];if($minor) { $minor="00" }; if ([string]::IsNullOrEmpty($minor)) { $minor="00" }` It doesn't step into the first if, but into the second. Sorry, i couldn't figure out how to add nicely formatted multi line code in a comment – Naryoril Jun 10 '20 at 06:41
  • For the first `if` you want `if (-not $minor) { $minor="00" }`. When `$minor` is null or an empty string it will eval to `$false` in a conditional. But it appears you want the `if` statement to execute so invert that to make the conditional eval to `$true`. – Keith Hill Jun 11 '20 at 16:43
  • Also `$str1=0`, in eg will return "empty". But `[string]::IsNullOrEmpty($str1)` will return false. However `[string]$str1=0` will return "not empty" in the example. As in JS you need to beware of implicit type conversion when using `if($str1)` – Jason S Dec 07 '20 at 12:19
  • 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.) – John Neuhaus Feb 15 '21 at 17:59
605

You can use the IsNullOrEmpty static method:

[string]::IsNullOrEmpty(...)
Shay Levy
  • 114,369
  • 30
  • 175
  • 198
  • 6
    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 Dec 10 '12 at 06:07
  • 28
    I guess you can just do !$var – Shay Levy Jun 14 '13 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 https://connect.microsoft.com/PowerShell/feedback/details/861093/nullstring-value-is-not-preserved-when-passed-to-functions. – JamieSee Dec 11 '14 at 17:59
  • 44
    Consider [String]::IsNullOrWhiteSpace(...) for validating empty spaces as well. – Sai May 04 '15 at 22:12
  • 4
    @ShayLevy Careful with the `!`. That only works in newer versions of PowerShell. `!` is an alias for `-not` – Kellen Stuart Jun 23 '17 at 00:03
53

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
Roman Kuzmin
  • 38,689
  • 10
  • 87
  • 111
  • 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 Jan 20 '16 at 17:22
  • 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 Jul 23 '21 at 13:42
25

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
}
Rubanov
  • 3,508
  • 1
  • 34
  • 33
  • This is by far better approach. Although, it is not exactly a solution to the question asked. – dmitry Jul 23 '21 at 13:33
19

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

11

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
    }
}
mhenry1384
  • 7,332
  • 5
  • 52
  • 73
  • Couldn't you use `.Trim()` instead of listing types of whitespace? So it would be `$str.Trim().Length -eq 0` – HackSlash May 13 '21 at 21:33
6
# cases
$x = null
$x = ''
$x = ' '

# test
if ($x -and $x.trim()) {'not empty'} else {'empty'}
or
if ([string]::IsNullOrWhiteSpace($x)) {'empty'} else {'not empty'}
Skatterbrainz
  • 1,077
  • 5
  • 22
  • 31
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.

Peter Mortensen
  • 30,030
  • 21
  • 100
  • 124
Ryan
  • 331
  • 2
  • 7
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
Santiago Squarzon
  • 20,988
  • 4
  • 10
  • 27
1

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.

Bender the Greatest
  • 17,062
  • 18
  • 82
  • 145
0

Note that the "if ($str)" and "IsNullOrEmpty" tests don't work comparably in all instances: an assignment of $str=0 produces false for both, and depending on intended program semantics, this could yield a surprise.

Steve Friedl
  • 3,692
  • 1
  • 22
  • 27
  • $str=0 is not a good coding practice. $str='0' will leave no doubt in what is the expected outcome of IsNullOrEmpty. – dmitry Sep 09 '19 at 10:39
  • This is incorrect. `$str=0` is assigning an integer value the same as `$str=1` or `$str=1000` is. If you need to assign a digit-only string to a variable, either convert the integer to a string with `[string]'0'`, `"0"`, or by strongly-defining the variable's type on declaration (in which case conversion will happen on assignment). Note that `0` in those samples can be replaced by any integer value – Bender the Greatest Jun 01 '22 at 01:58
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.

Zodman
  • 2,611
  • 1
  • 30
  • 37
0

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

```PowerShell
$rowData | ForEach-Object {
    if(-not [string]::IsNullOrEmpty($_.values) -and
        -not [string]::IsNullOrWhiteSpace($_.values)) {
            // Insert logic here to use non-null/whitespace values
    }
}
Toni
  • 1,495
  • 4
  • 13
  • 22
Daikyu
  • 111
  • 5
-2

Somewhat related hack - you can exclude empty values (eg Excel has a habit of including an extra empty cell when copying into PowerShell) like this:

get-clipboard | ? {$_}
KERR
  • 1,071
  • 14
  • 11
  • 2
    What is `get-clipboard` and how does it relate to this question? If it's what I think it is, OP hasn't indicated they're trying to check the value of the first item in their Windows clipboard storage at all (in which case this wouldn't answer the question). – TylerH Jul 12 '21 at 15:42