web-dev-qa-db-fra.com

Comment filtrer correctement plusieurs chaînes dans un script de copie PowerShell

J'utilise le script PowerShell de cette réponse pour faire une copie de fichier. Le problème se pose lorsque je souhaite inclure plusieurs types de fichiers à l'aide du filtre.

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

fonctionne comme un rêve. Cependant, le problème se pose lorsque je souhaite inclure plusieurs types de fichiers à l'aide du filtre.

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 donne l'erreur suivante:

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

J'ai plusieurs itérations de parenthèses, pas de parenthèses, -filter, -include, Définissant les inclusions comme variable (par exemple, $fileFilter) Et chaque fois, obtenant l'erreur ci-dessus, et pointant toujours à tout ce qui suit -filter.

L'exception intéressante à cela est quand je code -filter "*.gif,*.jpg,*.xls*,*.doc*,*.pdf*,*.wav*,*.ppt*". Il n'y a pas d'erreur, mais je n'obtiens aucun résultat et rien ne retourne à la console. Je suppose que j'ai par inadvertance codé un and implicite avec cette déclaration?

Alors, que fais-je de travers et comment puis-je le corriger?

68
dwwilson66

- Filter n'accepte qu'une seule chaîne. - Include accepte plusieurs valeurs, mais qualifie l'argument - Path. L'astuce consiste à ajouter \* jusqu'à la fin du chemin, puis utilisez - Include pour sélectionner plusieurs extensions. En passant, les chaînes de caractères ne sont pas nécessaires dans les arguments d’applet de commande, sauf si elles contiennent des espaces ou des caractères spéciaux Shell.

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

Notez que cela fonctionnera que $ originalPath se termine par une barre oblique inverse, car plusieurs barres obliques inverses consécutives sont interprétées comme un séparateur de chemin unique. Par exemple, essayez:

Get-ChildItem C:\\\\\Windows
162
Adi Inbar

Quelque chose comme ça devrait marcher (ça a fonctionné pour moi). La raison de vouloir utiliser -Filter au lieu de -Include est que include prend un énorme succès en termes de performances par rapport à -Filter.

Vous trouverez ci-dessous une boucle de chaque type de fichier et de plusieurs serveurs/postes de travail spécifiés dans des fichiers distincts.

##  
##  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
2
Kevin