PowerShell-FilterScriptをWhere-Objectに変数として渡します

Sep 11 2020

Where-Object FilterScriptスクリプトブロックを変数に入れようとしていますが、うまくいきませんでした。私がやろうとしていることの簡単な例として:

$test = @('one','two','three') $filter = '$_ -eq "one"' $test | Where-Object -FilterScript { $filter }

これは機能していないようです。私はすべての要素を取り戻します。私も試しました:

$filter = { $_ -eq "one" } $filter = [scriptblock]::Create($_ -eq 'one')

これらはすべて戻ります:

one
two
three

ただし、変数を実際のフィルターに置き換えると、期待どおりに機能します。

$test | Where-Object -FilterScript { $_ -eq "one" }

これは、「2」と「3」なしで「1」のみを返します。誰かが私がこれを機能させる方法を知っていますか?私はもともとCorev7.0.3で試していましたが、Windows PowerShellv5.1でもテストしました。

回答

4 Garrett Sep 11 2020 at 15:41

後の中括弧-FilterScriptはあなたを混乱させます。変数にScriptBlockが含まれると、それらの中括弧はもう必要ありません。それらがある場合、それはスクリプトブロックを含む変数のスクリプトブロックです。

$foo = "hi" $foo | gm     (TypeName: String)
{$foo} | gm   (TypeName: ScriptBlock)

変数を強く入力する[scriptblock]ために$filter変数に追加すると、変数を定義するときに中括弧を追加するまで、フォーマットについて文句を言います。これは、フィードするオブジェクトがWhere-Objectその-FilterScriptパラメーターの予想されるタイプと一致することを確認するための優れた方法です。ScriptBlock

中括弧が変数定義に含まれると、強い型が強制されることなく機能します。これにより、中括弧がScriptBlockになりますが、中括弧を削除して気付かない場合にエンジンが文句を言うように、型をそのままにしておきます。その過程で変数タイプを変更しています。

$test = @('one','two','three') [scriptblock]$filter = { $_ -eq "one" } $test | Where-Object -FilterScript $filter
one