Cái quái gì đang diễn ra với bộ lọc AD này trong PowerShell?


9

Gần đây tôi đã viết câu trả lời này và vấp phải điều gì đó thú vị.

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

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

trả về hai thứ rất khác nhau khi chạy với cùng một dữ liệu, với lệnh đầu tiên trả về giá trị mong đợi. Thoạt nhìn, người dùng có giá trị null trong trường mô tả sẽ không được trả về dưới dạng khớp trong lệnh thứ hai, mặc dù rõ ràng NULL không bằng "tự động".

Một vài người trong cuộc trò chuyện đã xem xét điều này và xác minh rằng tôi không điên. Những gì đang xảy ra ở đây?


1
Điều thú vị là đường ống thông qua đối tượng Where và áp dụng bộ lọc không hoạt động ở trên hoạt động. get-aduser -filter * -Mô tả mô tả | ? {$ _. mô tả -ne "Tự động"} | biện pháp
Mike

@ Mike Có, đây dường như là hành vi của các -netoán tử so sánh trong các -Filterkhối duy nhất. Cụ thể, khi giá trị đầu vào của so sánh là $null.
jscott

1
Thích và không thích dường như làm việc tương tự. {description -notlike "Something"} không hoạt động, nhưng {-not (giống như mô tả "cái gì đó")} thì không. Ngoài ra một trong những hoạt động mất nhiều thời gian để đánh giá. Giống như người bị hỏng không đánh giá tất cả các đối tượng cần.
Mike

@Mike Đúng vậy. Tôi thực sự vấp phải điều này bằng cách sử dụng -notlikeban đầu, nhưng chuyển sang -nesau khi tôi nhận ra tôi không nhận được những gì tôi muốn. TBH, tôi quên tôi thậm chí đã thử nó cho đến khi bạn đề cập đến nó - nhưng tôi cũng có thể sao chép nó.
MDMarra

2
Chỉ là một ý nghĩ nhưng có lẽ mệnh đề -eq/ -nemệnh đề của PoSH cố gắng hoạt động như một SQL =/ <>? Trong SQL, foo = NULLfoo <> NULLsẽ luôn trả về false, vì NULL là "không thể so sánh" - chỉ các toán tử đặc biệt foo IS NULLfoo IS NOT NULLmới hoạt động. Hành vi phải tương tự trong PoSH, trong đó -not (foo -eq "bar")bộ lọc của bạn sẽ trả về mọi thứ được (foo -eq "bar")trả về $false, foo -eq $nullsẽ làm gì. Thay vào đó, làm thế nào về if (!foo -or foo -ne "bar")(SQL tương đương foo IS NULL OR foo <> 'bar')?
jimbobmcgee

Câu trả lời:


4

Sự khác biệt chính giữa hai là lệnh đầu tiên không liên quan đến việc so sánh trực tiếp các giá trị để có được tất cả các kết quả và lệnh thứ hai thì có. Lệnh đầu tiên bao gồm các kết quả NULL và lệnh thứ hai thì không (như MDMarra đã được phát hiện). Cả hai lệnh bắt đầu với lệnh ghép ngắn này:

get-aduser

Khi đi qua phần bên dưới, hãy nhớ rằng kết quả của lệnh ghép ngắn này bao gồm tất cả người dùng AD bất kể mọi thứ khác trong -filtertham số sau nó.

Bây giờ hãy chia nhỏ hai phần khác nhau. Cái đầu tiên:

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

...có nghĩa

  1. "tìm ra nơi thuộc tính mô tả bằng chuỗi văn bản" auto ". Để so sánh này hoạt động, một chuỗi cần tồn tại trong trường mô tả để -eqtoán tử có thể so sánh nó với" auto ". Các giá trị NULL được loại bỏ khỏi điều này so sánh vì nó không thể so sánh NULL với giá trị chuỗi.
  2. độc lập với -eqtham số bộ lọc cung cấp cho tôi MỌI THỨ KHÔNG phải là kết quả (description -eq "auto"), sẽ bao gồm các NULL, vì lệnh ghép gốc get-aduser, bao gồm tất cả người dùng AD. Nó không phải so sánh bất cứ điều gì với bất cứ điều gì khác với -notnhà điều hành. Nó chỉ cung cấp cho bạn mọi thứ ngoài kết quả của (description -eq "auto")bộ lọc.

Trong ví dụ của bạn, giả sử bạn có 1 người dùng AD có mô tả của họ bằng "tự động", vài trăm với một cái gì đó không phải là "tự động" và vài trăm với mô tả NULL. Bước qua logic lệnh nó sẽ làm:

  1. Cung cấp cho tôi tất cả người dùng AD (get-aduser) trong đó mô tả bằng "tự động" - kết quả là 1 người dùng
  2. Hãy cho tôi tất cả những người dùng quảng cáo KHÔNG phải là những gì bạn vừa cho tôi - kết quả là vài trăm với thứ khác VÀ vài trăm người có NULL.

