Partager via


about_Parsing

Description courte

Décrit comment PowerShell analyse les commandes.

Description longue

Lorsque vous entrez une commande à l’invite de commandes, PowerShell décompose le texte de la commande en une série de segments appelés jetons , puis détermine comment interpréter chaque jeton.

Par exemple, si vous tapez :

Write-Host book

PowerShell décompose la commande en deux jetons, Write-Host et book, et interprète chaque jeton indépendamment à l’aide de l’un des deux principaux modes d’analyse : le mode expression et le mode argument.

Notes

Lorsque PowerShell analyse l’entrée de commande, il tente de résoudre les noms des commandes en applets de commande ou exécutables natifs. Si un nom de commande n’a pas de correspondance exacte, PowerShell ajoute Get- à la commande en tant que verbe par défaut. Par exemple, PowerShell analyse en Process tant que Get-Process. Il n’est pas recommandé d’utiliser cette fonctionnalité pour les raisons suivantes :

  • C’est inefficace. PowerShell effectue alors plusieurs recherches.
  • Les programmes externes portant le même nom sont résolus en premier. Vous ne pouvez donc pas exécuter l’applet de commande prévue.
  • Get-Help et Get-Command ne reconnaissent pas les noms sans verbe.

Mode Expression

Le mode Expression est destiné à combiner des expressions, requis pour la manipulation de valeur dans un langage de script. Les expressions sont des représentations de valeurs dans la syntaxe PowerShell et peuvent être simples ou composites, par exemple :

Les expressions littérales sont des représentations directes de leurs valeurs :

'hello'
32

Les expressions de variable portent la valeur de la variable qu’elles référencent :

$x
$script:path

Les opérateurs combinent d’autres expressions à des fins d’évaluation :

-12
-not $Quiet
3 + 7
$input.Length -gt 1
  • Les littéraux de chaîne de caractères doivent être contenus entre guillemets.
  • Les nombres sont traités comme des valeurs numériques plutôt que comme une série de caractères (sauf s’ils sont placés dans une séquence d’échappement).
  • Les opérateurs, y compris les opérateurs unaires comme - et et -not les opérateurs binaires comme + et -gt, sont interprétés comme des opérateurs et appliquent leurs opérations respectives sur leurs arguments (opérandes).
  • Les expressions d’attribut et de conversion sont analysées en tant qu’expressions et appliquées aux expressions subordonnées, par exemple [int] '7'.
  • Les références de variables sont évaluées à leurs valeurs, mais la platissement (c’est-à-dire le collage de jeux de paramètres préremplis) est interdit et provoque une erreur d’analyseur.
  • Toute autre commande sera traitée comme une commande à appeler.

Mode Argument

Lors de l’analyse, PowerShell cherche d’abord à interpréter l’entrée en tant qu’expression. Toutefois, lorsqu’un appel de commande est rencontré, l’analyse se poursuit en mode argument. Si vous avez des arguments qui contiennent des espaces, tels que des chemins, vous devez placer ces valeurs d’argument entre guillemets.

