Sonderzeichen (Quote, Dollar) in PowerShell maskieren (escape)


    Tags:

    Sonderzeichen in PowerShellPowerShell kennt wie prak­tisch jede Pro­grammier­sprache reser­vierte Zeichen, die bei­spiels­weise Vari­ablen mar­kieren oder als Opera­toren dienen. Möchte man sie in Zeichen­ketten ver­wenden, dann muss man sie je nach Kontext maskieren. Kompli­ziert wird es, wenn zu­sätzlich RegEx oder AD-Ab­fragen ins Spiel kommen.

    Ein typischer Fall, bei dem PowerShell einen ungültigen bzw. unvollständigen String reklamiert, ergibt sich, wenn man Anführungs­zeichen als Bestandteil der Zeichen­kette benötigt, also diese mit den anderen Zeichen ausgegeben werden sollen:

    "Das ist doppeltes " Anführungszeichen"

    Hier schickt die Eingabetaste den Befehl nicht ab, vielmehr erwartet PowerShell in der nächsten Zeile ein abschließendes Anführungs­zeichen. Und danach läuft man in eine Fehlermeldung, weil sich das letzte Wort außerhalb des Strings befindet.

    Die Lösung ist in diesem Beispiel recht simpel. Man kann dafür die Zeichenkette in einfache Anführungszeichen setzen:

    'Das ist doppeltes " Anführungszeichen'

    Keine Expansion von Variablen

    Dieses Vorgehen hat aber den Nachteil, dass Variablen, die im String enthalten sind, von PowerShell nicht expandiert werden. Vielmehr gibt sie im folgenden Beispiel einfach den Namen der Variablen aus:

    'Das ist ein $test für " Anführungszeichen'

    In dieser Situation kann man sich behelfen, indem man weiterhin doppelte Anführungs­zeichen verwendet und das im String enthaltene " durch das Escape-Zeichen von PowerShell maskiert. Dabei handelt es sich um den umgekehrten Apostroph `:

    "Das ist ein $test für `" Anführungszeichen"

    Mit Hilfe dieses Backticks ergibt sich eine weitere Variante für Zeichenketten mit Variablen, wenn diese nicht expandiert werden sollen:

    "Das ist ein `$test für `" Anführungszeichen"

    Expansion von Variablen in PowerShell-Strings abhängig von den Anführungszeichen

    Hier würde der Name und nicht der Inhalt der Variablen ausgegeben, weil das maskierte Dollarzeichen seine Bedeutung als Marker für Variablen verliert. Damit erzielt man den gleichen Effekt, wie wenn man die Zeichenkette in einfachen Anführungs­zeichen setzt.

    Dollar als Währungssymbol nutzen

    Möchte man umgekehrt ein Dollarzeichen als Währungs­symbol verwenden, dann könnte PowerShell dieses als erstes Zeichen einer Variablen missverstehen. Das passiert aber nur, wenn dem $ unmittelbar weitere Zeichen folgen, wie etwa $50. Steht es alleine oder am Ende eines Wortes, dann muss man es nicht maskieren:

    "Er hat sich damit 50 US$ verdient"

    Das Escape Character kann man überall dort einsetzen, wo man ein Metazeichen buchstäblich nehmen will. So dient etwa das Leerzeichen normal als Trenner zwischen Parametern, aber wenn es in einem Dateinamen vorkommt, dann soll es diese Funktion nicht haben:

    Get-Content -Path .\Einladung` zur` Party.doc

    Anstatt die Datei Einladung zur Party.doc in Anführungs­zeichen zu setzen, kann man die Leerzeichen durch den Backtick maskieren.

    Here Documents als Alternative zum Escape-Zeichen

    Hat man es mit einem String wie etwa einem HTML-Fragment zu tun, der viele Anführungs- oder Dollarzeichen sowie Zeilenvorschübe enthält, dann ist es zu umständlich, jedes einzelne mit dem Escape-Zeichen zu versehen. Für diesen Fall bietet PowerShell wie einige andere Script-Sprachen so genannte Here Documents.

    Dieses wird von @" und "@ umschlossen, wobei diese Zeichen­kombination jeweils auf einer eigenen Zeile stehen muss:

    Alles innerhalb eines Here Document wird wörtlich genommen, Variablen expandiert PowerShell jedoch. Möchte man das vermeiden, dann muss man das Dollarzeichen mit einem umgekehrten Apostroph maskieren.

    Here Documents als Alternative zur mehrfachen Verwendung des Escape-Zeichens.

    Metazeichen in RegEx

    Komplizierter wird es, wenn man in PowerShell reguläre Ausdrücke verwendet, weil diese eine eigene Syntax zur Maskierung von Zeichen erwarten. So kann es passieren, dass man gleich zwei Escape-Zeichen einsetzen muss, um ein Zeichen für PowerShell und die RegEx-Engine zu maskieren:

    "Er hat `$50 verloren" -replace "\`$5", "€4"

    In diesem Beispiel dient der Backslash dazu, das $-Zeichen vor der RegEx-Auswertung zu verstecken, weil es dort eine besondere Bedeutung für das Ende eines Strings hat. Zusätzlich sorgt der Backtick dafür, dass PowerShell nicht $5 als Variable interpretiert. Alternativ könnte man hier wieder einfache Anführungszeichen nehmen und so ein Escape-Zeichen einsparen:

    "Er hat `$50 verloren" -replace '\$5', "€4"

    Zeichen im Distinguished Name maskieren

    Ähnliche Situationen können überall dort auftreten, wo man in PowerShell einen Ausdruck an einen anderen Interpreter übergibt und dieser andere Mechanismen nutzt, um Zeichen zu maskieren. Das gilt etwa auch für Abfragen im Active Directory:

    Get-ADUser -Identity "CN=WVong,OU=F\+E,DC=windowspro,DC=local"

    In diesem Beispiel enthält der Name der OU ein +-Zeichen, das man durch einen Backslash entschärft. Ein Dollarsymbol im Namen der OU müsste man dagegen vor PowerShell schützen, entweder durch einen Backtick oder die Verwendung einfacher Anführungs­zeichen.

    Täglich Know-how für IT-Pros mit unserem Newsletter

    Wir ver­wenden Ihre Mail-Adresse nur für den Ver­sand der News­letter.
    Es erfolgt keine per­sonen­be­zogene Auswertung.

    Bild von Wolfgang Sommergut

    Wolfgang Sommergut hat lang­jährige Erfahrung als Fach­autor, Berater und Kon­ferenz­sprecher zu ver­schie­denen Themen der IT. Da­ne­ben war er als System­ad­mi­ni­stra­tor und Con­sultant tätig.
    // Kontakt: E-Mail, XING, LinkedIn //

    Ähnliche Beiträge

    Weitere Links