Vì nó không phải so sánh bất cứ thứ gì với bất kỳ thứ gì khác bằng cách sử dụng -nottoán tử, kết quả bao gồm người dùng mô tả NULL đã được ghi lại trong get-aduserlệnh ghép ngắn ban đầu .

Lệnh thứ hai:

{description -ne "auto"}

...có nghĩa

  1. "tìm ra nơi thuộc tính mô tả không bằng chuỗi" auto "chính xác. Một lần nữa, để so sánh này hoạt động, một chuỗi cần tồn tại trong trường mô tả để -netoán tử có thể so sánh nó với" auto ". được loại bỏ khỏi so sánh này vì nó không thể so sánh NULL với giá trị chuỗi.

Trong ví dụ của bạn một lần nữa giả sử bạn có 1 người dùng AD có mô tả của họ bằng "tự động", vài trăm với một cái gì đó không phải là "tự động" và vài trăm với mô tả NULL. Bước qua logic lệnh nó sẽ làm:

  1. Cung cấp cho tôi tất cả người dùng quảng cáo nơi mô tả không bằng "tự động" - kết quả trong vài trăm người dùng có nội dung khác với "tự động" trong mô tả của họ. Nó không kéo người dùng bằng các mô tả NULL vì nó không thể so sánh NULL với chuỗi văn bản.

Dù bằng cách nào, toàn bộ sự khác biệt giữa hai lệnh chắc chắn là không trực quan.

Sử dụng lệnh này, bạn sẽ có thể bắt được các NULL với "-and" trong đó giống như thế này:

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

Tôi không 100% về cú pháp vì tôi không thể kiểm tra nó ngay bây giờ và có lẽ có một cách tốt hơn để làm điều đó hơn là cú pháp này. Khi tất cả bị phá vỡ, nó khá chống khí hậu và phải gõ rất nhiều để giải thích, nhưng tôi đã gặp phải những thứ kỳ lạ như thế này trước khi sử dụng các toán tử khác nhau và rất nhiều thử nghiệm và lỗi vì tôi không bao giờ có thể nhớ tất cả các cảnh báo đi cùng với việc sử dụng mỗi một.

Tham khảo: http://technet.microsoft.com/en-us/l Library / hh847732.aspx :

Toán tử so sánh

Sử dụng các toán tử so sánh (-eq, -ne, -gt, -lt, -le, -ge) để so sánh các giá trị và điều kiện kiểm tra. Ví dụ: bạn có thể so sánh hai giá trị chuỗi để xác định xem chúng có bằng nhau không.

Các toán tử so sánh bao gồm các toán tử khớp (-match, -notmatch), tìm các mẫu bằng cách sử dụng các biểu thức thông thường; toán tử thay thế (-replace), sử dụng các biểu thức chính quy để thay đổi giá trị đầu vào; các toán tử like (-like, -notlike), tìm các mẫu sử dụng các ký tự đại diện (*); và các toán tử ngăn chặn (in, -notin, -contains, -notcontains), xác định xem giá trị thử nghiệm có xuất hiện trong tập tham chiếu hay không.

Chúng cũng bao gồm các toán tử bitwise (-bAND, -bOR, -bXOR, -bNOT) để thao tác các mẫu bit trong các giá trị.

Để biết thêm thông tin, hãy xem about_Comparison_Operators

Toán tử logic

Sử dụng các toán tử logic (-and, -or, -xor, -not ,!) Để kết nối các câu điều kiện thành một điều kiện phức tạp duy nhất . Ví dụ: bạn có thể sử dụng toán tử logic và để tạo bộ lọc đối tượng với hai điều kiện khác nhau.

Để biết thêm thông tin, hãy xem about_Logical_Operators.


Tổng quan tốt chắc chắn, nhưng tại sao các giá trị null được loại trừ khỏi các toán tử -ne và -không thích? Đó là người gãi đầu thực sự. Tôi đang tự hỏi nếu thiết kế của nó có một số giải thích đặc tả bí mật .net hoặc nếu đó là một lỗi hoặc hành vi không mong muốn?
MDMarra

Chờ đã, chỉ cần đọc kỹ hơn. Có vẻ như họ chỉ so sánh các chuỗi và các thuộc tính null thực sự là null và không phải là một chuỗi rỗng. Thú vị nếu không trực quan.
MDMarra

0

Thêm vào câu hỏi cũ này khi nó xuất hiện khi tìm kiếm:

Sử dụng -Filter với kết quả phủ định như -ne hoặc -notlike sẽ loại trừ kết quả với các giá trị null trống. Để bao gồm chúng, bạn cũng cần phải khớp một cách rõ ràng bằng cách sử dụng -notlike '*' as -eq ''-eq $ NULL không phải là các bộ lọc hợp lệ. Lưu ý đây là một cách giải quyết với -Filter, sử dụng một -LdapFilter trực tiếp DOES khớp với các giá trị trống.

Dưới đây là ví dụ về Bộ lọc và LdapFilter của đa kết hợp với phủ định:

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

Get-ADUser -LdapFilter '(&(mail=*example*)(!description=example))'
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.