如果作为参数传递给函数,PowerShell中的'Get-ChildItem -Include / -Exclude'不会过滤

时间:2010-02-09 15:21:40

标签: powershell include get-childitem

我在函数中向Get-ChildItem获取过滤器参数时遇到问题。

以下工作正常并显示整个文件列表:

c:\temp\Get-ChildItem -Include *deleteme*.txt -Recurse

现在说我有以下脚本

#file starts here
#filename = GetLastFile.ps1

param([string] $filter)

$files = Get-ChildItem $filter

Write-Host $files #should print all matching files but prints nothing

$file = $files | Select-Object -Last 1;


$file.name  #returns filename
#File ends here

现在尝试运行脚本,

c:\temp.\GetLastFile.ps1 "-Include *deleteme*.txt -Recurse"

什么都不返回。

提供过滤器*.*,工作正常。由于-Include-Exclude,它似乎失败了。有什么想法吗?

3 个答案:

答案 0 :(得分:5)

您开始进入Powershell 2.0代理功能可以提供帮助的区域。但是,如果没有这个,这里有一个简单的方法在PowerShell 2.0中执行此操作,假设您只需要-Include和-Recurse。实际上,我建议使用-Filter,它会做你想要的,坦率地说它的速度要快一些(在我的一些测试中是4倍),因为-filter使用操作系统提供的文件系统过滤,而-include由PowerShell处理。

param([string]$Filter, [switch]$Recurse)

$files = Get-ChildItem @PSBoundParameters

Write-Host $files #should print all matching files but prints nothing

$file = $files | Select-Object -Last 1;

$file.name #returns filename

@符号用于将参数中的数组或散列表“splat”到命令。 $ PSBoundParameters变量是PowerShell 2.0新增的自动变量,在函数中定义。它是一个包含所有有界(命名和位置)参数的哈希表,例如:

PS> function foo($Name,$LName,[switch]$Recurse) { $PSBoundParameters }
PS> foo -Name Keith Hill -Recurse

Key                                                         Value
---                                                         -----
Name                                                        Keith
Recurse                                                     True
LName                                                       Hill

当您针对命令展开这样的哈希表时,PowerShell会将密钥(例如Recurse)值映射到命令上名为Recurse的参数。

答案 1 :(得分:0)

我相信正在发生的事情是你的$ filter参数被视为Get-ChildItem命令的单个字符串参数。因此,除非您有一个名为“-Include deleteme.txt -Recurse”的目录,否则该命令将始终不返回任何内容。

至于解决问题,嗯,有很多方法可以解决它。可能一种更通用的方法是在传递$ filter参数时切换程序行为,而不是传递整个过滤器字符串,只需传递“deleteme.txt”字符串。

答案 2 :(得分:0)

您可以使用Invoke-Expression执行存储在变量中的命令。例如:

param([string] $filter)
$files = Invoke-Expression "Get-ChildItem $filter"

Write-Host $files

$file = $files | Select-Object -Last 1

$file.name