about_Parsing

Descrizione breve

Descrive il modo in cui PowerShell analizza i comandi.

Descrizione lunga

Quando si immette un comando al prompt dei comandi, PowerShell suddivide il testo del comando in una serie di segmenti denominati token e quindi determina come interpretare ogni token.

Ad esempio, se si digita:

Write-Host book

PowerShell suddivide il comando in due token Write-Host e bookinterpreta ogni token in modo indipendente usando una delle due modalità di analisi principali: modalità di espressione e modalità argomento.

Nota

Quando PowerShell analizza l'input del comando tenta di risolvere i nomi dei comandi in cmdlet o eseguibili nativi. Se un nome di comando non ha una corrispondenza esatta, PowerShell antepone Get- al comando come verbo predefinito. Ad esempio, PowerShell analizza Service come Get-Service. Non è consigliabile usare questa funzionalità per i motivi seguenti:

  • È inefficiente. In questo modo PowerShell esegue la ricerca più volte.
  • I programmi esterni con lo stesso nome vengono risolti per primi, quindi non è possibile eseguire il cmdlet previsto.
  • Get-Help e Get-Command non riconoscono nomi senza verbo.
  • Il nome del comando può essere una parola riservata o una parola chiave del linguaggio. Process è entrambi e non può essere risolto in Get-Process.

Modalità di espressione

La modalità di espressione è destinata alla combinazione di espressioni, necessarie per la manipolazione dei valori in un linguaggio di scripting. Le espressioni sono rappresentazioni di valori nella sintassi di PowerShell e possono essere semplici o composite, ad esempio:

Le espressioni letterali sono rappresentazioni dirette dei relativi valori:

'hello'
32

Le espressioni di variabile contengono il valore della variabile a cui fanno riferimento:

$x
$script:path

Gli operatori combinano altre espressioni per la valutazione:

-12
-not $Quiet
3 + 7
$input.Length -gt 1
  • I valori letterali stringa di caratteri devono essere contenuti tra virgolette.
  • I numeri vengono considerati come valori numerici anziché come una serie di caratteri (a meno che non venga preceduto da escape).
  • Gli operatori, inclusi gli operatori unari come - e gli operatori binari come + e -not-gt, vengono interpretati come operatori e applicano le rispettive operazioni sui relativi argomenti (operandi).
  • Le espressioni di attributo e conversione vengono analizzate come espressioni e applicate alle espressioni subordinate. Ad esempio: [int] '7'.
  • I riferimenti alle variabili vengono valutati ai relativi valori, ma lo splatting è vietato e genera un errore del parser.
  • Qualsiasi altro elemento viene considerato come un comando da richiamare.

Modalità argomento

Durante l'analisi, PowerShell cerca prima di tutto di interpretare l'input come espressione. Tuttavia, quando viene rilevata una chiamata al comando, l'analisi continua in modalità argomento. Se si dispone di argomenti che contengono spazi, ad esempio percorsi, è necessario racchiudere tali valori di argomento tra virgolette.

