PowerShell-Fallen #5: Doppelte, einfache, maskierte Anführungszeichen

Veröffentlicht am Kategorisiert in PowerShell Keine Kommentare zu PowerShell-Fallen #5: Doppelte, einfache, maskierte Anführungszeichen

Gerade für Pfadangaben sind „Gänsefüßchen“ unverzichtbar, damit Whitespace als Teil des Pfades interpretiert wird. Klassiker: C:\Program Files

Manchmal soll der Pfad aber gar nicht sofort von PowerShell verwertet, sondern zusammen mit den Anführungszeichen irgendwohin geschrieben werden, um sie dann später von einem anderen Prozess wieder einzulesen. So möchte man zum Beispiel eine geplante Augabe in Windows mit PowerShell anlegen und den kompletten Befehl mit allen Argumenten samt Dateipfaden darin speichern. Doch wie macht man das?

Wie es nicht geht

Offensichtlich kann man es nicht so schreiben:

$action = "PowerShell.exe -File "D:\My Scripts\Download-Files.ps1""

Output:
Unexpected token 'D:\My' in expression or statement.

Was ist passiert? Das erste Paar von Anführungszeichen kennzeichnet PowerShell.exe -File als String, und die Zeichen danach werden erfolglos als Befehl interpretiert.

Die folgende Variante produziert zwar keinen Fehler, ist aber trotzdem falsch, weil die Anführungszeichen um den Pfad in der Ausgabe fehlen:

$file_path = "D:\My Scripts\Download-Files.ps1"
$action = "PowerShell.exe -File $file_path"
$action

Output:
PowerShell.exe -File D:\My Scripts\Download-Files.ps1

So ausgeführt würde der Befehl fehlschlagen.

Die zweitbeste Lösung

Erfolg verspricht auf den ersten Blick, den Pfad in doppelten Anführungszeichen zu belassen, aber dafür den String in einfache Anführungszeichen zu fassen:

$action = 'PowerShell.exe -File "D:\My Scripts\Download-Files.ps1"'
$action

Output:
PowerShell.exe -File "D:\My Scripts\Download-Files.ps1"

Es funktioniert auch umgekehrt:

$action = "PowerShell.exe -File 'D:\My Scripts\Download-Files.ps1'"
$action

Output:
PowerShell.exe -File 'D:\My Scripts\Download-Files.ps1'

Man macht sich dabei zunutze, dass Zeichen zwischen gleichartigen Anführungszeichen als Strings interpretiert werden.

Was wäre, wenn der Befehl Variablen benötigte?

$folder = "folder_a"
$timeout = 3600
$action_1 = 'PowerShell.exe -File "D:\My Scripts\$folder\Download-Files.ps1" -Timeout $timeout'
$action_1
$action_2 = "PowerShell.exe -File 'D:\My Scripts\$folder\Download-Files.ps1' -Timeout $timeout"
$action_2

Output:
PowerShell.exe -File "D:\My Scripts\$folder\Download-Files.ps1" -Timeout $timeout
PowerShell.exe -File 'D:\My Scripts\folder_a\Download-Files.ps1' -Timeout 3600

Bei $action_1 wurden wegen der einfachen Anführungszeichen keine Variablen aufgelöst. Wenn der String wie bei $action_2 von doppelten Anführungszeichen eingerahmt wird, löst PowerShell die Variablen jedoch auf – ist das also unsere Lösung?

Nun, wahrscheinlich in den meisten Fällen. In unserem Beispiel ist der Befehl hingegen für eine Aktion einer geplanten Aufgabe bestimmt – und dort wird CMD-Syntax erwartet. Das bedeutet: Einfache Anführungszeichen sind nicht erlaubt. Der Dateipfad im Skript muss von doppelten Anführungszeichen umrahmt sein, aber das geht ja nicht, wenn schon der String doppelte Anführungszeichen nutzt …

Jetzt haben wir schon so viel Zeit investiert und immer noch keine Lösung!

Sicher mit Maske auch in PowerShell

Glücklicherweise wird alles ganz einfach, wenn man weiß, was Maskierungszeichen oder escape characters sind. Kurz gesagt erfüllen die Anführungszeichen eine bestimmte Funktion für die Programmiersprache, aber wenn man ihnen das Maskierungszeichen voranstellt, verlieren sie diese Funktion und werden stattdessen als Text interpretiert. In PowerShell ist das Maskierungszeichen das Gravis-Akzentzeichen ` und führt zum gewünschten Ergebnis, wenn man die Anführungszeichen des Dateipfads damit schmückt:

$folder = "folder_a"
$timeout = 3600
$action = "PowerShell.exe -File `"D:\My Scripts\$folder\Download-Files.ps1`" -Timeout $timeout"
$action

Output:
PowerShell.exe -File "D:\My Scripts\folder_a\Download-Files.ps1" -Timeout 3600

Die doppelten Anführungszeichen bleiben erhalten, und die Variablen werden korrekt eingesetzt. So kann der Befehl zum Beispiel in der CMD oder in einer geplanten Aufgabe eingesetzt werden.

Von Pascal Korz

IT Systems Engineer in und aus dem schönen Köln

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert