web-dev-qa-db-de.com

So filtern Sie mehrere Zeichenfolgen in einem PowerShell-Kopierskript ordnungsgemäß

Ich verwende das PowerShell-Skript von diese Antwort , um eine Dateikopie zu erstellen. Das Problem tritt auf, wenn ich mithilfe des Filters mehrere Dateitypen einschließen möchte.

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

funktioniert wie ein Traum. Das Problem tritt jedoch auf, wenn ich mithilfe des Filters mehrere Dateitypen einschließen möchte.

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 }

Gibt mir folgenden Fehler:

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

Ich habe verschiedene Iterationen von Klammern, keine Klammern, -filter, -include, Definieren der Einschlüsse als Variable (z. B. $fileFilter) und erhalte jedes Mal den obigen Fehler und zeige immer auf das, was folgt -filter.

Die interessante Ausnahme ist, wenn ich -filter "*.gif,*.jpg,*.xls*,*.doc*,*.pdf*,*.wav*,*.ppt*". Es gibt keine Fehler, aber ich bekomme keine Ergebnisse und nichts zurück zur Konsole. Ich vermute, ich habe versehentlich ein implizites and mit dieser Aussage codiert?

Was mache ich also falsch und wie kann ich das korrigieren?

68
dwwilson66

- Filter akzeptiert nur einen einzelnen String. - Include akzeptiert mehrere Werte, qualifiziert aber das Argument - Path. Der Trick besteht darin, \* An das Ende des Pfads anzuhängen und dann - Include zu verwenden, um mehrere Erweiterungen auszuwählen. Übrigens ist es in Cmdlet-Argumenten nicht erforderlich, Zeichenfolgen in Anführungszeichen zu setzen, es sei denn, sie enthalten Leerzeichen oder Shell-Sonderzeichen.

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

Beachten Sie, dass dies unabhängig davon funktioniert, ob $ originalPath mit einem umgekehrten Schrägstrich endet, da mehrere aufeinanderfolgende umgekehrte Schrägstriche als Trennzeichen für einen einzelnen Pfad interpretiert werden. Versuchen Sie zum Beispiel:

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

So etwas sollte funktionieren (bei mir). Der Grund für die Verwendung von -Filter Anstelle von -Include Ist, dass include im Vergleich zu -Filter Einen enormen Leistungseinbruch darstellt.

Im Folgenden werden nur die einzelnen Dateitypen und mehrere Server/Workstations, die in separaten Dateien angegeben sind, wiederholt.

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