La modalità argomento è progettata per l'analisi di argomenti e parametri per i comandi in un ambiente shell. Tutto l'input viene considerato come una stringa espandibile a meno che non usi una delle sintassi seguenti:

  • Il segno di dollaro ($) seguito da un nome di variabile inizia un riferimento a una variabile; in caso contrario, viene interpretato come parte della stringa espandibile. Il riferimento alla variabile può includere l'accesso ai membri o l'indicizzazione.

    • I caratteri aggiuntivi che seguono riferimenti a variabili semplici, ad esempio $HOME, vengono considerati parte dello stesso argomento. Racchiudere il nome della variabile tra parentesi graffe ({}) per separarlo dai caratteri successivi. Ad esempio: ${HOME}.
    • Quando il riferimento alla variabile include l'accesso ai membri, il primo dei caratteri aggiuntivi viene considerato l'inizio di un nuovo argomento. Ad esempio $HOME.Length-more , vengono restituiti due argomenti: il valore di $HOME.Length e il valore letterale -morestringa .
  • Virgolette (' e ") iniziano stringhe

  • Parentesi graffe ({}) iniziano un nuovo blocco di script

  • Le virgole (,) introducono elenchi passati come matrici, a meno che il comando chiamato non sia un'applicazione nativa, nel qual caso vengono interpretati come parte della stringa espandibile. Le virgole iniziali, consecutive o finali non sono supportate.

  • Parentesi (()) iniziano una nuova espressione

  • L'operatore Subexpression ($()) inizia un'espressione incorporata

  • Il segno iniziale (@) inizia le sintassi delle espressioni, ad esempio splatting (@args), matrici (@(1,2,3)) e valori letterali tabella hash (@{a=1;b=2}).

  • (), $()e @() all'inizio di un token creano un nuovo contesto di analisi che può contenere espressioni o comandi annidati.

    • Se seguito da caratteri aggiuntivi, il primo carattere aggiuntivo viene considerato l'inizio di un nuovo argomento separato.
    • Se preceduto da un valore letterale $() senza virgolette, funziona come una stringa espandibile, () avvia un nuovo argomento che è un'espressione e @() viene considerato come valore letterale @ con () l'inizio di un nuovo argomento che è un'espressione.
  • Tutto il resto viene considerato come una stringa espandibile, ad eccezione dei metacharacter che richiedono ancora l'escape. Vedere Gestione di caratteri speciali.

    • I metacharacter in modalità argomento (caratteri con un significato sintattico speciale) sono: <space> ' " ` , ; ( ) { } | & < > @ #. Di questi, < > @ # sono speciali solo all'inizio di un token.
  • Il token di analisi di arresto (--%) modifica l'interpretazione di tutti gli argomenti rimanenti. Per altre informazioni, vedere la sezione relativa al token di arresto dell'analisi di seguito.

Esempi

La tabella seguente fornisce diversi esempi di token elaborati in modalità di espressione e modalità di argomento e la valutazione di tali token. Per questi esempi, il valore della variabile $a è 4.

Esempio Modalità Risultato
2 Espressione 2 (intero)
`2 Espressione "2" (comando)
Write-Output 2 Espressione 2 (intero)
2+2 Espressione 4 (intero)
Write-Output 2+2 Argomento "2+2" (stringa)
Write-Output(2+2) Espressione 4 (intero)
$a Espressione 4 (intero)
Write-Output $a Espressione 4 (intero)
$a+2 Espressione 6 (intero)
Write-Output $a+2 Argomento "4+2" (stringa)
$- Argomento "$-" (comando)
Write-Output $- Argomento "$-" (string)
a$a Espressione "a$a" (comando)
Write-Output a$a Argomento "a4" (stringa)
a'$a' Espressione "a$a" (comando)
Write-Output a'$a' Argomento "a$a" (stringa)
a"$a" Espressione "a$a" (comando)
Write-Output a"$a" Argomento "a4" (stringa)
a$(2) Espressione "a$(2)" (comando)
Write-Output a$(2) Argomento "a2" (stringa)

Ogni token può essere interpretato come un tipo di oggetto, ad esempio Boolean o String. PowerShell tenta di determinare il tipo di oggetto dall'espressione. Il tipo di oggetto dipende dal tipo di parametro previsto da un comando e dal fatto che PowerShell sappia convertire l'argomento nel tipo corretto. Nella tabella seguente vengono illustrati diversi esempi dei tipi assegnati ai valori restituiti dalle espressioni.

Esempio Modalità Risultato
Write-Output !1 Argomento "!1" (stringa)
Write-Output (!1) expression False (booleano)
Write-Output (2) expression 2 (intero)
Set-Variable AB A,B Argomento 'A','B' (matrice)
CMD /CECHO A,B Argomento 'A,B' (stringa)
CMD /CECHO $AB expression 'A B' (matrice)
CMD /CECHO :$AB Argomento ':A B' (stringa)

Gestione dei caratteri speciali

Il carattere backtick (`) può essere usato per eseguire l'escape di qualsiasi carattere speciale in un'espressione. Ciò è più utile per l'escape dei metacharacter in modalità argomento da usare come caratteri letterali anziché come metacaracter. Ad esempio, per usare il segno di dollaro ($) come valore letterale in una stringa espandibile:

"The value of `$ErrorActionPreference is '$ErrorActionPreference'."
The value of $ErrorActionPreference is 'Continue'.

Continuazione di riga

Il carattere backtick può essere usato anche alla fine di una riga per consentire di continuare l'input nella riga successiva. Ciò consente di migliorare la leggibilità di un comando che accetta diversi parametri con nomi lunghi e valori di argomento. Ad esempio:

New-AzVm `
    -ResourceGroupName "myResourceGroupVM" `
    -Name "myVM" `
    -Location "EastUS" `
    -VirtualNetworkName "myVnet" `
    -SubnetName "mySubnet" `
    -SecurityGroupName "myNetworkSecurityGroup" `
    -PublicIpAddressName "myPublicIpAddress" `
    -Credential $cred

