PowerShell - Übergeben Sie FilterScript als Variable an Where-Object
Ich versuche, einen Where-Object FilterScript-Skriptblock in eine Variable zu integrieren, hatte aber bisher kein Glück. Als einfaches Beispiel für das, was ich versuche:
$test = @('one','two','three') $filter = '$_ -eq "one"' $test | Where-Object -FilterScript { $filter }
Das scheint nicht zu funktionieren; Ich bekomme alle Elemente zurück. Ich habe auch versucht:
$filter = { $_ -eq "one" } $filter = [scriptblock]::Create($_ -eq 'one')
Diese alle kehren zurück:
one
two
three
Das Ersetzen der Variablen durch den eigentlichen Filter funktioniert jedoch wie erwartet:
$test | Where-Object -FilterScript { $_ -eq "one" }
Dies gibt nur "eins" zurück, ohne "zwei" und "drei". Weiß jemand, wie ich diese Arbeit machen kann? Ich habe es ursprünglich unter Core v7.0.3 versucht, aber auch unter Windows PowerShell v5.1 getestet.
Antworten
Die geschweiften Klammern danach -FilterScriptbringen Sie durcheinander. Sobald die Variable einen ScriptBlock enthält, brauchen Sie diese Klammern nicht mehr. Wenn Sie sie dort haben, ist es ein Skriptblock einer Variablen, die einen Skriptblock enthält.
$foo = "hi" $foo | gm (TypeName: String)
{$foo} | gm (TypeName: ScriptBlock)
Wenn Sie [scriptblock]Ihrer $filterVariablen hinzufügen, um die Variable stark einzugeben, wird die Formatierung beanstandet, bis Sie die Klammern hinzufügen, wenn Sie Ihre Variable definieren. Dies ist eine großartige Möglichkeit, um sicherzustellen, dass das Objekt, das Sie füttern Where-Object, dem erwarteten Typ für seinen -FilterScriptParameter entsprichtScriptBlock
Es funktioniert, ohne dass der starke Typ erzwungen wird, sobald sich die geschweiften Klammern in der Variablendefinition befinden, was dazu führt, dass er zu einem ScriptBlock wird. Ich würde den Typ jedoch dort belassen, damit sich die Engine beschwert, wenn jemand die geschweiften Klammern entfernt und sie nicht erkennt Ändern Sie dabei Ihren Variablentyp.
$test = @('one','two','three') [scriptblock]$filter = { $_ -eq "one" } $test | Where-Object -FilterScript $filter
one