Apa yang terjadi dengan filter AD ini di PowerShell?

9

Saya baru-baru menulis jawaban ini dan menemukan sesuatu yang menarik.

get-aduser -filter {-not (description -eq "auto")} | measure-object

dan

get-aduser -filter {description -ne "auto"} | measure-object

mengembalikan dua hal yang sangat berbeda ketika dijalankan terhadap data yang sama, dengan perintah pertama mengembalikan nilai yang diharapkan. Tampaknya pada pandangan pertama bahwa pengguna dengan nilai nol di bidang deskripsi tidak dikembalikan sebagai kecocokan dalam perintah kedua, meskipun NULL jelas tidak sama dengan "otomatis".

Beberapa orang dalam obrolan telah melihat ini dan memverifikasi bahwa saya tidak gila. Apa yang terjadi di sini?

MDMarra
sumber
1
Menarik bahwa menyalurkannya melalui Tempat-objek dan menerapkan filter yang tidak berfungsi di atas berfungsi. get-aduser -filter * -Properti deskripsi | ? {$ _. deskripsi -ne "Otomatis"} | mengukur
Mike
@ Mike Ya, ini tampaknya menjadi perilaku -neoperator perbandingan dalam satu -Filterblok saja. Khususnya, ketika nilai input perbandingan adalah $null.
jscott
1
Suka dan tidak suka tampaknya bekerja sama. {description -notlike "something"} tidak berfungsi, tetapi {-not (description -like "something")} tidak berfungsi. Juga yang bekerja membutuhkan waktu lebih lama untuk mengevaluasi. Seperti yang rusak tidak mengevaluasi semua objek yang seharusnya.
Mike
@ Mike Itu benar. Saya sebenarnya tersandung pada penggunaan ini pada -notlikeawalnya, tetapi beralih ke -nesetelah saya menyadari saya tidak mendapatkan apa yang saya inginkan. TBH, saya lupa saya bahkan sudah mencobanya sampai Anda menyebutkannya - tetapi saya dapat mereproduksinya juga.
MDMarra
2
Hanya berpikir tapi mungkin PoSH's -eq/ -neklausa mencoba berperilaku seperti SQL =/ <>? Dalam SQL, foo = NULLdan foo <> NULLakan selalu kembali palsu, karena NULL adalah 'tak tertandingi' - hanya foo IS NULLdan foo IS NOT NULLkhusus operator akan bekerja. Perilaku harus serupa di PoSH, di mana -not (foo -eq "bar")filter Anda akan mengembalikan semua yang (foo -eq "bar")dikembalikan $false, yang foo -eq $nullakan dilakukan. Sebaliknya, bagaimana dengan if (!foo -or foo -ne "bar")(SQL setara foo IS NULL OR foo <> 'bar')?
jimbobmcgee

Jawaban:

4

Perbedaan utama antara keduanya adalah perintah pertama tidak melibatkan perbandingan nilai langsung untuk mendapatkan semua hasil, dan perintah kedua tidak. Perintah pertama termasuk hasil NULL dan yang kedua tidak (seperti MDMarra sudah ditemukan). Kedua perintah mulai dengan cmdlet ini:

get-aduser

Saat menelusuri di bawah, ingat bahwa hasil cmdlet ini mencakup semua pengguna AD terlepas dari apa pun di -filterparameter setelahnya.

Sekarang mari kita hancurkan dua bagian yang berbeda. Yang pertama:

{-not (description -eq "auto")}

...cara

  1. "cari tahu di mana atribut deskripsi sama dengan string teks" otomatis ". Agar perbandingan ini berfungsi, string harus ada di bidang deskripsi agar -eqoperator dapat membandingkannya dengan" otomatis ". Nilai NULL dikeluarkan dari ini perbandingan karena tidak dapat membandingkan NULL dengan nilai string.
  2. terlepas dari -eqparameter filter memberi saya SEMUA yang BUKAN hasil (description -eq "auto"), yang akan mencakup NULL, karena cmdlet asli get-aduser,, mencakup semua pengguna AD. Itu tidak harus membandingkan apa pun dengan apa pun dengan -notoperator. Itu memberi Anda segalanya selain apa hasil (description -eq "auto")filter itu.

Dalam contoh Anda anggap Anda memiliki 1 pengguna AD yang memiliki deskripsi mereka sama dengan "otomatis", beberapa ratus dengan sesuatu selain "otomatis" dan beberapa ratus dengan deskripsi NULL. Melangkah melalui logika perintah itu akan dilakukan:

  1. Beri saya semua pengguna AD (get-aduser) di mana deskripsi sama dengan "otomatis" - menghasilkan 1 pengguna
  2. Beri saya semua pengguna AD yang BUKAN apa yang baru saja Anda berikan kepada saya - hasilnya adalah beberapa ratus dengan sesuatu yang lain DAN beberapa ratus yang memiliki NULL.

