Get-ChildItem 和通配符以及过滤

Get-ChildItem and wildcards and filtering

我有两种不同的方法来获取具有通配符模式的文件:

Get-ChildItem "$ActivityLogDirectory/*.csv"

Get-ChildItem "$ActivityLogDirectory" -Filter *.csv

我更喜欢使用后者而不是前者,因为前者 (Get-ChildItem "$ActivityLogDirectory/*.csv") 有时会给我一个权限被拒绝的错误。

它们看起来 return 相同的结果,但是当我尝试使用此命令压缩生成的文件时:

Compress-Archive -Update -Path $CsvFiles -DestinationPath C:\Users\admin\Downloads\foo.zip

前者成功而后者失败并出现以下错误:

Compress-Archive : The path 'rgb dev automation store a_1-1_2194_20181120.csv'
either does not exist or is not a valid file system path.
At line:1 char:1
+ Compress-Archive -Update -Path $CsvFiles -DestinationPath C:\Users\ad ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (rgb dev automat...94_20181120.csv:String) [Compress-Archive], InvalidOperationException
    + FullyQualifiedErrorId : ArchiveCmdletPathNotFound,Compress-Archive

那么这两种使用通配符获取文件列表的方式有什么区别呢?或者换一种方式问,为什么使用 -Filter *.csv 会导致 Compress-Archive cmdlet 失败?

如果您从 shell 中 运行 使用 CSV 文件所在文件夹的位置进行此操作,则此方法可行。您通过将 $CsvFiles 变量传递给 Compress-Archive 所做的是尝试 运行 针对当前上下文中的文件名。要解决此问题,请传递完整路径 $CsvFiles.FullName:

$Csvfiles = (Get-Childitem $ActivityLogDirectory -Filter *.csv)
Compress-Archive -Update -Path $Csvfiles.fullname -DestinationPath C:\Users\admin\Downloads\foo.zip

您看到不同行为的原因是 Get-ChildItem:

输出的对象的 - 模糊的情境 - 字符串化行为

Get-ChildItem 输出恰好字符串化为 纯文件名 完整路径 时的详细信息, 碰巧 Get-ChildItem "$ActivityLogDirectory" -Filter *.csv 字符串化为文件名。

解决方法 是通过 FullName 属性 ( PSv3+ 语法):

$CsvFiles = (Get-ChildItem "$ActivityLogDirectory" -Filter *.csv).FullName