PowerShellの罠:-eqは等価演算子でもあり、配列フィルタ演算子でもある

http://winscript.jp/powershell/222
左辺が配列の場合、-eqは等価演算子ではなく配列フィルタ演算子として解釈される。
以下は「配列と"item-b"という文字が等価であるかどうかの評価を戻す」のではなく、「配列から"item-b"という文字のアイテムのみを抜き出した配列を戻す」。

$("item-a", "item-b", "item-b", "item-c", "item-c", "item-c") -eq "item-b"   # → @("item-b", "item-b") が取得される

その動作が原因で、`$配列が入った変数 -eq $null`が評価されるときいかのようになってしまう。

if (@("item-a", "item-b", "item-c") -eq $null) { echo "t" } # 配列フィルタとして処理された結果、@() が評価されるので偽と判定されて、ifブロックは実行されない
if (@("item-a", "item-b", $null   ) -eq $null) { echo "t" } # 配列フィルタとして処理された結果、@($null) になるがこれは自動展開されて$nullが評価されるので偽と判定されて、ifブロックは実行されない
if (@("item-a", $null   , $null   ) -eq $null) { echo "t" } # 配列フィルタとして処理された結果、@($null, $null) になる。これは自動展開されないので真と判定されて、ifブロックは実行される

対策はヨーダ記法を使うこと。

if ($null -eq @("item-a", $null)) {} # これなら等価判定として処理され、ifブロックは実行されない



ちなみに-neも同様に配列フィルタ演算子でもある。

$("item-a", "item-b", "item-b", "item-c", "item-c", "item-c") -ne "item-b"   # → @("item-a", "item-c", "item-c", "item-c") が取得される



……Where-Objectあるんやから、この仕様要らんかったでしょ。