PowerShell - 将 FilterScript 作为变量传递给Where-Object

Dar*_*oon 3 powershell

我正在尝试将Where-Object FilterScript 脚本块放入变量中,但到目前为止我还没有运气。作为我正在尝试做的事情的一个简单示例:

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

这似乎不起作用;我拿回了所有元素。我也尝试过:

$filter = { $_ -eq "one" }
$filter = [scriptblock]::Create($_ -eq 'one')
Run Code Online (Sandbox Code Playgroud)

这些都返回:

one
two
three
Run Code Online (Sandbox Code Playgroud)

但是,用实际过滤器替换变量可以按预期工作:

$test | Where-Object -FilterScript { $_ -eq "one" }
Run Code Online (Sandbox Code Playgroud)

这仅返回“一”,没有“二”和“三”。有谁知道我怎样才能做到这一点?我最初是在 Core v7.0.3 上尝试的,但也在 Windows PowerShell v5.1 上进行了测试。

Gar*_*ett 5

之后的大括号-FilterScript会让你变得混乱,一旦变量包含 ScriptBlock,你就不再需要这些大括号了。如果那里有它们,那么它是包含脚本块的变量的脚本块。

$foo = "hi"
$foo | gm     (TypeName: String)
{$foo} | gm   (TypeName: ScriptBlock)
Run Code Online (Sandbox Code Playgroud)

如果您添加[scriptblock]$filter变量以强类型变量,它会抱怨格式,直到您在定义变量时添加大括号为止。这是确保您提供的对象与其参数Where-Object的预期类型匹配的好方法-FilterScript,即ScriptBlock

一旦大括号位于变量定义中,它就可以在没有强制强类型的情况下工作,这会导致它成为一个 ScriptBlock,但我会将类型保留在那里,这样如果有人删除了大括号并且没有意识到它们,引擎就会抱怨在此过程中更改变量类型。

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