Weisheiten - der Netz-Weise Blog
Parametrisierte Programme in Powershell starten am Beispiel von 7Zip
Wenn man in Powershell ein ausführbares Programm starten möchte, kann man das normalerweise machen, indem man den direkten Pfad in der in der Konsole einfach aufruft. Genauso kann man ein Programm in einem Script direkt referenzieren.
C:\programme\7zip\7z.exe
Problematischer wird das, wenn der Pfad, in dem sich das Programm befindet, Leerzeichen enthält. Der Programmpfad muß dann in Anführungszeichen gesetzt werden, wird nun aber als String interpretiert und kann nicht mehr direkt aufgerufen. Powershell gibt stattdessen einfach nur den String zurück.
'C:\Program Files\7Zip\7z.exe'
C:\Program Files\7Zip\7z.exe
Die Lösung bietet der Ausführungsoperator &, der Powershell anweist, den folgenden String direkt auszuführen:
& 'C:\Program Files\7Zip\7z.exe'
Wenn dem Programm aber Parameter übergeben sollen, verhält sich der Ausführungsoperator erst einmal merkwürdig. Gibt man nämlich den Befehl inklusive der Parameter im String ein, erhält man eine Fehlermeldung:
& "'C:\Program Files\7Zip\7z.exe x -oC:\temp\extract C:\temp\archiv.7z"
& : Die Benennung ".\7z.exe x -oC:\temp\extract 'C:\temp\website test\website.7z'" wurde nicht als Name eines Cmdlet, einer Funktion, einer Skriptdatei oder eines ausführbaren Programms erkannt.
Der Ausführungsoperator benötigt die auszuführende Datei als einzelnen String. Die naheliegende Lösung ist also, die Parameter als zweiten String zu übergeben:
& "C:\Program Files\7Zip\7z.exe" "x -oC:\temp\extract C:\temp\archiv.7z"
Command Line Error:
Unsupported command:
x -oC:\temp\extract 'C:\temp\archiv.7z'
Tatsächlich müssen alle Parameter einzeln in einem Array übergeben werden, damit der Befehl korrekt ausgeführt wird. Achten Sie darauf, dass die Parameter Kommasepariert aufgelistet sind!
$arguments = "x","-oC:\temp\extract","C:\temp\archiv.7z"
& "C:\Program Files\7Zip\7z.exe" $arguments
Die Ausgabe des Befehls kann aufgefangen werden, indem man sie in eine Variable umleitet:
$Returnvalue = & "C:\Program Files\7Zip\7z.exe" $arguments
Man kann das Problem auch vermeintlich elegant mit Start-Process lösen:
Start-Process -FilePath C:\Program Files\7Zip\7z.exe -ArgumentList 'x -oc:\temp\extract C:\temp\archive.7z' -NoNewWindow -Wait
Das hat allerdings einen anderen Haken, denn die Rückgabe von 7z.exe kann nicht mehr aufgefangen werden, da Start-Process eine eigene Konsole startet. Möchten Sie die Rückgabe unterdrücken, indem Sie sie z.B. in die Variable $null umleiten, funktioniert das mit Start-Process nicht:
$null = Start-Process -FilePath C:\Program Files\7Zip\7z.exe -ArgumentList 'x -oc:\temp\extract C:\temp\archive.7z' -NoNewWindow -Wait
7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
Scanning the drive for archives:
1 file, 117778 bytes (116 KiB)
Extracting archive: C:\temp\archive.7z
[...]
Beim Übergeben der Parameter müssen Sie außerdem noch den Sonderfall betrachten, dass auch in den Pfaden der Argumente Leerzeichen stehen können. Da der String selber schon mit " (Doppelten Anführungszeichen) markiert ist, kann man nicht einfach Anführungszeichen um den Pfad setzen, sonden muß Sie für Powershell als nicht interpretierbare Zeichen markieren. Das geschieht mit Hilfe des ` (Backtick oder für die Französischfreunde: Der Accent Graph):
$arguments = "x","-oC:\temp\extract","`"C:\temp\mein archiv.7z`""
& "C:\Program Files\7Zip\7z.exe" $arguments
Kommentare 4
Ist die dargestellte Lösung nicht viel zu kompliziert?
Sollte folgendes nicht auch funktioniren?
& 'befehl' 'argument1' 'argument2'
Jupp, funktioniert aber nicht immer, wie oben im Text beschrieben:
& 'C:\Program Files\7-Zip\7z.exe' 'x' 'C:\Users\Urmel\Documents\temp\temp mit LZ.7z' '-oD:\Ordner mit Leerzeichen\'
Danke für den Tipp.