Niedawno napisałem tę odpowiedź i natknąłem się na coś interesującego.
get-aduser -filter {-not (description -eq "auto")} | measure-object
i
get-aduser -filter {description -ne "auto"} | measure-object
zwracają dwie bardzo różne rzeczy, gdy działają na tych samych danych, przy czym pierwsze polecenie zwraca oczekiwaną wartość. Na pierwszy rzut oka wydaje się, że użytkownicy z wartością zerową w polu opisu nie są zwracani jako dopasowania w drugim poleceniu, mimo że NULL wyraźnie nie równa się „auto”.
Kilka osób na czacie spojrzało na to i potwierdziło, że nie jestem szalony. Co tu się dzieje?
powershell
MDMarra
źródło
źródło
-ne
operatora porównania tylko w obrębie-Filter
bloku. W szczególności, gdy wartością wejściową porównania jest$null
.-notlike
oryginalnie, ale zmieniłem na,-ne
gdy zdałem sobie sprawę, że nie dostaję tego, czego chciałem. TBH, zapomniałem, że nawet próbowałem tego, dopóki o tym nie wspomniałeś - ale mogę to również odtworzyć.-eq
/-ne
klauzula próbuje zachowywać się jak SQL=
/<>
? W SQLfoo = NULL
ifoo <> NULL
zawsze zwróci false, ponieważ NULL jest „nieporównywalny” - działają tylko operatory specjalnefoo IS NULL
ifoo IS NOT NULL
. Zachowanie musi być podobne w PoSH, gdzie twój-not (foo -eq "bar")
filtr zwróci wszystko, za co(foo -eq "bar")
zwrócił$false
, cofoo -eq $null
by zrobiło . Zamiast tego, co powiesz naif (!foo -or foo -ne "bar")
(odpowiednik SQLfoo IS NULL OR foo <> 'bar'
)?Odpowiedzi:
Kluczowa różnica między nimi polega na tym, że pierwsze polecenie nie wymaga bezpośredniego porównania wartości w celu uzyskania wszystkich wyników, a drugie polecenie tak. Pierwsze polecenie zawiera wyniki NULL, a drugie nie (jak już odkryto MDMarra). Oba polecenia zaczynają się od tego polecenia cmdlet:
Przechodząc poniżej, pamiętaj, że wyniki tego polecenia cmdlet obejmują wszystkich użytkowników AD bez względu na wszystko inne w
-filter
parametrze po nim.Teraz podzielmy dwie części, które są różne. Pierwszy:
...znaczy
-eq
operator mógł porównać go z„ auto ”. Wartości NULL są z tego usuwane porównanie, ponieważ nie można porównać wartości NULL z wartością ciągu.-eq
parametr filtru daje mi WSZYSTKO, co NIE jest wynikiem(description -eq "auto")
, w tym NULL, ponieważ oryginalne polecenie cmdletget-aduser
obejmuje wszystkich użytkowników AD. Nie musiał niczego porównywać z-not
operatorem. Po prostu dał ci wszystko oprócz wyników(description -eq "auto")
filtru.W twoim przykładzie załóżmy, że masz 1 użytkownika AD, którego opis jest równy „auto”, kilkaset z czymś innym niż „auto” i kilkaset z opisami NULL. Przejście przez logikę poleceń spowoduje:
Ponieważ nie trzeba było porównywać niczego z niczym innym za pomocą
-not
operatora, wynik obejmował użytkowników opisu NULL, którzy zostali przechwyceni w oryginalnym poleceniuget-aduser
cmdlet.Drugie polecenie:
...znaczy
-ne
operator mógł go porównać z" auto ". Wartości NULL są usuwane z tego porównania, ponieważ nie można porównać wartości NULL z wartością ciągu.W twoim przykładzie ponownie załóżmy, że masz 1 użytkownika AD, którego opis jest równy „auto”, kilkaset z czymś innym niż „auto” i kilkaset z opisami NULL. Przejście przez logikę poleceń spowoduje:
Tak czy inaczej cała różnica między tymi dwoma poleceniami jest zdecydowanie nieintuicyjna.
Za pomocą tego polecenia powinieneś być w stanie złapać NULL-y z „-and” również w ten sposób:
Nie jestem w 100% odpowiedzialny za składnię, ponieważ nie mogę jej teraz przetestować i prawdopodobnie jest na to lepszy sposób. Kiedy wszystko jest zepsute, jest dość anty-klimatyczne i wymagało dużo pisania, aby wyjaśnić, ale natknąłem się na takie dziwne rzeczy przed użyciem różnych operatorów i wielu prób i błędów, ponieważ nigdy nie pamiętam wszystkich zastrzeżeń które pasują do każdego z nich.
Odniesienie: http://technet.microsoft.com/en-us/library/hh847732.aspx :
źródło
Dodanie do tego starego pytania, które pojawia się podczas wyszukiwania:
Użycie -Filter z dopasowaniem ujemnym, takim jak -ne lub -niepodobne, wyklucza wyniki z pustymi wartościami null. Aby je uwzględnić, musisz również jawnie dopasować, używając -niepodstawowego „*” jako -eq ” i -eq $ NULL nie są prawidłowymi filtrami. Zauważ, że jest to dziwactwo z -Filter, przy użyciu bezpośredniego -LdapFilter DOESZCZYĆ ujemne dopasowanie pustych wartości.
Oto przykład filtru i filtru LdapFilter z dopasowaniem wielokrotnym z ujemnym:
źródło