为什么PowerShell Where-Object在传递变量时不起作用?

时间:2012-02-13 18:05:48

标签: powershell

功能

 function findf {
     Write-Host "Find files that match: $args"
     gci -r | Where-Object { $_.name -match ".*$args.*" }
 }

似乎不起作用。例如,

 findf .exe

- 打印一堆不限制输出到EXE文件的东西 -

任何想法我做错了什么?

如果我从PowerShell命令窗口运行相同的命令,则命令有效:

 gci -r | Where-Object { $_.name -match ".*.exe.*" }

这样可以正确显示与* .EXE模式匹配的文件

2 个答案:

答案 0 :(得分:4)

$args是一个表示集合参数的对象。

你应该:

  • 引用$args[0]以获取表示第一个参数的字符串
  • 使用param定义输入参数,如:

 function findf {
     param ([string]$SeachStr)
     Write-Host "Find files that match: $SeachStr"
     gci -r | Where-Object { $_.name -match ".*$SeachStr.*" }
 }

我总是提倡在可能的情况下使用param,因为您可以像我在示例中那样强力键入变量。否则,可能会做一些令人困惑的事情,例如将数组作为参数传递,这可能会导致各种难以跟踪的问题。

答案 1 :(得分:1)

$ args无效,因为过滤器是一个脚本块,并在其自己的范围内运行。每个范围都使用它自己的$ args进行初始化,因此您无法将$ args隐式传递给子范围。由于没有规定将参数传递给过滤器脚本块,因此您必须执行以下操作:

  function findf {
       Write-Host "Find files that match: $args"
       $filter = $args[0]
       gci -r | Where-Object { $_.name -match ".*$filter.*" }
   }

使用命名参数也有效,因为它会隐式传递给子范围。