PowerShell - Passe FilterScript para Where-Object como variável
Estou tentando obter um bloco de script Where-Object FilterScript em uma variável, mas não tive sorte até agora. Como um exemplo simples do que estou tentando fazer:
$test = @('one','two','three') $filter = '$_ -eq "one"' $test | Where-Object -FilterScript { $filter }
Isso não parece funcionar; Eu recebo de volta todos os elementos. Eu também tentei:
$filter = { $_ -eq "one" } $filter = [scriptblock]::Create($_ -eq 'one')
Todos estes retornam:
one
two
three
No entanto, substituir a variável pelo filtro real funciona conforme o esperado:
$test | Where-Object -FilterScript { $_ -eq "one" }
Isso retorna apenas "um", sem "dois" e "três". Alguém sabe como posso fazer isso funcionar? Eu estava testando originalmente no Core v7.0.3, mas testei no Windows PowerShell v5.1 também.
Respostas
As chaves depois -FilterScriptestão bagunçando você, uma vez que a variável contém um ScriptBlock, você não precisa mais dessas chaves. Se você os tiver lá, é um scriptblock de uma variável contendo um scriptblock.
$foo = "hi" $foo | gm (TypeName: String)
{$foo} | gm (TypeName: ScriptBlock)
Se você adicionar [scriptblock]à sua $filtervariável para digitar fortemente a variável, ele reclamará da formatação até que você adicione as chaves ao definir sua variável. Esta é uma ótima maneira de garantir que o objeto que você está alimentando Where-Objectcorresponda ao tipo esperado para seu -FilterScriptparâmetro, que éScriptBlock
Ele funcionará sem que o tipo forte seja forçado uma vez que as chaves estão na definição de variável, o que faz com que se torne um ScriptBlock, mas eu deixaria o tipo lá para que o mecanismo reclamasse se alguém remover as chaves e não perceber estamos mudando seu tipo de variável no processo.
$test = @('one','two','three') [scriptblock]$filter = { $_ -eq "one" } $test | Where-Object -FilterScript $filter
one