2015-07-06 3 views
3

Я собираю список всех учетных записей пользователей в AD, у которых есть непустое название задания. Во-первых я получаю все пользователи (я фильтр позже):

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

Тогда я беру только те счета непустых заглавий. Сначала я попробовал следующее: «Ну, если есть значение, оно будет оцениваться до $ true».

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

Но это приводит к пустым спискам. Затем я попробовал то, что я думал, было то же самое, выполнив следующие действия:

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

В этом случае я получаю ожидаемый результат.

В чем разница между этими двумя утверждениями? Моя мысль заключается в том, что PowerShell -eq похож на === в JavaScript. Это верно?

ответ

4

Это происходит из-за того, что PowerShell пытается принудить правую сторону сравнения к типу левой стороны.

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

Это терпит неудачу, потому что это то же самое, как делают:

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

Чтобы понять, почему, попробуйте отливку: [string]$true

С другой стороны, если бы вы сделали это (и I рекомендую вам):

$allUsers | ? {$_.Title} 

Это сработало бы, как ожидалось.

Точно так же, когда вы делаете:

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

Это как делает:

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

Это в теории гораздо более опасное сравнение, потому что название, которое начинается с, скажем @ вернется ложный. На практике маловероятно, что у вас будет заголовок, начинающийся с символьного значения ниже 0, так как все буквы в верхнем и нижнем регистре имеют более высокое значение. Но я не учитываю интернационализацию.

Хотя для моей собственной пользы, и ради тех, кто придет после меня, бы вы изменить свой пост, чтобы объяснить, почему именно {$ _. Название} является предпочтительным методом ?

Я не говорю, что это абсолютно лучшее, но мне это нравится по нескольким причинам:

  • Это коротко.
  • Он не содержит встроенных констант. Не уверен, что это имеет большое значение, но это не так, чтобы ошибиться.
  • Это (на мой взгляд) очищает то, что вы тестируете, поскольку это распространенный способ тестирования этого на многих языках.
  • Он работает с $null и с пустой строкой.

Есть и другие способы:

$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 

Что-то я еще не обращался: вы должны делать это сравнение внутри -Filter свойства Get-ADUser и в идеале вы должны задать только для свойства, которые необходимы:

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

-Filter параметр выглядит как блок сценария, но он имеет свой собственный синтаксис и действительные операторы и значения, так что это немного сложнее. Это должно быть намного быстрее, хотя.

+0

Got it. В этом есть смысл. Хотя ради меня самого и ради тех, кто приходит за мной, вы отредактировали бы свой пост, чтобы объяснить, почему {$ _. Title} является предпочтительным методом? – Chris76786777

+0

@ idon'twearsuits обновлен. – briantist

+0

Очень информативный. Благодарю. – Chris76786777

Смежные вопросы