about_Parsing
Korte beschrijving
Beschrijft hoe PowerShell opdrachten parseert.
Lange beschrijving
Wanneer u een opdracht invoert bij de opdrachtprompt, breekt PowerShell de opdrachttekst op in een reeks segmenten met de naam tokens en bepaalt vervolgens hoe elk token moet worden geïnterpreteerd.
Als u bijvoorbeeld typt:
Write-Host book
PowerShell breekt de opdracht in twee tokens Write-Host en bookinterpreteert elk token onafhankelijk met behulp van een van de twee belangrijkste parseringsmodi: expressiemodus en argumentmodus.
Notitie
Omdat PowerShell opdrachtinvoer parseert, wordt geprobeerd de opdrachtnamen om te lossen naar cmdlets of systeemeigen uitvoerbare bestanden. Als een opdrachtnaam geen exacte overeenkomst heeft, krijgt PowerShell de Get- opdracht als standaardwerkwoord. PowerShell parseert Service bijvoorbeeld als Get-Service. Het is niet raadzaam om deze functie te gebruiken om de volgende redenen:
- Het is inefficiënt. Dit zorgt ervoor dat PowerShell meerdere keren kan zoeken.
- Externe programma's met dezelfde naam worden eerst omgezet, dus u kunt de beoogde cmdlet mogelijk niet uitvoeren.
Get-HelpenGet-Commandherkent geen werkwoordloze namen.- De opdrachtnaam kan een gereserveerd woord of een taalwoord zijn.
Processis beide, en zal niet oplossen totGet-Process.
Expressiemodus
De expressiemodus is bedoeld voor het combineren van expressies, vereist voor het bewerken van waarden in een scripttaal. Expressies zijn weergaven van waarden in de PowerShell-syntaxis en kunnen eenvoudig of samengesteld zijn, bijvoorbeeld:
Letterlijke expressies zijn directe weergaven van hun waarden:
'hello'
32
Variabeleexpressies dragen de waarde van de variabele waarnaar ze verwijzen:
$x
$script:path
Operators combineren andere expressies voor evaluatie:
-12
-not $Quiet
3 + 7
$input.Length -gt 1
- Letterlijke tekenreeksen moeten tussen aanhalingstekens staan.
- Getallen worden behandeld als numerieke waarden in plaats van als een reeks tekens (tenzij er een escape-teken is).
- Operators, waaronder unaire operators zoals
-en-notbinaire operatoren,+-gtworden geïnterpreteerd als operators en passen hun respectieve bewerkingen toe op hun argumenten (operands). - Kenmerk- en conversieexpressies worden geparseerd als expressies en toegepast op onderliggende expressies, bijvoorbeeld
[int] '7'. - Variabeleverwijzingen worden geëvalueerd op hun waarden, maar splatting (bijvoorbeeld het plakken van vooraf ingevulde parametersets) is verboden en veroorzaakt een parserfout.
- Iets anders wordt behandeld als een opdracht die moet worden aangeroepen.
Argumentmodus
Bij het parseren ziet PowerShell er eerst naar uit om invoer als een expressie te interpreteren. Maar wanneer er een opdrachtaanroep wordt aangetroffen, wordt het parseren voortgezet in de argumentmodus. Als u argumenten hebt die spaties bevatten, zoals paden, moet u deze argumentwaarden tussen aanhalingstekens plaatsen.
De argumentmodus is ontworpen voor het parseren van argumenten en parameters voor opdrachten in een shell-omgeving. Alle invoer wordt behandeld als een uitbreidbare tekenreeks, tenzij er een van de volgende syntaxis wordt gebruikt:
Dollarteken (
$) gevolgd door een variabelenaam begint een variabelereferentie, anders wordt het geïnterpreteerd als onderdeel van de uitvouwbare tekenreeks. De variabeleverwijzing kan lidtoegang of indexering bevatten.- Aanvullende tekens na eenvoudige variabeleverwijzingen, zoals
$HOME, worden beschouwd als onderdeel van hetzelfde argument. Plaats de naam van de variabele tussen accolades ({}) om deze te scheiden van de volgende tekens. Bijvoorbeeld${HOME}. - Wanneer de variabelereferentie lidtoegang bevat, wordt de eerste van eventuele extra tekens beschouwd als het begin van een nieuw argument. Resulteert bijvoorbeeld
$HOME.Length-morein twee argumenten: de waarde van$HOME.Lengthen de letterlijke-moretekenreeks.
- Aanvullende tekens na eenvoudige variabeleverwijzingen, zoals
Aanhalingstekens (
'en") beginnen tekenreeksenAccolades (
{}) beginnen met een nieuw scriptblokKomma's (
,) introduceren lijsten die als matrices worden doorgegeven, behalve wanneer de opdracht die moet worden aangeroepen een systeemeigen toepassing is, in welk geval ze worden geïnterpreteerd als onderdeel van de uitbreidbare tekenreeks. Initiële, opeenvolgende of volgkomma's worden niet ondersteund.Haakjes (
()) beginnen met een nieuwe expressieDe operator Voor subexpressie (
$()) wordt een ingesloten expressie gestartInitiële bijteken (
@) begint de expressiesyntaxis, zoals splatting (@args), matrices (@(1,2,3)) en letterlijke hashtabellen (@{a=1;b=2}).()en$()@()aan het begin van een token maakt u een nieuwe parseringscontext die expressies of geneste opdrachten kan bevatten.- Wanneer er extra tekens worden gevolgd, wordt het eerste extra teken beschouwd als het begin van een nieuw, afzonderlijk argument.
- Wanneer een letterlijke aanhalingsteken voorafgaat door een letterlijke aanhalingsteken
$(), werkt dit als een uitvouwbare tekenreeks,()begint u een nieuw argument dat een expressie is en@()wordt deze als letterlijk beschouwd@.()
Alles anders wordt behandeld als een uitbreidbare tekenreeks, behalve metacharacters die nog steeds moeten ontsnappen.
- De metacharacters voor de argumentmodus (tekens met speciale syntactische betekenis) zijn:
<space> ' " ` , ; ( ) { } | & < > @ #. Van deze,< > @ #zijn alleen speciaal aan het begin van een token.
- De metacharacters voor de argumentmodus (tekens met speciale syntactische betekenis) zijn:
Het token voor stoppen parseren (
--%) wijzigt de interpretatie van alle resterende argumenten. Zie de sectie stop-parsing-token hieronder voor meer informatie.
Voorbeelden
De volgende tabel bevat verschillende voorbeelden van tokens die worden verwerkt in de expressiemodus en argumentmodus en de evaluatie van deze tokens. Voor deze voorbeelden is 4de waarde van de variabele $a .
| Voorbeeld | Modus | Resultaat |
|---|---|---|
2 |
Expression | 2 (geheel getal) |
`2 |
Expression | "2" (opdracht) |
Write-Output 2 |
Expression | 2 (geheel getal) |
2+2 |
Expression | 4 (geheel getal) |
Write-Output 2+2 |
Argument | "2+2" (tekenreeks) |
Write-Output(2+2) |
Expression | 4 (geheel getal) |
$a |
Expression | 4 (geheel getal) |
Write-Output $a |
Expression | 4 (geheel getal) |
$a+2 |
Expression | 6 (geheel getal) |
Write-Output $a+2 |
Argument | "4+2" (tekenreeks) |
$- |
Argument | "$-" (opdracht) |
Write-Output $- |
Argument | "$-" (tekenreeks) |
a$a |
Expression | "a$a" (opdracht) |
Write-Output a$a |
Argument | "a4" (tekenreeks) |
a'$a' |
Expression | "a$a" (opdracht) |
Write-Output a'$a' |
Argument | "a$a" (tekenreeks) |
a"$a" |
Expression | "a$a" (opdracht) |
Write-Output a"$a" |
Argument | "a4" (tekenreeks) |
a$(2) |
Expression | "a$(2)" (opdracht) |
Write-Output a$(2) |
Argument | "a2" (tekenreeks) |
Elk token kan worden geïnterpreteerd als een soort objecttype, zoals Booleaanse waarde of tekenreeks. PowerShell probeert het objecttype van de expressie te bepalen. Het objecttype is afhankelijk van het type parameter dat een opdracht verwacht en of PowerShell weet hoe het argument moet worden geconverteerd naar het juiste type. In de volgende tabel ziet u verschillende voorbeelden van de typen die zijn toegewezen aan waarden die door de expressies worden geretourneerd.
| Voorbeeld | Modus | Resultaat |
|---|---|---|
Write-Output !1 |
Argument voor | "!1" (tekenreeks) |
Write-Output (!1) |
expressie | Onwaar (Booleaanse waarde) |
Write-Output (2) |
expressie | 2 (geheel getal) |
Set-Variable AB A,B |
Argument voor | 'A','B' (matrix) |
CMD /CECHO A,B |
Argument voor | 'A,B' (tekenreeks) |
CMD /CECHO $AB |
expressie | A B (matrix) |
CMD /CECHO :$AB |
Argument voor | ':A B' (tekenreeks) |
Argumenten doorgeven aan systeemeigen opdrachten
Wanneer u systeemeigen opdrachten uitvoert vanuit PowerShell, worden de argumenten eerst geparseerd door PowerShell. De geparseerde argumenten worden vervolgens samengevoegd tot één tekenreeks, waarbij elke parameter wordt gescheiden door een spatie.
Met de volgende opdracht wordt bijvoorbeeld het programma aanroepen icacls.exe .
icacls X:\VMS /grant Dom\HVAdmin:(CI)(OI)F
Als u deze opdracht wilt uitvoeren in PowerShell 2.0, moet u escapetekens gebruiken om te voorkomen dat PowerShell haakjes verkeerd interpreteert.
icacls X:\VMS /grant Dom\HVAdmin:`(CI`)`(OI`)F
Het stop-parsing-token
Vanaf PowerShell 3.0 kunt u het token stoppen () gebruiken om te voorkomen dat PowerShell invoer interpreteert als PowerShell-opdrachten--% of -expressies.
Notitie
Het stop-parsing-token is alleen bedoeld voor gebruik op Windows-platforms.
Wanneer u een systeemeigen opdracht aanroept, plaatst u het stopparseringstoken vóór de programmaargumenten. Deze techniek is veel eenvoudiger dan het gebruik van escape-tekens om onjuiste interpretatie te voorkomen.
Wanneer er een stop-parsing-token wordt weergegeven, behandelt PowerShell de resterende tekens in de regel als een letterlijke waarde. De enige interpretatie die wordt uitgevoerd, is het vervangen van waarden voor omgevingsvariabelen die gebruikmaken van standaard Windows-notatie, zoals %USERPROFILE%.
icacls X:\VMS --% /grant Dom\HVAdmin:(CI)(OI)F
PowerShell verzendt de volgende opdrachtreeks naar het icacls.exe programma:
X:\VMS /grant Dom\HVAdmin:(CI)(OI)F
Het token voor stoppen parseren is alleen van kracht tot het volgende nieuwe regel- of pijplijnteken. U kunt een vervolgteken (`) niet gebruiken om het effect ervan uit te breiden of een opdrachtscheidingsteken (;) gebruiken om het effect te beëindigen.
Behalve verwijzingen naar %variable% omgevingsvariabelen kunt u geen andere dynamische elementen insluiten in de opdracht. Het ontsnappen van een % teken als %%, de manier waarop u in batchbestanden kunt doen, wordt niet ondersteund. %<name>% tokens worden altijd uitgebreid. Als <name> dit niet verwijst naar een gedefinieerde omgevingsvariabele, wordt het token als zodanig doorgegeven.
U kunt stroomomleiding (zoals >file.txt) niet gebruiken omdat deze letterlijk worden doorgegeven als argumenten aan de doelopdracht.
Argumenten doorgeven die aanhalingstekens bevatten
Sommige systeemeigen opdrachten verwachten argumenten die aanhalingstekens bevatten. Normaal gesproken verwijdert de opdrachtregelparsering van PowerShell het aanhalingsteken dat u hebt opgegeven. De geparseerde argumenten worden vervolgens samengevoegd tot één tekenreeks, waarbij elke parameter wordt gescheiden door een spatie. Deze tekenreeks wordt vervolgens toegewezen aan de eigenschap Argumenten van een ProcessStartInfo object. Aanhalingstekens binnen de tekenreeks moeten worden ontsnapt met extra aanhalingstekens of backslashtekens (\).
Notitie
Het backslash-teken (\) wordt niet herkend als een escape-teken door PowerShell. Het is het escape-teken dat wordt gebruikt door de onderliggende API voor ProcessStartInfo.Arguments.
Zie de documentatie voor ProcessStartInfo.Arguments voor meer informatie over de escapevereisten.
In de volgende voorbeelden wordt het TestExe.exe hulpprogramma gebruikt. Dit hulpprogramma wordt gebruikt door de Pester-tests in de PowerShell-bronopslagplaats. Het doel van deze voorbeelden is om het mappad "C:\Program Files (x86)\Microsoft\" door te geven aan een systeemeigen opdracht, zodat het pad als een aanhalingstekenreeks is ontvangen.
De parameter echoargs van TestExe geeft de waarden weer die zijn ontvangen als argumenten voor het uitvoerbare bestand. U kunt dit hulpprogramma gebruiken om te controleren of u de tekens in uw argumenten correct hebt ontsnapt.
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 --% """C:\Program Files (x86)\Microsoft\\""
TestExe -echoargs --% """%ProgramFiles(x86)%\Microsoft\\""
De uitvoer is hetzelfde voor alle voorbeelden:
Arg 0 is <"C:\Program Files (x86)\Microsoft\">
U kunt bouwen TestExe op basis van de broncode. Zie TestExe.
Argumenten doorgeven aan PowerShell-opdrachten
Vanaf PowerShell 3.0 kunt u het token end-of-parameters (--) gebruiken om te voorkomen dat PowerShell invoer interpreteert als PowerShell-parameters. Dit is een conventie die is opgegeven in de SPECIFICATIE van POSIX Shell en Hulpprogramma's.
Het token end-of-parameters (--) geeft aan dat alle argumenten die erop volgen, in hun werkelijke vorm moeten worden doorgegeven alsof er dubbele aanhalingstekens rond de aanhalingstekens zijn geplaatst. U kunt bijvoorbeeld -- de tekenreeks -InputObject uitvoeren zonder aanhalingstekens te gebruiken of deze als parameter te laten interpreteren:
Write-Output -- -InputObject
-InputObject
In tegenstelling tot het token voor stoppen parseren (--%) kunnen alle waarden na het -- token worden geïnterpreteerd als expressies door PowerShell.
Write-Output -- -InputObject $env:PROCESSOR_ARCHITECTURE
-InputObject
AMD64
Dit gedrag is alleen van toepassing op PowerShell-opdrachten. Als u het -- token gebruikt bij het aanroepen van een externe opdracht, wordt de -- tekenreeks doorgegeven als argument voor die opdracht.
TestExe -echoargs -a -b -- -c
In de uitvoer ziet u dat deze -- wordt doorgegeven als argument aan TestExe.
Arg 0 is <-a>
Arg 1 is <-b>
Arg 2 is <-->
Arg 3 is <-c>
Experimentele functie
Powershell 7.2 bevat de experimentele functie PSNativeCommandArgumentPassing . Wanneer deze experimentele functie is ingeschakeld, gebruikt PowerShell de eigenschap ArgumentList van het StartProcessInfo object in plaats van ons huidige mechanisme voor het reconstrueren van een tekenreeks bij het aanroepen van een systeemeigen uitvoerbaar bestand.
Zie PSNativeCommandArgumentPassing voor meer informatie.