Cómo filtrar correctamente varias cadenas en un script de copia de PowerShell


Estoy usando el script de PowerShell de esta respuesta para hacer una copia de archivo. El problema surge cuando quiero incluir varios tipos de archivos usando el filtro.

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

Funciona como un sueño. Sin embargo, el problema surge cuando quiero incluir varios tipos de archivos usando el filtro.

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 }

Me da el siguiente error:

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

Tengo varias iteraciones de paréntesis, sin paréntesis, -filter, -include, definiendo las inclusiones como variable (por ejemplo, $fileFilter) y cada tiempo obtener el error anterior, y siempre apuntando a lo que sigue -filter.

La interesante excepción a eso es cuando codifico -filter "*.gif,*.jpg,*.xls*,*.doc*,*.pdf*,*.wav*,*.ppt*". No hay errores, pero yo y no obtener resultados y nada de nuevo a la consola. Sospecho que he codificado inadvertidamente un impicit and con esa declaración?

Entonces, ¿qué estoy haciendo mal y cómo puedo corregirlo?

Author: Community, 2013-09-04

4 answers

-Filter solo acepta una sola cadena. -Include acepta múltiples valores, pero califica el argumento -Path. El truco es añadir \* al final de la ruta, y luego usar -Include para seleccionar varias extensiones. Por cierto, las cadenas entre comillas no son necesarias en los argumentos de cmdlet a menos que contengan espacios o caracteres especiales del shell.

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

Tenga en cuenta que esto funcionará independientemente de si origin originalPath termina en una barra invertida, porque las barras invertidas consecutivas se interpretan como un único separador de ruta. Por ejemplo, intente:

Get-ChildItem C:\\\\\Windows
 131
Author: Adi Inbar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-05 01:44:49

Algo como esto debería funcionar (lo hizo para mí). La razón para querer usar -Filter en lugar de -Include es que include tiene un gran éxito de rendimiento en comparación con -Filter.

A continuación, solo hace un bucle de cada tipo de archivo y varios servidores/estaciones de trabajo especificados en archivos separados.

##  
##  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
 1
Author: Kevin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-21 14:53:41
 -2
Author: capsch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-04 14:46:15
Get-ChildItem $originalPath\* -Include @("*.gif", "*.jpg", "*.xls*", "*.doc*", "*.pdf*", "*.wav*", "*.ppt")
 -2
Author: DPC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-13 17:54:19