PowerShell - Przekaż FilterScript do Where-Object jako zmienna

Sep 11 2020

Próbuję uzyskać blok skryptu Where-Object FilterScript w zmiennej, ale nie miałem dotąd szczęścia. Jako prosty przykład tego, co próbuję zrobić:

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

To nie wydaje się działać; Odzyskuję wszystkie elementy. Próbowałem też:

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

Te wszystkie powracają:

one
two
three

Jednak zastąpienie zmiennej rzeczywistym filtrem działa zgodnie z oczekiwaniami:

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

Zwraca tylko „jeden”, bez „dwa” i „trzy”. Czy ktoś wie, jak mogę to zrobić? Początkowo próbowałem go na Core 7.0.3, ale testowałem także na Windows PowerShell v5.1.

Odpowiedzi

4 Garrett Sep 11 2020 at 15:41

Nawiasy klamrowe po nawiasach klamrowych -FilterScriptCię denerwują, gdy zmienna zawiera ScriptBlock, nie potrzebujesz już tych nawiasów. Jeśli je masz, jest to blok skryptu zmiennej zawierający blok skryptu.

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

Jeśli dodasz [scriptblock]do $filterzmiennej, aby zdecydowanie wpisać zmienną, narzeka na formatowanie, dopóki nie dodasz nawiasów klamrowych podczas definiowania zmiennej. Jest to świetny sposób na upewnienie się, że karmiony obiekt Where-Objectodpowiada oczekiwanemu typowi jego -FilterScriptparametru, którym jestScriptBlock

Będzie działać bez wymuszania silnego typu, gdy klamry znajdują się w definicji zmiennej, co powoduje, że staje się ScriptBlock, ale zostawiłbym ten typ w tym miejscu, więc silnik narzeka, jeśli ktoś usunie nawiasy i nie zdaje sobie z tego sprawy W trakcie tego procesu zmieniasz typ zmiennej.

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