RUBRIQUE
about_pipelines
DESCRIPTION COURTE
Combinaison de commandes en pipelines dans Windows PowerShell
DESCRIPTION LONGUE
Un pipeline est une série de commandes connectées par des
opérateurs de pipeline (|) (ASCII 124). Chaque opérateur de
pipeline envoie les résultats de la commande précédente à la
commande suivante.
Vous pouvez utiliser des pipelines pour envoyer les objets
générés par une commande à une autre commande qui les utilisera
comme entrée à traiter. De même, vous pouvez envoyer la sortie de
cette commande à une autre commande encore. Il en résulte une
chaîne de commandes très puissante ou " pipeline " comprenant une
série de commandes simples.
Par exemple :
Command-1 | Command-2 | Command-3
Dans cet exemple, les objets émis par Command-1 sont envoyés
à Command-2. Command-2 les traite et les envoie à Command-3.
Command-3 les traite et les envoie vers la suite du pipeline.
Étant donné qu'il n'y a plus de commande dans le pipeline,
les résultats s'affichent sur la console.
Dans un pipeline, les commandes sont traitées de gauche à droite,
dans l'ordre dans lequel elles apparaissent. Le traitement est
mené comme une opération unique et la sortie est affichée dès
qu'elle est générée.
Voici un exemple simple. La commande suivante obtient le
processus Notepad (Bloc-notes), puis l'arrête.
get-process notepad | stop-process
La première commande utilise l'applet de commande Get-Process
pour obtenir un objet représentant le processus Notepad. Elle
utilise un opérateur de pipeline (|) pour envoyer l'objet
processus à l'applet de commande Stop-Process, qui arrête le
processus Notepad. Remarquez que la commande Stop-Process ne
comporte aucun paramètre Name ou ID pour spécifier le processus
car le processus spécifié est envoyé à travers le pipeline.
Voici un exemple pratique. Ce pipeline de commandes obtient les
fichiers texte du répertoire actif, sélectionne uniquement les
fichiers de plus de 10 000 octets de long, les trie par longueur,
puis affiche le nom et la longueur de chaque fichier dans une table.
Get-ChildItem -path *.txt | Where-Object {$_.length -gt 10000} |
Sort-Object -property Length | Format-Table -property name, length
Ce pipeline comporte quatre commandes dans l'ordre spécifié.
La commande est écrite horizontalement, mais nous afficherons
le processus verticalement dans le graphique suivant.
Get-ChildItem -path *.txt
|
| (FileInfo objects )
| ( .txt )
|
V
Where-Object {$_.length -gt 10000}
|
| (FileInfo objects )
| ( .txt )
| ( Length > 10000 )
|
V
Sort-Object -property Length
|
| (FileInfo objects )
| ( .txt )
| ( Length > 10000 )
| ( Sorted by length )
|
V
Format-Table -property name, length
|
| (FileInfo objects )
| ( .txt )
| ( Length > 10000 )
| ( Sorted by length )
| (Formatted in a table )
|
V
Name Length
---- ------
tmp1.txt 82920
tmp2.txt 114000
tmp3.txt 114000
UTILISATION DE PIPELINES
Les applets de commande Windows PowerShell ont été conçues pour
être utilisées dans des pipelines. Par exemple, vous pouvez
généralement rediriger les résultats d'une applet de commande
Get vers une applet de commande d'action (telle que Set, Start,
Stop ou Rename) pour le même nom.
Par exemple, vous pouvez rediriger tout service de l'applet de
commande Get-Service vers l'applet de commande Start-Service ou
Stop-Service (toutefois, les services désactivés ne peuvent pas
être redémarrés de cette façon).
Ce pipeline de commandes démarre le service WMI sur l'ordinateur
local :
get-service wmi | start-service
Les applets de commande qui obtiennent et définissent des objets
des fournisseurs Windows PowerShell, telles que les applets de
commande Item et ItemProperty, sont également conçues pour être
utilisées dans des pipelines.
Par exemple, vous pouvez rediriger les résultats d'une commande
Get-Item ou Get-ChildItem du fournisseur de Registre Windows
PowerShell vers l'applet de commande New-ItemProperty. Cette
commande ajoute une nouvelle entrée de Registre, NoOfEmployees,
avec la valeur 8124 à la clé de Registre MyCompany.
get-item -path HKLM:\Software\MyCompany | new-Itemproperty -name NoOfEmployees -value 8124
Bon nombre des applets de commande utilitaires, telles que Get-Member,
Where-Object, Sort-Object, Group-Object et Measure-Object sont utilisées
presque exclusivement dans des pipelines. Vous pouvez rediriger tout
type d'objet vers ces applets de commande.
Par exemple, vous pouvez rediriger tous les processus de
l'ordinateur vers la commande Sort-Object pour qu'ils soient
triés selon le nombre de handles qu'ils contiennent.
get-process | sort-object -property handles
De même, vous pouvez rediriger tout type d'objet vers les applets
de commande de mise en forme, telles que Format-List et
Format-Table, les applets de commande Export, telles que
Export-Clixml et Export-CSV, et les applets de commande Out,
telles qu'Out-Printer.
Par exemple, vous pouvez rediriger le processus Winlogon vers
l'applet de commande Format-List pour afficher toutes les
propriétés du processus dans une liste.
get-process winlogon | format-list -property *
Avec un peu de pratique, vous vous apercevrez que le fait de
combiner des commandes simples dans des pipelines est un réel
gain de temps et rend l'écriture de scripts plus efficace.
FONCTIONNEMENT DES PIPELINES
Lorsque vous redirigez des objets, c'est-à-dire lorsque vous les
envoyez de la sortie d'une commande vers une autre commande,
Windows PowerShell essaie de les associer à l'un des paramètres
de l'applet de commande destinataire.
Pour cela, le composant de liaison des paramètres de Windows
PowerShell, qui associe des objets d'entrée aux paramètres
d'applet de commande, essaie de trouver un paramètre remplissant
les critères suivants :
-- Le paramètre doit accepter l'entrée provenant d'un pipeline
(tous ne l'acceptent pas).
-- Le paramètre doit accepter le type d'objet envoyé ou un type
d'objet vers lequel l'objet peut être converti.
-- Le paramètre ne doit pas déjà être utilisé dans la commande.
Par exemple, l'applet de commande Start-Service comporte de
nombreux paramètres, mais seuls deux d'entre eux, Name et
InputObject, acceptent l'entrée du pipeline. Le paramètre Name
accepte des chaînes et le paramètre InputObject accepte des
objets services. Par conséquent, vous pouvez rediriger des
chaînes et des objets services (ainsi que des objets avec des
propriétés pouvant être converties en chaîne et objets services)
vers Start-Service.
Si le composant de liaison des paramètres de Windows PowerShell
ne peut pas associer les objets redirigés à un paramètre de
l'applet de commande destinataire, la commande échoue et Windows
PowerShell vous invite à fournir les valeurs de paramètre manquantes.
Vous ne pouvez pas forcer le composant de liaison des paramètres
à associer des objets redirigés à un paramètre particulier. Vous
ne pouvez même pas suggérer un paramètre. C'est en effet la
logique du composant qui gère la redirection aussi efficacement
que possible.
TRAITEMENT INDIVIDUEL
La redirection d'objets vers une commande est similaire à
l'utilisation d'un paramètre de la commande pour l'envoi des objets.
Par exemple, la redirection d'objets représentant les services
de l'ordinateur vers une commande Format-Table, comme suit :
get-service | format-table -property name, dependentservices
est similaire à la procédure consistant à enregistrer des objets
services dans une variable et à utiliser le paramètre InputObject
de Format-Table pour les envoyer
$services = get-service
format-table -inputobject $services -property name, dependentservices
ou à l'incorporation de la commande dans la valeur de paramètre.
format-table -inputobject (get-service wmi) -property name, dependentservices
Toutefois, il y a une différence importante. Lorsque vous redirigez
plusieurs objets vers une commande, Windows PowerShell les envoie
un par un. Lorsque vous utilisez un paramètre de commande, les
objets sont envoyés comme un objet tableau unique.
Cette différence apparemment technique peut avoir d'intéressantes,
et parfois utiles, conséquences.
Par exemple, si vous redirigez plusieurs objets processus de
l'applet de commande Get-Process vers l'applet de commande
Get-Member, Windows PowerShell envoie chaque objet processus,
un par un, à Get-Member. Get-Member affiche la classe (type)
.NET des objets processus et leurs propriétés et méthodes.
(Get-Member supprime les doublons, donc si les objets sont tous
du même type, il affiche un seul type d'objet.)
Dans ce cas, Get-Member affiche les propriétés et méthodes de chaque
objet processus, autrement dit, un objet System.Diagnostics.Process.
get-process | get-member
TypeName: System.Diagnostics.Process
Name MemberType Definition
---- ---------- ----------
Handles AliasProperty Handles = Handlecount
Name AliasProperty Name = ProcessName
NPM AliasProperty NPM = NonpagedSystemMemorySize
...
Toutefois, si vous utilisez le paramètre InputObject de
Get-Member, Get-Member reçoit un tableau d'objets
System.Diagnostics.Process comme seule unité et affiche les
propriétés d'un tableau d'objets. (Remarquez le symbole de
tableau ([]) après le nom de type System.Object.)
get-member -inputobject (get-process)
TypeName: System.Object[]
Name MemberType Definition
---- ---------- ----------
Count AliasProperty Count = Length
Address Method System.Object & Address(Int32 )
Clone Method System.Object Clone()
...
Ce résultat peut ne pas être ce que vous attendiez, mais lorsque
vous l'aurez compris, vous pourrez l'utiliser. Par exemple, un
tableau d'objets processus comporte une propriété Count que vous
pouvez utiliser pour compter le nombre de processus sur l'ordinateur.
(get-process).count
Cette distinction peut avoir son importance. Aussi,
rappelez-vous que lorsque vous redirigez des objets
vers une applet de commande, ils sont remis un par un.
ACCEPTE L'ENTRÉE DE PIPELINE
Pour recevoir des objets provenant d'un pipeline, l'applet de commande
destinataire doit avoir un paramètre qui accepte l'entrée de
pipeline. Vous pouvez utiliser une commande Get-Help avec les
paramètres Full ou Parameter pour déterminer lequel, le cas échéant,
des paramètres d'une applet de commande accepte l'entrée de pipeline.
Dans l'affichage par défaut de Get-Help, l'élément "Accepts
pipeline input" (" Accepte l'entrée de pipeline ") apparaît dans
une table d'attributs de paramètre. Cette table s'affiche
uniquement lorsque vous utilisez les paramètres Full ou Parameter
de l'applet de commande Get-Help.
Par exemple, pour déterminer lequel des paramètres de l'applet
de commande Start-Service accepte l'entrée de pipeline, tapez :
get-help start-service -full
get-help start-service -parameter *
Par exemple, l'aide sur l'applet de commande Start-Service indique
que les paramètres Name et InputObject acceptent l'entrée de pipeline
("true", " vrai "). Tous les autres paramètres ont une valeur "false"
(" faux ") pour la ligne "Accept pipeline input?"
(" Accepter l'entrée de pipeline ? ").
-name <string[]>
Spécifie le nom de service du service à démarrer.
Le nom de paramètre est facultatif. Vous pouvez utiliser
" -Name " ou son alias, " -ServiceName ", ou encore
omettre le nom de paramètre.
Obligatoire ? true
Position ? 1
Valeur par défaut
--> Accepter l'entrée de pipeline ? true (ByValue, ByPropertyName)
Accepter les caractères génériques ? true
-inputObject <ServiceController[]>
Spécifie les objets ServiceController représentant les
services à démarrer. Entrez une variable contenant les
objets ou tapez une commande ou une expression qui obtient
les objets.
Obligatoire ? false
Position ? named
Valeur par défaut
--> Accepter l'entrée de pipeline ? true (ByValue)
Accepter les caractères génériques ? false
Cela signifie que vous pouvez envoyer des objets (PsObject) à
travers le pipeline à l'applet de commande Where-Object et que
Windows PowerShell associera l'objet au paramètre InputObject.
MÉTHODES D'ACCEPTATION DE L'ENTRÉE DE PIPELINE
Les paramètres d'applet de commande peuvent accepter l'entrée de
pipeline de l'une des deux façons suivantes :
-- Par valeur (ByValue) : les paramètres qui acceptent l'entrée
" par valeur " peuvent accepter des objets redirigés qui ont
le même type .NET que leur valeur de paramètre ou des objets
pouvant être convertis en ce type.
Par exemple, le paramètre Name de Start-Service accepte
l'entrée de pipeline par valeur. Il peut accepter des objets
chaînes ou des objets pouvant être convertis en chaînes.
-- Par nom de propriété (ByPropertyName) : les paramètres qui
acceptent l'entrée " par nom de propriété " peuvent accepter
des objets redirigés uniquement lorsqu'une propriété de
l'objet porte le même nom que le paramètre.
Par exemple, le paramètre Name de Start-Service peut accepter
des objets ayant une propriété Name.
(Pour répertorier les propriétés d'un objet, redirigez-le
vers Get-Member.)
Certains paramètres peuvent accepter des objets par valeur ou
par nom de propriété. Ces paramètres sont conçus pour accepter
facilement l'entrée de pipeline.
EXAMEN DES ERREURS DE PIPELINE
Si une commande échoue à cause d'une erreur de pipeline,
vous pouvez examiner cette dernière et la réécrire.
Par exemple, la commande suivante essaie de déplacer une entrée
du Registre d'une clé de Registre vers une autre en utilisant
l'applet de commande Get-Item pour obtenir le chemin de destination,
puis rediriger le chemin d'accès vers l'applet de commande
Move-ItemProperty.
La commande utilise, en particulier, l'applet de commande
Get-Item pour obtenir le chemin de destination. Elle utilise un
opérateur de pipeline pour envoyer le résultat à l'applet de
commande Move-ItemProperty. La commande Move-ItemProperty
spécifie le chemin d'accès actif et le nom de l'entrée du
Registre à déplacer.
get-item -path hklm:\software\mycompany\sales |
move-itemproperty -path hklm:\software\mycompany\design -name product
La commande échoue et Windows PowerShell affiche le message
d'erreur suivant :
Move-ItemProperty : l'objet d'entrée ne peut être lié à
aucun paramètre de la commande, soit parce que cette
commande n'accepte pas l'entrée de pipeline, soit parce que
l'entrée et ses propriétés ne correspondent à aucun des
paramètres qui acceptent l'entrée de pipeline.
À la ligne : 1 Caractère : 23
+ $a | move-itemproperty <<<< -path hklm:\software\mycompany\design -name product
Pour examiner la raison de l'échec, utilisez l'applet de commande
Trace-Command pour tracer le composant de liaison des paramètres
de Windows PowerShell. La commande suivante trace le composant de
liaison des paramètres pendant que la commande procède au
traitement. Elle utilise le paramètre -pshost pour afficher les
résultats sur la console et la commande -filepath pour les
envoyer vers le fichier debug.txt pour référence ultérieure.
trace-command -name parameterbinding -expression {get-item -path
hklm:\software\mycompany\sales | move-itemproperty -path
hklm:\software\mycompany\design -name product} -pshost -filepath debug.txt
Les résultats de la trace sont longs, mais ils indiquent les
valeurs liées à l'applet de commande Get-Item, puis les valeurs
nommées liées à l'applet de commande Move-ItemProperty.
...
BIND NAMED cmd line args [Move-ItemProperty]
BIND arg [hklm:\software\mycompany\design] to parameter [Chemin d'accès]
...
BIND arg [produit] to parameter [Nom]
....
BIND POSITIONAL cmd line args [Move-ItemProperty]
...
Au final, cela montre que la tentative de liaison du chemin
d'accès au paramètre Destination de Move-ItemProperty a échoué.
...
BIND PIPELINE object to parameters: [Move-ItemProperty]
PIPELINE object TYPE = [Microsoft.Win32.RegistryKey]
RESTORING pipeline parameter's original values
Parameter [Destination] PIPELINE INPUT ValueFromPipelineByPropertyName NO COERCION
Parameter [Informations d'identification] PIPELINE INPUT ValueFromPipelineByPropertyName NO COERCION
...
Pour examiner la raison de l'échec, utilisez l'applet de
commande Get-Help pour afficher les attributs du paramètre
Destination. La commande suivante obtient des informations
détaillées sur le paramètre Destination.
get-help move-itemproperty -parameter destination
Les résultats indiquent que le paramètre Destination accepte
uniquement l'entrée de pipeline " par nom de propriété ".
Autrement dit, l'objet redirigé doit avoir une propriété nommée
Destination.
-destination <chaîne>
Spécifie le chemin d'accès à l'emplacement de destination.
Obligatoire ? true
Position ? 2
Valeur par défaut
Accepter l'entrée de pipeline ? true (ByPropertyName)
Accepter les caractères génériques ? true
Pour afficher les propriétés de l'objet redirigé vers l'applet
de commande Move-ItemProperty, redirigez-le vers l'applet de
commande Get-Member. La commande suivante redirige les résultats
de la première partie de la commande vers l'applet de commande
Get-Member.
get-item -path hklm:\software\mycompany\sales | get-member
La sortie indique que l'élément est un objet Microsoft.Win32.Regi
stryKey sans propriété Destination. Cela explique pourquoi la
commande a échoué.
Pour résoudre la commande, nous devons spécifier la destination
dans l'applet de commande Move-ItemProperty. Nous pouvons
utiliser une commande Get-ItemProperty pour obtenir le chemin
d'accès, mais le nom et la destination doivent être spécifiés
dans la partie Move-ItemProperty de la commande.
get-item -path hklm:\software\mycompany\design |
move-itemproperty -dest hklm:\software\mycompany\design -name product
Pour vérifier que la commande a fonctionné, utilisez une commande Get-ItemProperty :
get-itemproperty hklm:\software\mycompany\sales
Les résultats indiquent que l'entrée du Registre Product a été
déplacée vers la clé Sales.
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\software\mycompany\sales
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\software\mycompany
PSChildName : sales
PSDrive : HKLM
PSProvider : Microsoft.PowerShell.Core\Registry
Product : 18
VOIR AUSSI
about_objects
about_parameters
about_command_syntax
about_foreach