84

我正在使用此答案中的 PowerShell 脚本进行文件复制。当我想使用过滤器包含多种文件类型时,就会出现问题。

Get-ChildItem $originalPath -filter "*.htm"  | `
   foreach{ $targetFile = $htmPath + $_.FullName.SubString($originalPath.Length); ` 
 New-Item -ItemType File -Path $targetFile -Force;  `
 Copy-Item $_.FullName -destination $targetFile }

像梦一样工作。但是,当我想使用过滤器包含多种文件类型时,就会出现问题。

Get-ChildItem $originalPath ` 
  -filter "*.gif","*.jpg","*.xls*","*.doc*","*.pdf*","*.wav*",".ppt*")  | `
   foreach{ $targetFile = $htmPath + $_.FullName.SubString($originalPath.Length); ` 
 New-Item -ItemType File -Path $targetFile -Force;  `
 Copy-Item $_.FullName -destination $targetFile }

给我以下错误:

Get-ChildItem : Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 'Filter'. Specified method is not supported.
At F:\data\foo\CGM.ps1:121 char:36
+ Get-ChildItem $originalPath -filter <<<<  "*.gif","*.jpg","*.xls*","*.doc*","*.pdf*","*.wav*",".ppt*" | `
    + CategoryInfo          : InvalidArgument: (:) [Get-ChildItem], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgument,Microsoft.PowerShell.Commands.GetChildItemCommand

我有各种括号迭代,没有括号,-filter, -include,将包含项定义为变量(例如,$fileFilter)并且每次都得到上述错误,并且总是指向后面的任何内容-filter

有趣的例外是当我编写代码时-filter "*.gif,*.jpg,*.xls*,*.doc*,*.pdf*,*.wav*,*.ppt*"。没有错误,但我没有得到任何结果,也没有返回控制台。我怀疑我无意中and用该语句编写了一个隐含的代码?

那么我做错了什么,我该如何纠正呢?

4

5 回答 5

209

-Filter只接受单个字符串。-Include接受多个值,但限定-Path参数。诀窍是追加\*到路径的末尾,然后使用-Include选择多个扩展名。顺便说一句,在 cmdlet 参数中不需要引用字符串,除非它们包含空格或 shell 特殊字符。

Get-ChildItem $originalPath\* -Include *.gif, *.jpg, *.xls*, *.doc*, *.pdf*, *.wav*, .ppt*

请注意,无论$originalPath是否以反斜杠结尾,这都会起作用,因为多个连续的反斜杠被解释为单个路径分隔符。例如,尝试:

Get-ChildItem C:\\\\\Windows
于 2013-09-05T01:44:49.853 回答
3

像这样的东西应该有效(它对我有用)。想要使用-Filter而不是的原因-Include是 include 与-Filter.

下面只是循环每个文件类型和在单独文件中指定的多个服务器/工作站。

##  
##  This script will pull from a list of workstations in a text file and search for the specified string


## Change the file path below to where your list of target workstations reside
## Change the file path below to where your list of filetypes reside

$filetypes = gc 'pathToListOffiletypes.txt'
$servers = gc 'pathToListOfWorkstations.txt'

##Set the scope of the variable so it has visibility
set-variable -Name searchString -Scope 0
$searchString = 'whatYouAreSearchingFor'

foreach ($server in $servers)
    {

    foreach ($filetype in $filetypes)
    {

    ## below creates the search path.  This could be further improved to exclude the windows directory
    $serverString = "\\"+$server+"\c$\Program Files"


    ## Display the server being queried
    write-host “Server:” $server "searching for " $filetype in $serverString

    Get-ChildItem -Path $serverString -Recurse -Filter $filetype |
    #-Include "*.xml","*.ps1","*.cnf","*.odf","*.conf","*.bat","*.cfg","*.ini","*.config","*.info","*.nfo","*.txt" |
    Select-String -pattern $searchstring | group path | select name | out-file f:\DataCentre\String_Results.txt

    $os = gwmi win32_operatingsystem -computer $server
    $sp = $os | % {$_.servicepackmajorversion}
    $a = $os | % {$_.caption}

    ##  Below will list again the server name as well as its OS and SP
    ##  Because the script may not be monitored, this helps confirm the machine has been successfully scanned
        write-host $server “has completed its " $filetype "scan:” “|” “OS:” $a “SP:” “|” $sp


    }

}
#end script
于 2014-01-30T10:00:56.590 回答
1

让我们回顾一下选项:

  • -Filter只需要一种模式,所以它不适用于这个问题。

  • -Include工作但很慢(在许多情况下完全没问题)。

  • 管道传输Where-Object比 快得多-Include。它也是最强大的选项,因为它使您可以访问正则表达式模式匹配(而不是普通的通配符匹配)和您可能需要的任何其他逻辑,例如下面的示例:

    # checking extension with regex
    Get-ChildItem $dir |
        Where-Object { $_.Extension -match '\.(xlsx?|jpe?g)$' }
    
    # checking extension and creation time
    Get-ChildItem $dir | Where-Object {
        $_.Extension -in '.xls', '.xlsx', '.jpg', '.jpeg' -and
        $_.CreationTime -gt $yesterday
    }
    
  • -Path仍然稍微快一些,但采用完整路径而不是文件名,这很难使用(参见下面的示例),并且仅适用于简单的情况,因为路径模式无法匹配可变数量的目录级别。这与典型的 shell 不同,后者*匹配单个目录并**匹配任意数量的嵌套目录。

    # simpler
    $paths = $dir\*.xls, $dir\*.xlsx, $dir\*.jpg, $dir\*.jpeg
    Get-ChildItem $paths
    
    # less repetitive
    $paths = 'xls', 'xlsx', 'jpg', 'jpeg' | % { Join-Path $dir *.$_ }
    Get-ChildItem $paths
    
于 2021-09-02T19:25:40.780 回答
0
Get-ChildItem $originalPath\* -Include @("*.gif", "*.jpg", "*.xls*", "*.doc*", "*.pdf*", "*.wav*", "*.ppt")
于 2014-06-13T17:28:43.950 回答
-2

使用 include 是最简单的方法

http://www.vistax64.com/powershell/168315-get-childitem-filter-files-multiple-extensions.html

于 2013-09-04T14:46:15.277 回答