PowerShellのこのADフィルターで一体何が起こっているのですか?


9

は最近この答え書いて、何か面白いものに出会いました。

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

そして

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

同じデータに対して実行すると2つの非常に異なるものを返し、最初のコマンドは期待値を返します。説明フィールドにNULL値を持つユーザーがいることを一見思わない NULLは明らかに「自動」に等しくないにも関わらず、2番目のコマンドで一致としてで返されます。

チャット中の数人の人がこれを見て、私が気が狂っていないことを確認しました。何が起きてる?


1
Where-objectを介してそれをパイプ処理し、上記で機能しないフィルターを適用することは興味深いことです。get-aduser -filter *-プロパティの説明| ?{$ _。description -ne "Auto"} | 測定
マイク

@マイクはい、これはブロック-ne比較演算子の動作のようです。具体的には、比較の入力値がの場合。-Filter$null
jscott 2013年

1
好きと嫌いは同じように動作するようです。{description -notlike "something"}は機能しませんが、{-not(description -like "something")}は機能します。また、機能するものの評価にはかなり時間がかかります。壊れたように、すべてのオブジェクトを評価するわけではありません。
Mike

@マイクそうです。私は実際にこれを使って偶然に偶然見つけましたが、自分が望んでいたものを取得していないことに気付い-notlike-ne後に切り替えました。TBH、あなたがそれを言うまでそれを試したことさえ忘れていました-私はそれを再現することもできます。
MDMarra 2013年

2
考えただけですが、PoSHの-eq/ -ne句はSQLのように動作します=/ <>?SQLでは、foo = NULLfoo <> NULLのみ- NULLは「比類のない」ですので、常にfalseを返しますfoo IS NULLfoo IS NOT NULL、特別な演算子は動作します。行動は、あなたの優雅な、で類似していなければならない-not (foo -eq "bar")フィルタは、そのためにすべて返す(foo -eq "bar")返され$falsefoo -eq $nullだろうが。代わりに、if (!foo -or foo -ne "bar")(同等のSQL foo IS NULL OR foo <> 'bar')はどうですか?
jimbobmcgee 2013年

回答:


4

2つの主な違いは、最初のコマンドはすべての結果を取得するための値の直接比較を必要とせず、2番目のコマンドはそうすることです。最初のコマンドにはNULLの結果が含まれ、2番目のコマンドには含まれません(MDMarraがすでに発見したため)。どちらのコマンドも次のコマンドレットで始まります。

get-aduser

以下の手順を実行するときは、このコマンドレットの結果には、-filterその後のパラメーターの他の部分に関係なく、すべてのADユーザーが含まれることに注意してください。

次に、異なる2つの部分を分解してみましょう。最初の1つ:

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

...手段

  1. "description属性テキスト文字列" auto " と等しい場所を見つけ出します。この比較が機能するためには、-eq演算子が" auto "と比較できるように文字列がdescriptionフィールドに存在する必要があります。NULL値はこれから削除されますNULLと文字列値を比較できないためです。
  2. 独立して -eq(description -eq "auto")元のコマンドレットget-aduserにはすべてのADユーザーが含まれているため、フィルターパラメーターはの結果ではないすべてを私に提供します。これにはNULLが含まれます。-notオペレーターと比較する必要はありませんでした。(description -eq "auto")フィルターの結果以外のすべてが得られました。

あなたの例では、 "auto"に等しい説明を持つ1人のADユーザーがいて、 "auto"以外の何かで数百人、NULLの説明で数百人いるとします。実行するコマンドロジックをステップ実行します。

  1. 説明が「auto」に等しいすべてのADユーザー(get-aduser)を取得します-1ユーザーになります
  2. ちょうどあなたが私に与えたものではないすべてのADユーザーを私に与えてください-結果は何か他のものを持つ数百とNULLを持つ数百です。

-not演算子を使用して他のものと比較する必要がないため、結果には、元のget-aduserコマンドレットでキャプチャされたNULLの説明ユーザーが含まれていました。

2番目のコマンド:

{description -ne "auto"}

...手段

  1. "description属性正確な文字列" auto " と等しくない場所を見つけ出します。ここでも、この比較が機能するためには、-ne演算子が" auto "と比較できるように文字列がdescriptionフィールドに存在する必要があります。NULL値NULLと文字列値を比較できないため、この比較から除外されます。

この例でも、「auto」と同じ説明を持つADユーザーが1人いるとします。数百は「auto」以外のもので、数百はNULLの説明です。実行するコマンドロジックをステップ実行します。

  1. 説明が「auto」と等しくないすべてのADユーザーを教えてください。数百人のユーザーの説明に「auto」以外のものが含まれています。NULLとテキスト文字列を比較できないため、NULLの説明でユーザーをプルしません。

どちらの方法でも、2つのコマンドの違いはまったく直感的ではありません。

このコマンドを使用すると、次のように "-and"でNULLをキャッチできるはずです。

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

今は構文をテストできないので、構文を完全に理解しているわけではありません。おそらく、これよりも優れた方法があります。すべてが分解されると、かなり気候が悪くなり、説明するのに多くの入力が必要になりますが、さまざまな演算子を使用する前に、このような奇妙なことに遭遇したり、すべての注意事項を思い出せないため、多くの試行錯誤を繰り返したりしました。それぞれを使用することでうまくいきます。

リファレンス:http : //technet.microsoft.com/en-us/library/hh847732.aspx

比較演算子

値とテスト条件を比較するには、比較演算子(-eq、-ne、-gt、-lt、-le、-ge)を使用します。たとえば、2つの文字列値を比較して、それらが等しいかどうかを判断できます。

比較演算子には、正規表現を使用してパターンを検索する一致演算子(-match、-notmatch)が含まれます。正規表現を使用して入力値を変更する置換演算子(-replace)。like演算子(-like、-notlike)。ワイルドカード文字(*)を使用してパターンを検索します。および包含演算子(in、-notin、-contains、-notcontains)は、テスト値が参照セットに表示されるかどうかを決定します。

また、値のビットパターンを操作するためのビット演算子(-bAND、-bOR、-bXOR、-bNOT)も含まれています。

詳細については、about_Comparison_Operatorsを参照してください。

論理演算子

論理演算子(-and、-or、-xor、-not 、!)を使用して、条件ステートメントを単一の複雑な条件に接続します。たとえば、論理AND演算子を使用して、2つの異なる条件を持つオブジェクトフィルターを作成できます。

詳細については、about_Logical_Operatorsを参照してください。


概要は確かですが、null値が-neおよび-notlike演算子から除外されるのはなぜですか?それは本当の頭のスクラッチャーです。設計上、難解な.net仕様の説明があるのか​​、それともバグなのか、予期しない動作なのか?
MDMarra 2013年

待って、もっとよく読んでください。それらは文字列のみを比較し、null属性は実際にはnullであり、空の文字列ではないようです。直感的でない場合は興味深い。
MDMarra 2013年

0

検索時に出てくるこの古い質問に追加:

-neや-notlikeなどの否定一致で-Filterを使用すると、空のnull値の結果が除外されます。それらを含めるには、-notlike '*' as -eq ''および-eq $ NULLを使用して明示的に一致させる必要もあり、有効なフィルターではありません。これは-Filterの癖であり、直接の-LdapFilterは空の値との否定的な一致を行います。

以下は、負の複数一致のFilterおよびLdapFilterの例です。

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

Get-ADUser -LdapFilter '(&(mail=*example*)(!description=example))'
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.