Le mode Argument est conçu pour analyser les arguments et les paramètres des commandes dans un environnement d’interpréteur de commandes. Toutes les entrées sont traitées comme une chaîne extensible, sauf si elles utilisent l’une des syntaxes suivantes :

  • Le signe dollar ($) suivi d’un nom de variable commence une référence de variable, sinon il est interprété comme faisant partie de la chaîne extensible. La référence de variable peut inclure l’accès aux membres ou l’indexation.

    • Les caractères supplémentaires qui suivent des références de variables simples, comme $HOME, sont considérés comme faisant partie du même argument. Placez le nom de la variable entre accolades ({}) pour le séparer des caractères suivants. Par exemple : ${HOME}.
    • Lorsque la référence de variable inclut l’accès aux membres, le premier des caractères supplémentaires est considéré comme le début d’un nouvel argument. Par exemple$HOME.Length-more, génère deux arguments : la valeur de et le littéral -morede $HOME.Length chaîne .
  • Guillemets (' et ") commencent les chaînes

  • Accolades ({}) commencent un nouveau bloc de script

  • Les virgules (,) introduisent des listes passées en tant que tableaux, sauf lorsque la commande à appeler est une application native, auquel cas elles sont interprétées comme faisant partie de la chaîne extensible. Les virgules initiales, consécutives ou de fin ne sont pas prises en charge.

  • Les parenthèses (()) commencent une nouvelle expression

  • L’opérateur subexpression ($()) commence une expression incorporée

  • Initial at sign (@) commence les syntaxes d’expression telles que splatting (@args), les tableaux (@(1,2,3)) et les littéraux de table de hachage (@{a=1;b=2}).

  • (), $()et @() au début d’un jeton créent un contexte d’analyse qui peut contenir des expressions ou des commandes imbriquées.

    • Lorsqu’il est suivi de caractères supplémentaires, le premier caractère supplémentaire est considéré comme le début d’un nouvel argument distinct.
    • Lorsqu’il est précédé d’un littéral $() sans guillemets fonctionne comme une chaîne extensible, () démarre un nouvel argument qui est une expression et @() est pris comme littéral @ avec () le démarrage d’un nouvel argument qui est une expression.
  • Tout le reste est traité comme une chaîne extensible, à l’exception des métacharacteurs qui ont encore besoin de s’échapper.

    • Les métacharacteurs en mode argument (caractères avec une signification syntaxique spéciale) sont les suivants : <space> ' " ` , ; ( ) { } | & < > @ #. Parmi ceux-ci, < > @ # sont uniquement spéciaux au début d’un jeton.
  • Le jeton d’arrêt d’analyse (--%) modifie l’interprétation de tous les arguments restants. Pour plus d’informations, consultez la section jeton d’arrêt d’analyse ci-dessous.

Exemples

Le tableau suivant fournit plusieurs exemples de jetons traités en mode d’expression et en mode argument, ainsi que l’évaluation de ces jetons. Pour ces exemples, la valeur de la variable $a est 4.

Exemple Mode Résultats
2 Expression 2 (entier)
`2 Expression « 2 » (commande)
Write-Output 2 Expression 2 (entier)
2+2 Expression 4 (entier)
Write-Output 2+2 Argument « 2+2 » (chaîne)
Write-Output(2+2) Expression 4 (entier)
$a Expression 4 (entier)
Write-Output $a Expression 4 (entier)
$a+2 Expression 6 (entier)
Write-Output $a+2 Argument « 4+2 » (chaîne)
$- Argument « $- » (commande)
Write-Output $- Argument « $- » (chaîne)
a$a Expression « a$a » (commande)
Write-Output a$a Argument « a4 » (chaîne)
a'$a' Expression « a$a » (commande)
Write-Output a'$a' Argument « a$a » (chaîne)
a"$a" Expression « a$a » (commande)
Write-Output a"$a" Argument « a4 » (chaîne)
a$(2) Expression « a$(2) » (commande)
Write-Output a$(2) Argument « a2 » (chaîne)

Chaque jeton peut être interprété comme un type d’objet, tel que Boolean ou String. PowerShell tente de déterminer le type d’objet à partir de l’expression. Le type d’objet dépend du type de paramètre attendu par une commande et de savoir si PowerShell sait comment convertir l’argument vers le type correct. Le tableau suivant présente plusieurs exemples de types attribués aux valeurs retournées par les expressions.

Exemple Mode Résultats
Write-Output !1 argument « !1 » (chaîne)
Write-Output (!1) expression False (booléen)
Write-Output (2) expression 2 (entier)
Set-Variable AB A,B argument 'A','B' (tableau)
CMD /CECHO A,B argument 'A,B' (chaîne)
CMD /CECHO $AB expression 'A B' (tableau)
CMD /CECHO :$AB argument ' :A B' (string)

Transfert d’arguments à des commandes natives

Lors de l’exécution de commandes natives à partir de PowerShell, les arguments sont d’abord analysés par PowerShell. Les arguments analysés sont ensuite joints en une seule chaîne avec chaque paramètre séparé par un espace.

Par exemple, la commande suivante appelle le icacls.exe programme.

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

Pour exécuter cette commande dans PowerShell 2.0, vous devez utiliser des caractères d’échappement pour empêcher PowerShell de mal interpréter les parenthèses.

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

Jeton d’arrêt de l’analyse

À compter de PowerShell 3.0, vous pouvez utiliser le jeton d’arrêt d’analyse (--%) pour empêcher PowerShell d’interpréter l’entrée en tant que commandes ou expressions PowerShell.

Notes

Le jeton d’arrêt d’analyse est uniquement destiné à être utilisé sur les plateformes Windows.

Lors de l’appel d’une commande native, placez le jeton d’arrêt d’analyse avant les arguments du programme. Cette technique est beaucoup plus facile que d’utiliser des caractères d’échappement pour éviter une mauvaise interprétation.

Lorsqu’il rencontre un jeton d’analyse d’arrêt, PowerShell traite les caractères restants dans la ligne comme un littéral. La seule interprétation qu’il effectue consiste à substituer des valeurs aux variables d’environnement qui utilisent la notation Windows standard, comme %USERPROFILE%.

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

PowerShell envoie la chaîne de commande suivante au icacls.exe programme :

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

Le jeton d’analyse d’arrêt n’est effectif que jusqu’au caractère de ligne ou de pipeline suivant. Vous ne pouvez pas utiliser un caractère de continuation (`) pour étendre son effet ou utiliser un délimiteur de commande (;) pour arrêter son effet.

