PowerShell: passa FilterScript a Where-Object come variabile

Sep 11 2020

Sto cercando di ottenere un blocco di script Where-Object FilterScript in una variabile, ma finora non ho avuto fortuna. Come semplice esempio di quello che sto cercando di fare:

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

Questo non sembra funzionare; Riprendo tutti gli elementi. Ho anche provato:

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

Questi ritornano tutti:

one
two
three

Tuttavia, la sostituzione della variabile con il filtro effettivo funziona come previsto:

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

Restituisce solo "uno", senza "due" e "tre". Qualcuno sa come posso farlo funzionare? Inizialmente lo stavo provando su Core v7.0.3, ma l'ho testato anche su Windows PowerShell v5.1.

Risposte

4 Garrett Sep 11 2020 at 15:41

Le parentesi graffe dopo ti -FilterScriptstanno incasinando, una volta che la variabile contiene uno ScriptBlock non hai più bisogno di quelle parentesi graffe. Se li hai lì, è un blocco di script di una variabile che contiene un blocco di script.

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

Se aggiungi [scriptblock]alla tua $filtervariabile per digitare fortemente la variabile, si lamenta della formattazione fino a quando non aggiungi le parentesi quadre quando definisci la variabile. Questo è un ottimo modo per assicurarti che l'oggetto che stai alimentando Where-Objectcorrisponda al tipo previsto per il suo -FilterScriptparametro che èScriptBlock

Funzionerà senza che il tipo forte venga forzato una volta che le parentesi graffe sono nella definizione della variabile, il che fa sì che diventi uno ScriptBlock, ma lascerei il tipo lì così il motore si lamenta se qualcuno rimuove le parentesi graffe e non se ne rende conto stai cambiando il tipo di variabile nel processo.

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