I'm trying to get a Where-Object FilterScript scriptblock into a variable, but I have had no luck far. As a simple example of what I'm trying to do:
$test = @('one','two','three')
$filter = '$_ -eq "one"'
$test | Where-Object -FilterScript { $filter }
This doesn't seem to work; I get back all elements. I've also tried:
$filter = { $_ -eq "one" }
$filter = [scriptblock]::Create($_ -eq 'one')
These all return:
one
two
three
However, replacing the variable with the actual filter works as expected:
$test | Where-Object -FilterScript { $_ -eq "one" }
This returns only "one", without "two" and "three". Does anyone know how I can make this work? I was originally trying it on Core v7.0.3, but tested on Windows PowerShell v5.1 as well.
Best Answer
The curly braces after
-FilterScript
are messing you up, once the variable contains a ScriptBlock you don't need those braces anymore. If you have them there, it's a scriptblock of a variable containing a scriptblock.If you add
[scriptblock]
to your$filter
variable to strongly type the variable, it complains about the formatting until you add the braces when you define your variable. This is a great way to ensure the object you're feedingWhere-Object
matches the expected type for its-FilterScript
parameter which isScriptBlock
It will work without the strong type being forced once the braces are in the variable definition, which causes it to become a ScriptBlock, but I'd leave the type in there so the engine complains if somebody removes the braces and doesn't realize they're changing your variable type in the process.