Mit Powershell und 7Zip alle Dateien eines Ordners einzeln packen

Aus bknowledgebase
Zur Navigation springen Zur Suche springen

Einleitung[Bearbeiten]

Wenn man alle Dateien in einem Ordner einzeln per CLI und 7Zip packen möchte kann man das folgendermaßen tun:

Kurzanleitung[Bearbeiten]

Hier werden z.B. alle .pst-Dateien in dem Ordner "d:\testordner" in 7zip-Dateien verpackt, die den gleichen Namen tragen


Get-ChildItem "D:\testordner" -filter "*.pst" | foreach-object {./7z a -t7z "$($_.FullName).7z" $_.FullName}


Kurz in Worten von links nach rechts:

Hol mit alle Dateien aus dem Ordner "D:\testordner" gefiltert nach der Dateiendung "pst" > Für jedes dieser Objekte tue folgendes > 7z.exe aufrufen mit dem "add" commando (a) und Typ 7zip-Archiv (t7z) der ARchivname soll dabei bitte dem Originalnamen der aktuellen Datei plus ".7z" entsprechen und das bitte für diese Datei "$_.FullName" (Vollständiger Pfad des aktuellen objektes/Datei)


Das Ganze geht auch mit Passwort[Bearbeiten]

In diesem Fall werden alle 7z-Files noch mit Passwort "secret" verschlüsselt. Außerdem nehme ich hier alle dateien aus einer Ordnerstruktur also Recursiv, die .pdf-Files sind.

 Get-ChildItem -r "D:\test\" -filter "*.pdf" | foreach-object {./7z a -t7z -psecret "$($_.FullName).7z" $_.FullName}

Hinweise[Bearbeiten]

Das einzig "knifflige" hierbei ist ggf. die Syntax "$($_.FullName).7z". Hier ist es so, ich muss den Namen des archivs angeben, in welches ich die Datei verpacken möchte. Also 'Dateiname.7z'.

Jetzt wäre die erste Idee an dieser Stelle einfach $_.FullName + ".7z" zu schreiben. Also den original Dateinamen des aktuellen objektes samt pfad plus "7z" als Endung. Hier ist es allerdings so, das Powershell das nicht frisst an dieser Stelle, da wir uns inmitten der ForEach-Schleife befinden. Deswegen muss eine Spezielle Syntax innerhalb des Strings genutzt werden. Also innerhalb der doppelten Hochkommata in denen der Dateiname steht sagt man mit $( erstmal, ACHTUNG hier kommt eine Variable die IN den String eingefügt werden soll. Dann eben das was ich einfügen will $_.FullName und Klammer wieder zu ) und dann geht der String "weiter" also fehlt noch das "7z".


Ich gehe hier davon aus, dass man bereits per cd in den Ordner navigiert hat in dem die 7z.exe liegt. Ansonsten muss man eben noch den Pfad zu der Datei angeben.


Beispielscripte[Bearbeiten]

Mit anschließendem Löschen der Originalfiles[Bearbeiten]

cd "C:\Program Files\7-Zip"
Get-ChildItem -r "C:\<Zielpfad>" -filter "*.pdf" | foreach-object {
 ./7z a -t7z "$($_.FullName).7z" $_.FullName
 rm $_.FullName
}


Zusätzlicher Loop[Bearbeiten]

Hier wird das Ganze dann auch noch für viele Dateitypen wiederholt um mehr in einem Abwasch zu erledigen. Leider ist es scheinbar nicht möglich den Parameter "Filter" so zu nutzen, dass dieser mehrere Filter enthält. Oder ich habe es noch nicht rausgefunden, dann bin ich für Kommentare dankbar :).

cd "C:\Program Files\7-Zip"
[String[]] $filetypes = "pdf","xml","doc","docx","xls","xlsx","pst","ppt","pptx","txt"

foreach($type in $filetypes){
   
    $currentFilter = "*." + $type
    Get-ChildItem -r "C:\<Zielpfad>" -filter $currentFilter | foreach-object {
    ./7z a -t7z "$($_.FullName).7z" $_.FullName
    rm $_.FullName
    }
}

Löschen nur im Erfolgsfall[Bearbeiten]

Jetzt ist das Löschen der Originaldatei relativ gefährlich. Wenn z.B. das Zippen nicht klappt, weil z.B. Pfade zu lang sind dann kann es passieren, dass die Datei nicht gezippt wird (weil Fehler) aber danach die originaldatei trotzdem gelöscht wird. Deshalb hier noch eine If-Abfrage die Prüft ob die .7z Datei am ende auch erstellt wurde.

cd "C:\Program Files\7-Zip"
[String[]] $filetypes = "pdf","xml","doc","docx","xls","xlsx","pst","ppt","pptx","txt"

foreach($type in $filetypes){
    
    $currentFilter = "*." + $type
    Get-ChildItem -r "C:\<Zielpfad>" -filter $currentFilter | foreach-object {
    ./7z a -t7z "$($_.FullName).7z" $_.FullName
    
    if(Test-Path "$($_.FullName).7z"){
        rm $_.FullName
    }
    }

}