PowerShell - Meneruskan FilterScript ke Where-Object sebagai variabel
Saya mencoba untuk mendapatkan scriptblock Where-Object FilterScript menjadi variabel, tetapi saya tidak beruntung sejauh ini. Sebagai contoh sederhana dari apa yang saya coba lakukan:
$test = @('one','two','three') $filter = '$_ -eq "one"' $test | Where-Object -FilterScript { $filter }
Ini sepertinya tidak berhasil; Saya mendapatkan kembali semua elemen. Saya juga sudah mencoba:
$filter = { $_ -eq "one" } $filter = [scriptblock]::Create($_ -eq 'one')
Ini semua kembali:
one
two
three
Namun, mengganti variabel dengan filter sebenarnya berfungsi seperti yang diharapkan:
$test | Where-Object -FilterScript { $_ -eq "one" }
Ini hanya mengembalikan "satu", tanpa "dua" dan "tiga". Adakah yang tahu bagaimana saya bisa membuat ini bekerja? Saya awalnya mencobanya di Core v7.0.3, tetapi diuji di Windows PowerShell v5.1 juga.
Jawaban
Tanda kurung kurawal setelah -FilterScriptmengacaukan Anda, setelah variabel berisi ScriptBlock Anda tidak memerlukan tanda kurung itu lagi. Jika Anda memilikinya di sana, itu adalah scriptblock dari variabel yang berisi scriptblock.
$foo = "hi" $foo | gm (TypeName: String)
{$foo} | gm (TypeName: ScriptBlock)
Jika Anda menambahkan [scriptblock]ke $filtervariabel Anda untuk mengetik variabel dengan kuat, itu mengeluh tentang pemformatan sampai Anda menambahkan tanda kurung saat Anda mendefinisikan variabel Anda. Ini adalah cara yang bagus untuk memastikan objek yang Anda beri makan Where-Objectcocok dengan tipe yang diharapkan untuk -FilterScriptparameternya yaituScriptBlock
Ini akan bekerja tanpa memaksa tipe yang kuat begitu kurung kurawal berada dalam definisi variabel, yang menyebabkannya menjadi ScriptBlock, tetapi saya akan membiarkan jenisnya di sana sehingga mesin mengeluh jika seseorang menghapus kurung kurawal dan tidak menyadarinya sedang mengubah jenis variabel Anda dalam prosesnya.
$test = @('one','two','three') [scriptblock]$filter = { $_ -eq "one" } $test | Where-Object -FilterScript $filter
one