Karena tidak perlu membandingkan apa pun dengan hal lain menggunakan -notoperator, hasilnya termasuk deskripsi pengguna NULL yang ditangkap dalam get-adusercmdlet asli .

Perintah kedua:

{description -ne "auto"}

...cara

  1. " cari tahu di mana atribut deskripsi tidak sama dengan string" auto "yang tepat. Sekali lagi, agar perbandingan ini berfungsi, string harus ada di bidang deskripsi agar -neoperator dapat membandingkannya dengan" otomatis ". Nilai NULL dikeluarkan dari perbandingan ini karena tidak dapat membandingkan NULL dengan nilai string.

Dalam contoh Anda lagi anggap Anda memiliki 1 pengguna AD yang memiliki deskripsi mereka sama dengan "otomatis", beberapa ratus dengan sesuatu selain "otomatis" dan beberapa ratus dengan deskripsi NULL. Melangkah melalui logika perintah itu akan dilakukan:

  1. Beri saya semua pengguna AD yang uraiannya tidak sama dengan "otomatis" - menghasilkan beberapa ratus pengguna dengan sesuatu selain "otomatis" dalam uraian mereka. Itu tidak menarik pengguna dengan deskripsi NULL karena tidak dapat membandingkan NULL dengan string teks.

Apa pun perbedaan antara kedua perintah itu jelas tidak intuitif.

Dengan menggunakan perintah ini, Anda harus dapat menangkap NULL dengan "-and" di sana juga seperti ini:

{description -ne "auto" -and description -ne $NULL}

Saya tidak 100% menggunakan sintaks karena saya tidak bisa mengujinya sekarang, dan mungkin ada cara yang lebih baik untuk melakukannya daripada ini juga. Ketika semuanya rusak itu cukup anti-iklim dan butuh banyak mengetik untuk menjelaskan, tapi saya sudah mengalami hal-hal aneh seperti ini sebelum menggunakan berbagai operator dan banyak trial and error karena saya tidak pernah bisa mengingat semua peringatan yang sejalan dengan menggunakan masing-masing.

Referensi: http://technet.microsoft.com/en-us/library/hh847732.aspx :

Operator Perbandingan

Gunakan operator pembanding (-eq, -ne, -gt, -lt, -le, -ge) untuk membandingkan nilai dan kondisi pengujian. Misalnya, Anda dapat membandingkan dua nilai string untuk menentukan apakah keduanya sama.

Operator pembanding termasuk operator pertandingan (-match, -notmatch), yang menemukan pola dengan menggunakan ekspresi reguler; ganti operator (-letakkan), yang menggunakan ekspresi reguler untuk mengubah nilai input; operator sejenis (-seperti, -tidak suka), yang menemukan pola menggunakan karakter wildcard (*); dan operator kontainmen (dalam, -notin, -contains, -notcontains), yang menentukan apakah nilai tes muncul dalam set referensi.

Mereka juga termasuk operator bitwise (-bAND, -bOR, -bXOR, -bNOT) untuk memanipulasi pola bit dalam nilai.

Untuk informasi lebih lanjut, lihat about_Comparison_Operators

Operator yang logis

Gunakan operator logis (-dan, -atau, -xor, -not,!) Untuk menghubungkan pernyataan kondisional ke kondisional kompleks tunggal . Misalnya, Anda bisa menggunakan logika-dan operator untuk membuat filter objek dengan dua kondisi berbeda.

Untuk informasi lebih lanjut, lihat about_Logical_Operators.

Agustus
sumber
Gambaran umum yang baik pasti, tetapi mengapa nilai nol dikeluarkan dari operator -ne dan -notlike? Itu adalah scratcher kepala asli. Saya bertanya-tanya apakah itu dengan desain dan memiliki beberapa penjelasan khusus .net spec atau apakah itu bug atau perilaku yang tidak terduga?
MDMarra
Tunggu, baca saja dengan seksama. Sepertinya mereka hanya membandingkan atribut string dan null yang sebenarnya null dan bukan string kosong. Menarik jika tidak intuitif.
MDMarra
0

Menambahkan ke pertanyaan lama ini saat muncul saat mencari:

Menggunakan -Filter dengan kecocokan negatif seperti -ne atau -notlike mengecualikan hasil dengan nilai nol kosong. Agar dapat disertakan, Anda juga harus mencocokkan secara eksplisit menggunakan -notlike '*' as -eq '' dan -eq $ NULL bukan filter yang valid. Perhatikan ini adalah kekhasan dengan -Filter, menggunakan -LdapFilter langsung TIDAK cocok dengan nilai kosong.

Berikut ini adalah contoh Filter dan LdapFilter dari multi-cocok dengan negatif:

Get-ADUser -Filter { mail -like '*example*' -and (description -ne 'example' -or description -notlike '*') }

Get-ADUser -LdapFilter '(&(mail=*example*)(!description=example))'
WhoIsRich
sumber