Tuttavia, è consigliabile evitare di usare la continuazione di riga.

  • I personaggi di backtick possono essere difficili da vedere e facile da dimenticare.
  • Uno spazio aggiuntivo dopo che il backtick interrompe la continuazione della riga. Poiché lo spazio è difficile da vedere, può essere difficile trovare l'errore.

PowerShell offre diversi modi per suddividere le linee in punti naturali nella sintassi.

  • Dopo i caratteri pipe (|)
  • Dopo gli operatori binari (+, -, -eqe così via)
  • Dopo le virgole (,) in una matrice
  • Dopo l'apertura di caratteri, ad [esempio , , {(

Per il set di parametri di grandi dimensioni, usare invece splatting. Ad esempio:

$parameters = @{
    ResourceGroupName = "myResourceGroupVM"
    Name = "myVM"
    Location = "EastUS"
    VirtualNetworkName = "myVnet"
    SubnetName = "mySubnet"
    SecurityGroupName = "myNetworkSecurityGroup"
    PublicIpAddressName = "myPublicIpAddress"
    Credential = $cred
}
New-AzVm @parameters

Passaggio di argomenti a comandi nativi

Quando si eseguono comandi nativi da PowerShell, gli argomenti vengono prima analizzati da PowerShell. Gli argomenti analizzati vengono quindi uniti in una singola stringa con ogni parametro separato da uno spazio.

Ad esempio, il comando seguente chiama il icacls.exe programma.

icacls X:\VMS /grant Dom\HVAdmin:(CI)(OI)F

Per eseguire questo comando in PowerShell 2.0, è necessario usare caratteri di escape per impedire a PowerShell di interpretazione errata delle parentesi.

icacls X:\VMS /grant Dom\HVAdmin:`(CI`)`(OI`)F

Token di arresto dell'analisi

A partire da PowerShell 3.0, è possibile usare il token di interruzione dell'analisi (--%) per impedire a PowerShell di interpretare l'input come comandi o espressioni di PowerShell.

Nota

Il token di arresto dell'analisi è destinato solo all'uso di comandi nativi nelle piattaforme Windows.

Quando si chiama un comando nativo, posizionare il token di arresto dell'analisi prima degli argomenti del programma. Questa tecnica è molto più semplice rispetto all'uso di caratteri di escape per evitare errori di interpretazione.

Quando rileva un token di arresto dell'analisi, PowerShell considera i caratteri rimanenti nella riga come valore letterale. L'unica interpretazione eseguita consiste nel sostituire i valori per le variabili di ambiente che usano la notazione standard di Windows, ad esempio %USERPROFILE%.

icacls X:\VMS --% /grant Dom\HVAdmin:(CI)(OI)F

PowerShell invia la stringa di comando seguente al icacls.exe programma:

X:\VMS /grant Dom\HVAdmin:(CI)(OI)F

Il token di analisi dell'arresto è effettivo solo fino al successivo carattere di nuova riga o pipeline. Non è possibile usare il carattere di continuazione della riga (`) per estenderne l'effetto o usare un delimitatore di comando (;) per terminarne l'effetto.

%variable% Oltre ai riferimenti a variabili di ambiente, non è possibile incorporare altri elementi dinamici nel comando. L'escape di un % carattere come %%, il modo in cui è possibile eseguire all'interno di file batch, non è supportato. %<name>% i token vengono espansi invariabilmente. Se <name> non fa riferimento a una variabile di ambiente definita, il token viene passato così come è.

Non è possibile usare il reindirizzamento del flusso (ad esempio >file.txt) perché vengono passati verbatim come argomenti al comando di destinazione.

Nell'esempio seguente il primo passaggio esegue un comando senza usare il token di analisi di arresto. PowerShell valuta la stringa tra virgolette e passa il valore (senza virgolette) a cmd.exe, che genera un errore.

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"

Nota

Il token di arresto dell'analisi non è necessario quando si usano i cmdlet di PowerShell. Tuttavia, può essere utile passare argomenti a una funzione di PowerShell progettata per chiamare un comando nativo con tali argomenti.

Passaggio di argomenti contenenti caratteri virgolette

Alcuni comandi nativi prevedono argomenti che contengono caratteri virgolette. PowerShell 7.3 ha modificato la modalità di analisi della riga di comando per i comandi nativi.

