What is the difference between "-gt 0" and "-eq $ true" when looking for non-empty string values?

I am collecting a list of all user accounts in AD that have a non-empty job title. First I get all users (I will filter later):

$allUsers = get-aduser -filter * -properties *

      

Then I only grab those accounts with non-empty headers. First I tried the following: "Well, if a value is present, it will evaluate to $ true."

$allUsers | ? {$_.Title -eq $true}

      

But this leads to empty lists. So, I tried the same as I did by doing the following:

$allUsers | ? {$_.Title -gt 0}

      

In this case, I get the expected result.

What is the difference between the two statements? My thought is that PowerShell -eq is like === in JavaScript. It is right?

+3


source to share


1 answer


This is because PowerShell is trying to coerce the right side of the comparison to be the left side.

$allUsers | ? {$_.Title -eq $true}

      

It doesn't work because it is the same as doing:

$allUsers | ? {$_.Title -eq "True"}

      

To find out why, try casting: [string]$true

On the other hand, if you did ( and I recommend you do ):

$allUsers | ? {$_.Title}

      

It would work as expected.

Likewise, when you do:

$allUsers | ? {$_.Title -gt 0}

      

This is how to do it:



$allUsers | ? {$_.Title -gt "0"}

      

This is theoretically a much more dangerous comparison, because a name starting with, say @

, will return false. In practice, it is unlikely that you will have a heading starting with the character value below 0

, since all upper and lower case letters have a higher value. But I am not considering internationalization.

Although for my own sake and for the sake of those who follow me, you would edit the post to explain exactly why {$ _. Title} is the preferred method?

I don't think this is the absolute best, but I like it for several reasons:

  • In short.
  • It contains no built-in constants. Not sure if it matters a lot, but it's less to be wrong.
  • This (in my opinion) cleans up what you are testing as this is the usual way of testing this in many languages.
  • It works with $null

    and with an empty string.

There are other ways:

$allUsers | ? { ![String]::IsNullOrEmpty($_.Title) }
$allUsers | ? { $_.Title.Length -gt 0 }
$allUsers | ? { $_.Title -ne "" } # would include $null titles
$allUsers | ? { $_.Title -ne $null } # would include empty string titles

      

Something else I'm not addressing: you have to do this comparison inside a property -Filter

Get-ADUser

, and ideally you only need to query the properties you need:

$allUsers = Get-ADUser -Filter { -not (Title -like "*") } -Properties Title

      

The parameter -Filter

looks like a script block, but it has its own syntax and valid statements and values, so it's a little more complex. It should be much faster though.

+4


source







All Articles