PowerShell - передать FilterScript в Where-Object как переменную
Я пытаюсь поместить блок сценария 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" }
Это возвращает только «один», без «два» и «три». Кто-нибудь знает, как я могу заставить это работать? Изначально я пробовал его на Core v7.0.3, но тестировал и на Windows PowerShell v5.1.
Ответы
Фигурные скобки после -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