Attenzione

Il nuovo comportamento è una modifica che causa un'interruzione rispetto al comportamento di Windows PowerShell 5.1. Questo può interrompere gli script e l'automazione che possono risolvere i vari problemi quando si richiamano applicazioni native. Usare il token di arresto dell'analisi (--%) o il Start-Process cmdlet per evitare il passaggio dell'argomento nativo quando necessario.

La nuova $PSNativeCommandArgumentPassing variabile di preferenza controlla questo comportamento. Questa variabile consente di selezionare il comportamento in fase di esecuzione. I valori validi sono Legacy, Standarde Windows. Il comportamento predefinito è specifico della piattaforma. Nelle piattaforme Windows l'impostazione predefinita è Windows e le piattaforme non Windows per impostazione predefinita sono Standard.

Legacy è il comportamento storico. Il comportamento di Windows e Standard la modalità sono uguali tranne, in Windows modalità, le chiamate dei file seguenti usano automaticamente l'argomento di Legacy stile passando.

  • cmd.exe
  • cscript.exe
  • wscript.exe
  • terminando con .bat
  • terminando con .cmd
  • terminando con .js
  • terminando con .vbs
  • terminando con .wsf

$PSNativeCommandArgumentPassing Se è impostato su Legacy o Standard, il parser non verifica la presenza di questi file.

Nota

Negli esempi seguenti viene usato lo TestExe.exe strumento . È possibile eseguire la compilazione TestExe dal codice sorgente. Vedere TestExe nel repository di origine di PowerShell.

Nuovi comportamenti resi disponibili da questa modifica:

  • Le stringhe letterali o espandibili con virgolette incorporate vengono ora mantenute:

    PS> $a = 'a" "b'
    PS> TestExe -echoargs $a 'c" "d' e" "f
    Arg 0 is <a" "b>
    Arg 1 is <c" "d>
    Arg 2 is <e f>
    
  • Le stringhe vuote come argomenti vengono ora mantenute:

    PS> TestExe -echoargs '' a b ''
    Arg 0 is <>
    Arg 1 is <a>
    Arg 2 is <b>
    Arg 3 is <>
    

L'obiettivo di questi esempi è passare il percorso della directory (con spazi e virgolette) "C:\Program Files (x86)\Microsoft\" a un comando nativo in modo che abbia ricevuto il percorso come stringa tra virgolette.

In Windows modalità o Standard , gli esempi seguenti producono i risultati previsti:

TestExe -echoargs """${env:ProgramFiles(x86)}\Microsoft\"""
TestExe -echoargs '"C:\Program Files (x86)\Microsoft\"'

Per ottenere gli stessi risultati in Legacy modalità, è necessario eseguire l'escape delle virgolette o usare il token di analisi stop (--%):

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\\""

Nota

Il carattere barra rovesciata (\) non viene riconosciuto come carattere di escape da PowerShell. È il carattere di escape usato dall'API sottostante per ProcessStartInfo.ArgumentList.

PowerShell 7.3 ha anche aggiunto la possibilità di tracciare l'associazione dei parametri per i comandi nativi. Per altre informazioni, vedere Trace-Command.

Passaggio di argomenti ai comandi di PowerShell

A partire da PowerShell 3.0, è possibile usare il token end-of-parameters (--) per impedire a PowerShell di interpretare l'input come parametri di PowerShell. Si tratta di una convenzione specificata nella specifica POSIX Shell e Utilities.

Token di fine parametri

Il token end-of-parameters (--) indica che tutti gli argomenti che seguono devono essere passati nel formato effettivo come se le virgolette doppie fossero posizionate intorno a esse. Ad esempio, è -- possibile restituire la stringa -InputObject senza usare virgolette o averla interpretata come parametro:

Write-Output -- -InputObject
-InputObject

A differenza del token di arresto dell'analisi (--%), tutti i valori che seguono il -- token possono essere interpretati come espressioni da PowerShell.

Write-Output -- -InputObject $env:PROCESSOR_ARCHITECTURE
-InputObject
AMD64

Questo comportamento si applica solo ai comandi di PowerShell. Se si usa il -- token quando si chiama un comando esterno, la -- stringa viene passata come argomento a tale comando.

TestExe -echoargs -a -b -- -c

L'output mostra che -- viene passato come argomento a TestExe.

Arg 0 is <-a>
Arg 1 is <-b>
Arg 2 is <-->
Arg 3 is <-c>

Vedi anche