En dehors des %variable% références de variable d’environnement, vous ne pouvez pas incorporer d’autres éléments dynamiques dans la commande. L’échappement d’un % caractère en tant que %%, comme vous pouvez le faire dans les fichiers batch, n’est pas pris en charge. %<name>% les jetons sont toujours développés. Si <name> ne fait pas référence à une variable d’environnement définie, le jeton est transmis tel quel.

Vous ne pouvez pas utiliser la redirection de flux (comme >file.txt) car ils sont passés textuellement en tant qu’arguments à la commande cible.

Passage d’arguments contenant des guillemets

Certaines commandes natives attendent des arguments qui contiennent des guillemets. Normalement, l’analyse de ligne de commande de PowerShell supprime le guillemet que vous avez fourni. Les arguments analysés sont ensuite joints en une seule chaîne avec chaque paramètre séparé par un espace. Cette chaîne est ensuite affectée à la propriété Arguments d’un ProcessStartInfo objet . Les guillemets dans la chaîne doivent être placés dans une séquence d’échappement à l’aide de guillemets supplémentaires ou de caractères de barre oblique inverse (\).

Notes

La barre oblique inverse (\) n’est pas reconnue comme caractère d’échappement par PowerShell. Il s’agit du caractère d’échappement utilisé par l’API sous-jacente pour ProcessStartInfo.Arguments.

Pour plus d’informations sur les exigences d’échappement, consultez la documentation de ProcessStartInfo.Arguments.

Exemples suivants utilisant l’outil TestExe.exe . Cet outil est utilisé par les tests Pester dans le référentiel source PowerShell. L’objectif de ces exemples est de passer le chemin d’accès "C:\Program Files (x86)\Microsoft\" au répertoire à une commande native afin qu’elle reçoive le chemin sous forme de chaîne entre guillemets.

Le paramètre echoargs de TestExe affiche les valeurs reçues en tant qu’arguments de l’exécutable. Vous pouvez utiliser cet outil pour vérifier que vous avez correctement échappé les caractères de vos arguments.

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

La sortie est la même pour tous les exemples :

Arg 0 is <"C:\Program Files (x86)\Microsoft\">

Vous pouvez générer TestExe à partir du code source. Consultez TestExe.

Passage d’arguments aux commandes PowerShell

À compter de PowerShell 3.0, vous pouvez utiliser le jeton de fin de paramètres (--) pour empêcher PowerShell d’interpréter l’entrée en tant que paramètres PowerShell. Il s’agit d’une convention spécifiée dans la spécification POSIX Shell et Utilities.

Le jeton de fin de paramètre (--) indique que tous les arguments qui le suivent doivent être passés sous leur forme réelle comme si des guillemets doubles étaient placés autour d’eux. Par exemple, en utilisant -- vous pouvez générer la chaîne -InputObject sans utiliser de guillemets ou la faire interpréter comme un paramètre :

Write-Output -- -InputObject
-InputObject

Contrairement au jeton d’arrêt d’analyse (--%), toutes les valeurs qui suivent le -- jeton peuvent être interprétées comme des expressions par PowerShell.

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

Ce comportement s’applique uniquement aux commandes PowerShell. Si vous utilisez le jeton lors de l’appel -- d’une commande externe, la -- chaîne est passée en tant qu’argument à cette commande.

TestExe -echoargs -a -b -- -c

La sortie indique que -- est passé en tant qu’argument à TestExe.

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

Voir aussi