about_Pipelines
Mis à jour: mai 2014
S'applique à: Windows PowerShell 2.0, Windows PowerShell 3.0, Windows PowerShell 4.0, Windows PowerShell 5.0
RUBRIQUE
about_pipelines
DESCRIPTION COURTE
Combinaison de commandes en pipelines dans Windows PowerShell
DESCRIPTION DÉTAILLÉE
Un pipeline est une série de commandes reliées par des opérateurs de pipeline (|, code ASCII 124). Chaque opérateur de pipeline envoie les résultats de la commande précédente à la commande suivante.
Vous pouvez utiliser les pipelines pour envoyer les objets générés par une commande afin qu'ils soient utilisés comme entrée d'une autre commande pour traitement. Et vous pouvez encore envoyer la sortie de la commande à une autre commande. Le résultat est une chaîne de commandes très puissante ou « pipeline », composée d'une série de commandes simples.
Par exemple,
Command-1 | Command-2 | Command-3
Dans cet exemple, les objets que Command-1 émet sont envoyés à Command-2. Command-2 traite les objets et les envoie à Command-3. Command-3 traite les objets et les envoie dans le pipeline. Comme il n'y a pas d'autres commandes dans le pipeline, les résultats sont affichés sur la console.
Dans un pipeline, les commandes sont traitées de gauche à droite, dans l'ordre dans lequel elles apparaissent. Le traitement est géré comme une seule opération et la sortie est affichée telle 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. Notez que la commande Stop-Process n'a pas de 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 commande obtient les fichiers texte dans le répertoire en cours, sélectionne uniquement les fichiers longs de plus de 10 000 octets, les trie par longueur et 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 est composé de quatre commandes dans l'ordre spécifié. La commande est écrite horizontalement, mais nous allons montrer 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 DES PIPELINES
Les applets de commande Windows PowerShell ont été conçues pour être utilisées dans les pipelines. Par exemple, vous pouvez généralement diriger les résultats d'une applet de commande Get vers une applet de commande de type action (par exemple, une applet de commande Set, Start, Stop ou Rename) pour le même nom.
Par exemple, vous pouvez acheminer un service à partir de l'applet de commande Get-Service vers les applets de commande Start-Service ou Stop-Service (bien que les services désactivés ne puissent pas être redémarrés de cette façon).
Ce pipeline de commande démarre le service WMI sur l'ordinateur :
get-service wmi | start-service
Les applets de commande qui obtiennent et définissent les objets des fournisseurs Windows PowerShell, tels que les applets de commande Item et ItemProperty, sont également conçues pour être utilisées dans les pipelines.
Par exemple, vous pouvez diriger 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, ayant la valeur 8124, à la clé de Registre MyCompany.
get-item -path HKLM:\Software\MyCompany | new-Itemproperty -name NoOfEmployees -value 8124
La plupart des applets de commande utilitaires, telles que Get-Member, Where-Object, Sort-Object, Group-Object et Measure-Object, sont utilisées presque uniquement dans les pipelines. Vous pouvez diriger tous les objets vers ces applets de commande.
Par exemple, vous pouvez diriger tous les processus de l'ordinateur vers la commande Sort-Object et les faire trier par nombre de handles dans le processus.
get-process | sort-object -property handles
En outre, vous pouvez acheminer des objets vers les applets de commande de mise en forme, telles que Format-List et Format-Table, les applets de commande Export, telles qu'Export-Clixml et Export-CSV, et les applets de commande Out, telles qu'Out-Printer.
Par exemple, vous pouvez diriger 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 constaterez que la combinaison de commandes simples en pipelines permet de gagner du temps, d'économiser de la saisie et d'augmenter l'efficacité de votre script.
FONCTIONNEMENT DES PIPELINES
Lorsque vous « redirigez dans un pipeline » des objets, c'est-à-dire que vous envoyez les objets de la sortie d'une commande vers une autre commande, Windows PowerShell tente d'associer les objets redirigés avec l'un des paramètres de l'applet de commande de réception.
Pour ce faire, le composant de « liaison de paramètre » de Windows PowerShell, qui associe les objets d'entrée aux paramètres d'applet de commande, essaie de trouver un paramètre qui répond aux critères suivants :
-- Le paramètre doit accepter l'entrée d'un pipeline (tous ne le font pas)
-- Le paramètre doit accepter le type d'objet envoyé ou un type dans lequel l'objet peut être converti.
-- Le paramètre ne doit pas être déjà utilisé dans la commande.
Par exemple, l'applet de commande Start-Service possède de nombreux paramètres, mais seuls deux d'entre eux, Name et InputObject, acceptent l'entrée de pipeline. Le paramètre Name accepte les chaînes et le paramètre InputObject les objets de service. Par conséquent, vous pouvez rediriger des chaînes et des objets de service (et les objets avec les propriétés qui peuvent être converties en objets chaîne et service) vers Start-Service.
Si le composant de liaison de paramètre de Windows PowerShell ne peut pas associer les objets redirigés à un paramètre de l'applet de commande de réception, la commande échoue et Windows PowerShell vous invite à saisir les valeurs des paramètres manquants.
Vous ne pouvez pas obliger le composant de liaison de paramètre à associer les objets redirigés à un paramètre particulier ; vous ne pouvez même pas suggérer un paramètre. Au lieu de cela, la logique du composant gère le pipe aussi efficacement que possible.
TRAITEMENT UN À LA FOIS
Rediriger en pipe les objets vers une commande s'apparente beaucoup à l'utilisation d'un paramètre de la commande pour envoyer les objets.
Par exemple, la redirection en pipe d'objets représentant les services sur l'ordinateur vers une commande Format-Table, comme :
get-service | format-table -property name, dependentservices
est similaire à l'enregistrement des objets de service dans une variable et à l'utilisation du paramètre InputObject de Format-Table pour envoyer l'objet de service.
$services = get-service
format-table -inputobject $services -property name, dependentservices
ou à l'incorporation de la commande dans la valeur du paramètre
format-table -inputobject (get-service wmi) -property name, dependentservices
Cependant, il existe une différence importante. Lorsque vous redirigez en pipe plusieurs objets vers une commande, Windows PowerShell envoie les objets à la commande l'un après l'autre. Lorsque vous utilisez un paramètre de commande, les objets sont envoyés comme objet de tableau unique.
Cette différence apparemment technique peut avoir des conséquences intéressantes et, parfois, utiles.
Par exemple, si vous dirigez plusieurs objets de processus depuis l'applet de commande Get-Process vers l'applet de commande Get-Member, Windows PowerShell envoie chaque processus, un seul à la fois, à Get-Member. Get-Member affiche la classe .NET (type) des objets du processus, ainsi que leurs propriétés et méthodes. (Comme Get-Member élimine les doublons, si les objets sont tous du même type, un seul type d'objet est affiché.)
Dans ce cas, Get-Member affiche les propriétés et les méthodes de chaque objet de 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 ensuite un tableau d'objets System.Diagnostics.Process comme seule unité et affiche les propriétés d'un tableau d'objets. (Notez 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 celui que vous attendiez, mais une fois que vous l'avez compris, vous pouvez l'utiliser. Par exemple, un tableau d'objets de processus possède une propriété Count que vous pouvez utiliser pour compter le nombre de processus sur l'ordinateur.
(get-process).count
Comme cette distinction peut être importante, n'oubliez pas que lorsque vous redirigez en pipe les objets vers une applet de commande, ils sont transmis l'un après l'autre.
ACCEPTE LES ENTRÉES DE PIPELINE
Pour recevoir des objets dans un pipeline, l'applet de commande de réception doit avoir un paramètre qui accepte les entrées de pipeline. Vous pouvez utiliser une commande Get-Help avec les paramètres Full ou Parameter afin de déterminer lequel des paramètres d'une applet de commande, le cas échéant, accepte les entrées de pipeline.
Dans l'affichage par défaut de Get-Help, l'élément « Accepte l'entrée de pipeline » apparaît dans le tableau des attributs de paramètre. Ce tableau s'affiche uniquement lorsque vous utilisez les paramètres Full ou Parameter de l'applet de commande Get-Help.
Par exemple, pour déterminer les paramètres dont l'applet de commande Start-Service accepte les entrées de pipeline, tapez :
get-help start-service -full
get-help start-service -parameter *
Par exemple, l'aide de l'applet de commande Start-Service indique que les paramètres Name et InputObject acceptent les entrées de pipeline (« true »). Tous les autres paramètres ont la valeur « false » dans la ligne « Accepter l'entrée de pipeline ? ».
-name <string[]>
Specifies the service names for the service to be started.
The parameter name is optional. You can use "-Name" or its alias,
"-ServiceName", or you can omit the parameter name.
Required? true
Position? 1
Default value
--> Accept pipeline input? true (ByValue, ByPropertyName)
Accept wildcard characters? true
-inputObject <ServiceController[]>
Specifies ServiceController objects representing the services to be started. Enter
a variable that contains the objects or type a command or expression that gets the
objects.
Required? false
Position? named
Default value
--> Accept pipeline input? true (ByValue)
Accept wildcard characters? false
Cela signifie que vous pouvez envoyer des objets (PsObjects) via le pipeline à l'applet de commande Where-Object et que Windows PowerShell associera l'objet au paramètre InputObject.
MÉTHODES D'ACCEPTATION D'UNE ENTRÉE DE PIPELINE
Les paramètres des applets de commande peuvent accepter les entrées de pipeline de deux façons différentes :
-- Par valeur : Les paramètres qui acceptent les entrées « par valeur » peuvent accepter les objets transmis dans le pipe qui ont le même type .NET que la valeur du paramètre ou les objets qui peuvent être convertis dans ce type.
Par exemple, le paramètre Name de Start-Service accepte les entrées de pipeline par valeur. Il peut accepter des objets de type chaîne (string) ou qui peuvent être convertis en chaînes.
-- Par nom de propriété : Les paramètres acceptant les entrées « par nom de propriété » peuvent accepter les objets redirigés en pipe uniquement lorsqu'une propriété de l'objet a 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 afficher les propriétés d'un objet, dirigez-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 les entrées du pipeline.
RECHERCHE DES ERREURS DE PIPELINE
Si une commande échoue en raison d'une erreur de pipeline, vous pouvez étudier l'échec et écrire à nouveau la commande.
Par exemple, la commande suivante tente de déplacer une entrée de Registre depuis une clé de Registre vers une autre à l'aide de l'applet de commande Get-Item pour obtenir le chemin d'accès de destination, puis en dirigeant le chemin d'accès vers l'applet de commande Move-ItemProperty.
Plus particulièrement, la commande utilise l'applet de commande Get-Item pour obtenir le chemin d'accès de destination. Elle utilise un opérateur de pipeline (|) pour envoyer le résultat vers l’applet de commande Move-ItemProperty. La commande Move-ItemProperty spécifie le chemin d'accès actuel et le nom de l'entrée de 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 : The input object cannot be bound to any parameters for the
command either because the command does not take pipeline input or the input
and its properties do not match any of the parameters that take pipeline input.
At line:1 char:23
+ $a | move-itemproperty <<<< -path hklm:\software\mycompany\design -name product
Pour enquêter, utilisez l'applet de commande Trace-Command afin de suivre le composant de liaison de paramètre de Windows PowerShell. La commande suivante suit le composant de liaison de paramètre pendant le traitement de la commande. Elle utilise le paramètre - pshost pour afficher les résultats sur la console et la commande - filepath pour les envoyer au fichier debug.txt à des fins de 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 du suivi sont longs, mais ils affichent 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 [Path]
...
BIND arg [product] to parameter [Name]
....
BIND POSITIONAL cmd line args [Move-ItemProperty]
...
Enfin, l'applet de commande indique que la tentative de lier le 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 [Credential] PIPELINE INPUT ValueFromPipelineByPropertyName NO COERCION
...
Pour analyser l'échec, utilisez l'applet de commande Get-Help afin d'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 montrent que Destination accepte les entrées de pipeline uniquement « par nom de propriété ». Autrement dit, l'objet redirigé doit avoir une propriété nommée Destination.
-destination <string>
Specifies the path to the destination location.
Required? true
Position? 2
Default value
Accept pipeline input? true (ByPropertyName)
Accept wildcard characters? 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.RegistryKey qui n'a pas de propriété Destination. Telle est la raison pour laquelle la commande a échoué.
Pour corriger 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 montrent que l'entrée de 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