Как правильно -фильтировать несколько строк в копии PowerShell script
Я использую PowerShell script из этого ответа, чтобы сделать копию файла. Проблема возникает, когда я хочу включить несколько типов файлов, используя фильтр.
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
с этим утверждением?
Так что я делаю неправильно, и как я могу его исправить?
Ответы
Ответ 1
-Filter принимает только одну строку. -Include принимает несколько значений, но квалифицирует аргумент -Path. Хитрость заключается в том, чтобы добавить \*
в конец пути, а затем использовать -Include, чтобы выбрать несколько расширений. BTW, цитирующие строки не нужны в аргументах cmdlet, если они не содержат пробелов или специальных символов оболочки.
Get-ChildItem $originalPath\* -Include *.gif, *.jpg, *.xls*, *.doc*, *.pdf*, *.wav*, .ppt*
Обратите внимание, что это будет работать независимо от того, закончится ли $originalPath обратная косая черта, потому что несколько последовательных обратных косых интерпретаций интерпретируются как разделитель одного пути. Например, попробуйте:
Get-ChildItem C:\\\\\Windows
Ответ 2
Что-то вроде этого должно работать (это было для меня). Причиной желания использовать -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 *.txt |
#-Include "*.xml","*.ps1","*.cnf","*.odf","*.conf","*.bat","*.cfg","*.ini","*.config","*.info","*.nfo","*.txt" |
Select-String -pattern 'cifs01' | 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
Ответ 3
использовать include - самый простой способ по
http://www.vistax64.com/powershell/168315-get-childitem-filter-files-multiple-extensions.html
Ответ 4
Get-ChildItem $originalPath\* -Include @("*.gif", "*.jpg", "*.xls*", "*.doc*", "*.pdf*", "*.wav*", "*.ppt")