PowerShell - Chuyển FilterScript đến Where-Object dưới dạng biến

Sep 11 2020

Tôi đang cố gắng đưa scriptblock Where-Object FilterScript vào một biến, nhưng tôi đã không gặp may. Như một ví dụ đơn giản về những gì tôi đang cố gắng làm:

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

Điều này dường như không hoạt động; Tôi nhận lại tất cả các yếu tố. Tôi cũng đã thử:

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

Tất cả đều trả về:

one
two
three

Tuy nhiên, việc thay thế biến bằng bộ lọc thực tế sẽ hoạt động như mong đợi:

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

Điều này chỉ trả về "một", không có "hai" và "ba". Có ai biết làm thế nào tôi có thể làm cho nó hoạt động? Ban đầu tôi đã thử nó trên Core v7.0.3, nhưng cũng đã thử nghiệm trên Windows PowerShell v5.1.

Trả lời

4 Garrett Sep 11 2020 at 15:41

Các dấu ngoặc nhọn sau -FilterScriptđó làm bạn rối tung lên, một khi biến chứa ScriptBlock thì bạn không cần các dấu ngoặc nhọn đó nữa. Nếu bạn có chúng ở đó, đó là một scriptblock của một biến chứa scriptblock.

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

Nếu bạn thêm [scriptblock]vào $filterbiến của mình để nhập mạnh biến, nó sẽ phàn nàn về định dạng cho đến khi bạn thêm dấu ngoặc nhọn khi xác định biến của mình. Đây là một cách tuyệt vời để đảm bảo đối tượng bạn đang cung cấp Where-Objectkhớp với loại mong đợi cho -FilterScripttham số của nó làScriptBlock

Nó sẽ hoạt động mà không cần buộc loại mạnh khi dấu ngoặc nhọn nằm trong định nghĩa biến, điều này khiến nó trở thành ScriptBlock, nhưng tôi sẽ để loại ở đó để động cơ phàn nàn nếu ai đó loại bỏ dấu ngoặc nhọn và không nhận ra họ đang thay đổi loại biến của bạn trong quá trình này.

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