about_Parsing
Kurze Beschreibung
Beschreibt, wie PowerShell Befehle analysiert.
Lange Beschreibung
Wenn Sie an der Eingabeaufforderung einen Befehl eingeben, unterbricht PowerShell den Befehlstext in eine Reihe von Segmenten, die als Token bezeichnet werden, und bestimmt dann, wie jedes Token interpretiert wird.
Wenn Sie beispielsweise Folgendes eingeben:
Write-Host book
PowerShell unterteilt den Befehl in zwei Token Write-Host
und book
interpretiert jedes Token unabhängig von einem von zwei hauptanalysemodi: Ausdrucksmodus und Argumentmodus.
Hinweis
Da PowerShell Befehlseingaben analysiert, versucht sie, die Befehlsnamen in Cmdlets oder systemeigene ausführbare Dateien aufzulösen. Wenn ein Befehlsname keine genaue Übereinstimmung aufweist, stellt Get-
PowerShell dem Befehl als Standardverb vor. PowerShell analysiert Service
z. B. als Get-Service
. Es wird nicht empfohlen, dieses Feature aus den folgenden Gründen zu verwenden:
- Es ist ineffizient. Dies führt dazu, dass PowerShell mehrmals durchsucht wird.
- Externe Programme mit demselben Namen werden zuerst aufgelöst, sodass Sie das beabsichtigte Cmdlet möglicherweise nicht ausführen.
Get-Help
undGet-Command
nicht verblose Namen erkennen.- Der Befehlsname kann ein reserviertes Wort oder ein Sprachstichwort sein.
Process
ist beides und kann nicht aufgelöstGet-Process
werden.
Ausdrucksmodus
Der Ausdrucksmodus dient zum Kombinieren von Ausdrücken, die für die Wertmanipulation in einer Skriptsprache erforderlich sind. Ausdrücke sind Darstellungen von Werten in der PowerShell-Syntax und können einfach oder zusammengesetzt sein, z. B.:
Literale Ausdrücke sind direkte Darstellungen ihrer Werte:
'hello'
32
Variable Ausdrücke tragen den Wert der Variablen, auf die sie verweisen:
$x
$script:path
Operatoren kombinieren andere Ausdrücke für die Auswertung:
-12
-not $Quiet
3 + 7
$input.Length -gt 1
- Zeichenfolgenliterale müssen in Anführungszeichen enthalten sein.
- Zahlen werden als numerische Werte und nicht als Eine Reihe von Zeichen behandelt (es sei denn, escaped).
- Operatoren, einschließlich unärer Operatoren wie
-
und-not
binäre Operatoren,+
-gt
werden als Operatoren interpretiert und ihre jeweiligen Vorgänge auf ihre Argumente angewendet (Operanden). - Attribut- und Konvertierungsausdrücke werden als Ausdrücke analysiert und auf untergeordnete Ausdrücke angewendet. Beispiel:
[int] '7'
- Variable Verweise werden auf ihre Werte ausgewertet, aber splatting ist verboten und verursacht einen Parserfehler.
- Alles andere wird als befehl behandelt, der aufgerufen werden soll.
Argumentmodus
Beim Analysieren sucht PowerShell zunächst, eingaben als Ausdruck zu interpretieren. Wenn jedoch ein Befehlsaufruf auftritt, wird die Analyse im Argumentmodus fortgesetzt. Wenn Sie Argumente haben, die Leerzeichen enthalten, z. B. Pfade, müssen Sie diese Argumentwerte in Anführungszeichen setzen.
Der Argumentmodus wurde für die Analyse von Argumenten und Parametern für Befehle in einer Shellumgebung entwickelt. Alle Eingaben werden als erweiterbare Zeichenfolge behandelt, es sei denn, sie verwendet eine der folgenden Syntaxen:
Dollarzeichen (
$
) gefolgt von einem Variablennamen beginnt einen Variablenverweis, andernfalls wird es als Teil der erweiterbaren Zeichenfolge interpretiert. Der Variableverweis kann den Memberzugriff oder die Indizierung umfassen.- Zusätzliche Zeichen nach einfachen Variablenbezügen, z
$HOME
. B. , werden als Teil desselben Arguments betrachtet. Schließen Sie den Variablennamen in geschweifte Klammern ({}
) ein, um ihn von nachfolgenden Zeichen zu trennen. Beispiel:${HOME}
. - Wenn der Variablenverweis den Memberzugriff enthält, wird der erste zusätzliche Zeichen als Beginn eines neuen Arguments betrachtet. Führt z. B
$HOME.Length-more
. zu zwei Argumenten: dem Wert und dem$HOME.Length
Zeichenfolgenliteral-more
.
- Zusätzliche Zeichen nach einfachen Variablenbezügen, z
Anführungszeichen (
'
und"
) beginnen ZeichenfolgenGeschweifte Klammern (
{}
) beginnen mit neuen SkriptblöckenKommas (
,
) führen Listen ein, die als Arrays übergeben werden, es sei denn, der aufgerufene Befehl ist eine systemeigene Anwendung, in diesem Fall werden sie als Teil der erweiterbaren Zeichenfolge interpretiert. Anfängliche, aufeinander folgende oder nachfolgende Kommas werden nicht unterstützt.Klammern (
()
) beginnen mit einem neuen AusdruckDer Subexpression-Operator (
$()
) beginnt einen eingebetteten Ausdruck.Initial at sign (
@
) begins expression syntaxes such as splatting (@args
), arrays (@(1,2,3)
) and hash table literals (@{a=1;b=2}
).()
,$()
und@()
am Anfang eines Tokens erstellen Sie einen neuen Analysekontext, der Ausdrücke oder geschachtelte Befehle enthalten kann.- Gefolgt von zusätzlichen Zeichen wird das erste zusätzliche Zeichen als Beginn eines neuen, separaten Arguments betrachtet.
- Wenn ein nicht angestelltes Literal
$()
wie eine erweiterbare Zeichenfolge vorangestellt wird,()
beginnt ein neues Argument, das ein Ausdruck ist, und@()
wird als Literal@
verwendet, indem()
ein neues Argument gestartet wird, das ein Ausdruck ist.
Alles andere wird als erweiterbare Zeichenfolge behandelt, mit Ausnahme von Metacharactern, die noch entweichen müssen. Siehe Behandeln von Sonderzeichen.
- Die Argumentmodus-Metacharacter (Zeichen mit spezieller syntaktischer Bedeutung) sind:
<space> ' " ` , ; ( ) { } | & < > @ #
. Von diesen sind< > @ #
nur zu Beginn eines Tokens besonders.
- Die Argumentmodus-Metacharacter (Zeichen mit spezieller syntaktischer Bedeutung) sind:
Das Stoppanalysetoken (
--%
) ändert die Interpretation aller verbleibenden Argumente. Weitere Informationen finden Sie im Abschnitt "Stop-Parsing Token" weiter unten.
Beispiele
Die folgende Tabelle enthält mehrere Beispiele für Token, die im Ausdrucksmodus und im Argumentmodus verarbeitet werden, und die Auswertung dieser Token. Für diese Beispiele lautet 4
der Wert der Variablen $a
.
Beispiel | Mode | Ergebnis |
---|---|---|
2 |
Ausdruck | 2 (ganze Zahl) |
`2 |
Ausdruck | "2" (Befehl) |
Write-Output 2 |
Ausdruck | 2 (ganze Zahl) |
2+2 |
Ausdruck | 4 (ganze Zahl) |
Write-Output 2+2 |
Argument | "2+2" (Zeichenfolge) |
Write-Output(2+2) |
Ausdruck | 4 (ganze Zahl) |
$a |
Ausdruck | 4 (ganze Zahl) |
Write-Output $a |
Ausdruck | 4 (ganze Zahl) |
$a+2 |
Ausdruck | 6 (ganze Zahl) |
Write-Output $a+2 |
Argument | "4+2" (Zeichenfolge) |
$- |
Argument | "$-" (Befehl) |
Write-Output $- |
Argument | "$-" (Zeichenfolge) |
a$a |
Ausdruck | "a$a" (Befehl) |
Write-Output a$a |
Argument | "a4" (Zeichenfolge) |
a'$a' |
Ausdruck | "a$a" (Befehl) |
Write-Output a'$a' |
Argument | "a$a" (Zeichenfolge) |
a"$a" |
Ausdruck | "a$a" (Befehl) |
Write-Output a"$a" |
Argument | "a4" (Zeichenfolge) |
a$(2) |
Ausdruck | "a$(2)" (Befehl) |
Write-Output a$(2) |
Argument | "a2" (Zeichenfolge) |
Jedes Token kann als eine Art von Objekttyp interpretiert werden, z . B. boolean oder String. PowerShell versucht, den Objekttyp aus dem Ausdruck zu ermitteln. Der Objekttyp hängt vom Typ des Parameters ab, den ein Befehl erwartet, und ob PowerShell weiß, wie das Argument in den richtigen Typ konvertiert werden kann. Die folgende Tabelle enthält mehrere Beispiele für die Typen, die von den Ausdrücken zurückgegebenen Werten zugewiesen sind.
Beispiel | Mode | Ergebnis |
---|---|---|
Write-Output !1 |
Argument | "!1" (Zeichenfolge) |
Write-Output (!1) |
expression | False (boolean) |
Write-Output (2) |
expression | 2 (ganze Zahl) |
Set-Variable AB A,B |
Argument | 'A','B' (Array) |
CMD /CECHO A,B |
Argument | 'A;B' (Zeichenfolge) |
CMD /CECHO $AB |
expression | 'A B' (Array) |
CMD /CECHO :$AB |
Argument | ':A B' (Zeichenfolge) |
Verarbeiten von Sonderzeichen
Das Backtick-Zeichen (`
) kann verwendet werden, um ein beliebiges Sonderzeichen in einem Ausdruck zu escapen. Dies ist am nützlichsten für das Escapen der Argumentmodus-Metacharacter, die Sie als Literalzeichen und nicht als Metacharacter verwenden möchten. Verwenden Sie beispielsweise das Dollarzeichen ($
) als Literal in einer erweiterbaren Zeichenfolge:
"The value of `$ErrorActionPreference is '$ErrorActionPreference'."
The value of $ErrorActionPreference is 'Continue'.
Zeilenfortsetzung
Das Backtick-Zeichen kann auch am Ende einer Zeile verwendet werden, damit Sie die Eingabe in der nächsten Zeile fortsetzen können. Dies verbessert die Lesbarkeit eines Befehls, der mehrere Parameter mit langen Namen und Argumentwerten verwendet. Zum Beispiel:
New-AzVm `
-ResourceGroupName "myResourceGroupVM" `
-Name "myVM" `
-Location "EastUS" `
-VirtualNetworkName "myVnet" `
-SubnetName "mySubnet" `
-SecurityGroupName "myNetworkSecurityGroup" `
-PublicIpAddressName "myPublicIpAddress" `
-Credential $cred
Sie sollten jedoch vermeiden, die Zeilenfortsetzung zu verwenden.
- Die Backtick-Zeichen können schwer zu erkennen und leicht zu vergessen sein.
- Ein zusätzliches Leerzeichen, nachdem der Backtick die Zeilenfortsetzung unterbrochen hat. Da der Platz schwer zu erkennen ist, kann es schwierig sein, den Fehler zu finden.
PowerShell bietet mehrere Möglichkeiten, Umbruchlinien an natürlichen Punkten in der Syntax zu trennen.
- Nach Pipezeichen (
|
) - Nach binären Operatoren (
+
,-
,-eq
usw.) - Nach Kommas (
,
) in einem Array - Nach dem Öffnen von Zeichen wie
[
, ,{
(
Verwenden Sie für einen großen Parametersatz stattdessen splatting. Zum Beispiel:
$parameters = @{
ResourceGroupName = "myResourceGroupVM"
Name = "myVM"
Location = "EastUS"
VirtualNetworkName = "myVnet"
SubnetName = "mySubnet"
SecurityGroupName = "myNetworkSecurityGroup"
PublicIpAddressName = "myPublicIpAddress"
Credential = $cred
}
New-AzVm @parameters
Übergeben von Argumenten an native Befehle
Wenn Systemeigene Befehle aus PowerShell ausgeführt werden, werden die Argumente zuerst von PowerShell analysiert. Die analysierten Argumente werden dann mit einer einzelnen Zeichenfolge verknüpft, wobei jeder Parameter durch ein Leerzeichen getrennt ist.
Beispielsweise ruft der folgende Befehl das icacls.exe
Programm auf.
icacls X:\VMS /grant Dom\HVAdmin:(CI)(OI)F
Um diesen Befehl in PowerShell 2.0 auszuführen, müssen Sie Escapezeichen verwenden, um zu verhindern, dass PowerShell die Klammern falsch interpretiert.
icacls X:\VMS /grant Dom\HVAdmin:`(CI`)`(OI`)F
Das Stoppanalysetoken
Ab PowerShell 3.0 können Sie das Stoppanalysetoken (--%
) verwenden, um zu verhindern, dass PowerShell Eingaben als PowerShell-Befehle oder -Ausdrücke interpretiert.
Hinweis
Das Stoppanalysetoken ist nur für systemeigene Befehle auf Windows-Plattformen vorgesehen.
Platzieren Sie beim Aufrufen eines systemeigenen Befehls das Stoppanalysetoken vor den Programmargumenten. Diese Technik ist viel einfacher als die Verwendung von Escapezeichen, um Fehlinterpretation zu verhindern.
Wenn ein Stoppanalysetoken auftritt, behandelt PowerShell die verbleibenden Zeichen in der Zeile als Literal. Die einzige Interpretation, die sie ausführt, besteht darin, Werte für Umgebungsvariablen zu ersetzen, die die standardmäßige Windows-Schreibweise verwenden, z %USERPROFILE%
. B. .
icacls X:\VMS --% /grant Dom\HVAdmin:(CI)(OI)F
PowerShell sendet die folgende Befehlszeichenfolge an das icacls.exe
Programm:
X:\VMS /grant Dom\HVAdmin:(CI)(OI)F
Das Stop-Parsing-Token ist nur wirksam, bis das nächste Neueline- oder Pipelinezeichen vorhanden ist. Sie können das Zeilenfortsetzungszeichen (`
) nicht verwenden, um den Effekt zu erweitern oder ein Befehlstrennzeichen (;
) zum Beenden des Effekts zu verwenden.
%variable%
Außer Umgebungsvariablen-Verweisen können Sie keine anderen dynamischen Elemente in den Befehl einbetten. Das Escapen eines %
Zeichens als %%
, wie Sie innerhalb von Batchdateien vorgehen können, wird nicht unterstützt. %<name>%
Token werden unveränderlich erweitert. Wenn <name>
nicht auf eine definierte Umgebungsvariable verwiesen wird, wird das Token wie folgt übergeben.
Sie können die Streamumleitung (z >file.txt
. B. ) nicht verwenden, da sie als Argumente an den Zielbefehl übergeben werden.
Im folgenden Beispiel führt der erste Schritt einen Befehl aus, ohne das Stop-Parsing-Token zu verwenden. PowerShell wertet die Zeichenfolge aus und übergibt den Wert (ohne Anführungszeichen) an cmd.exe
, was zu einem Fehler führt.
PS> cmd /c echo "a|b"
'b' is not recognized as an internal or external command,
operable program or batch file.
PS> cmd /c --% echo "a|b"
"a|b"
Hinweis
Das Stoppanalysetoken ist bei Verwendung von PowerShell-Cmdlets nicht erforderlich. Es kann jedoch hilfreich sein, Argumente an eine PowerShell-Funktion zu übergeben, die zum Aufrufen eines systemeigenen Befehls mit diesen Argumenten konzipiert ist.
Übergeben von Argumenten, die Anführungszeichen enthalten
Einige systemeigene Befehle erwarten Argumente, die Anführungszeichen enthalten. Normalerweise entfernt die Befehlszeilenanalyse von PowerShell das von Ihnen bereitgestellte Anführungszeichen. Die analysierten Argumente werden dann mit einer einzelnen Zeichenfolge verknüpft, wobei jeder Parameter durch ein Leerzeichen getrennt ist. Diese Zeichenfolge wird dann der Arguments-Eigenschaft eines ProcessStartInfo
Objekts zugewiesen. Anführungszeichen innerhalb der Zeichenfolge müssen mit zusätzlichen Anführungszeichen oder umgekehrten Schrägstrichen (\
) escapet werden.
Hinweis
Der umgekehrte Schrägstrich (\
) wird von PowerShell nicht als Escapezeichen erkannt. Es ist das Escapezeichen, das von der zugrunde liegenden API für ProcessStartInfo.Arguments
.
Weitere Informationen zu den Escapeanforderungen finden Sie in der Dokumentation zu ProcessStartInfo.Arguments.
Hinweis
In den folgenden Beispielen wird das TestExe.exe
-Tool verwendet. Sie können TestExe
aus dem Quellcode erstellen. Weitere Informationen finden Sie unter TestExe im PowerShell-Quellrepository.
Ziel dieser Beispiele ist es, den Verzeichnispfad "C:\Program Files (x86)\Microsoft\"
an einen systemeigenen Befehl zu übergeben, damit er den Pfad als anführungszeichenierte Zeichenfolge empfangen hat.
Der Echoargs-Parameter zeigt TestExe
die werte an, die als Argumente für die ausführbare Datei empfangen wurden. Sie können dieses Tool verwenden, um zu überprüfen, ob die Zeichen in Ihren Argumenten ordnungsgemäß escapet sind.
TestExe -echoargs """""${env:ProgramFiles(x86)}\Microsoft\\"""""
TestExe -echoargs """""C:\Program Files (x86)\Microsoft\\"""""
TestExe -echoargs --% ""\""C:\Program Files (x86)\Microsoft\\""
TestExe -echoargs --% """C:\Program Files (x86)\Microsoft\\""
TestExe -echoargs --% """%ProgramFiles(x86)%\Microsoft\\""
Die Ausgabe ist für alle Beispiele identisch:
Arg 0 is <"C:\Program Files (x86)\Microsoft\">
Übergeben von Argumenten an PowerShell-Befehle
Ab PowerShell 3.0 können Sie das End-of-Parameters-Token (--
) verwenden, um zu verhindern, dass PowerShell Eingaben als PowerShell-Parameter interpretiert. Dies ist eine Konvention, die in der POSIX Shell and Utilities-Spezifikation angegeben ist.
Das End-of-Parameters-Token
Das End-of-Parameters-Token (--
) gibt an, dass alle darauf folgenden Argumente in ihrer tatsächlichen Form übergeben werden müssen, als ob doppelte Anführungszeichen um sie herum platziert wurden. Sie --
können beispielsweise die Zeichenfolge -InputObject
ohne Anführungszeichen ausgeben oder als Parameter interpretiert haben:
Write-Output -- -InputObject
-InputObject
Im Gegensatz zum Stop-Parsing-Token (--%
) können alle Werte, die dem --
Token folgen, von PowerShell als Ausdrücke interpretiert werden.
Write-Output -- -InputObject $env:PROCESSOR_ARCHITECTURE
-InputObject
AMD64
Dieses Verhalten gilt nur für PowerShell-Befehle. Wenn Sie das --
Token beim Aufrufen eines externen Befehls verwenden, wird die --
Zeichenfolge als Argument an diesen Befehl übergeben.
TestExe -echoargs -a -b -- -c
Die Ausgabe zeigt, dass --
als Argument an TestExe
.
Arg 0 is <-a>
Arg 1 is <-b>
Arg 2 is <-->
Arg 3 is <-c>
Tilde (~)
Das Tildezeichen (~
) hat in PowerShell eine besondere Bedeutung. Wenn sie mit PowerShell-Befehlen am Anfang eines Pfads verwendet wird, wird das Tildezeichen in das Startverzeichnis des Benutzers erweitert. Wenn das Tildezeichen an einer anderen Stelle in einem Pfad verwendet wird, wird es als Literalzeichen behandelt.
PS D:\temp> $PWD
Path
----
D:\temp
PS D:\temp> Set-Location ~
PS C:\Users\user2> $PWD
Path
----
C:\Users\user2
In diesem Beispiel erwartet der Name-Parameter eine New-Item
Zeichenfolge. Das Tildezeichen wird als Literalzeichen behandelt. Um in das neu erstellte Verzeichnis zu wechseln, müssen Sie den Pfad mit dem Tildezeichen qualifizieren.
PS D:\temp> Set-Location ~
PS C:\Users\user2> New-Item -Type Directory -Name ~
Directory: C:\Users\user2
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 5/6/2024 2:08 PM ~
PS C:\Users\user2> Set-Location ~
PS C:\Users\user2> Set-Location .\~
PS C:\Users\user2\~> $PWD
Path
----
C:\Users\user2\~
Wenn Sie das Tildezeichen mit systemeigenen Befehlen verwenden, übergibt PowerShell die Tilde als Literalzeichen. Die Verwendung der Tilde in einem Pfad verursacht Fehler für systemeigene Befehle unter Windows, die das Tildezeichen nicht unterstützen.
PS D:\temp> $PWD
Path
----
D:\temp
PS D:\temp> Get-Item ~\repocache.clixml
Directory: C:\Users\user2
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 4/29/2024 3:42 PM 88177 repocache.clixml
PS D:\temp> more.com ~\repocache.clixml
Cannot access file D:\temp\~\repocache.clixml