Aller au contenu principal

Le pipeline et les objets : ce qui distingue PowerShell

Notions théoriques

La grande différence avec les shells Unix

Sous Linux, un pipeline enchaîne des commandes qui échangent du texte :

ps aux | grep firefox | awk '{print $2}'

Chaque maillon doit redécouper ce texte à la main (grep, awk...) pour en extraire l'information utile. En PowerShell, le pipeline transporte de véritables objets .NET typés, avec leurs propriétés nommées :

Get-Process | Where-Object Name -eq "firefox" | Select-Object Id

Plus besoin de cut, awk ou sed pour extraire une colonne : on demande directement la propriété par son nom, et le résultat ne casse pas si la mise en forme de l'affichage change. C'est la caractéristique qui distingue le plus PowerShell des shells traditionnels.

Get-Member, l'outil de découverte

Get-Process | Get-Member

Cette commande liste toutes les propriétés et méthodes réellement disponibles sur les objets qui circulent dans le pipeline.

astuce

Le réflexe à acquérir : quand vous ne savez pas quelle propriété filtrer ou afficher, envoyez le résultat dans Get-Member pour découvrir ce qui est disponible.

attention

Ce que vous voyez à l'écran n'est pas l'objet complet : la console applique une mise en forme par défaut qui masque certaines propriétés. Get-Process | Select-Object -First 1 * révèle toutes les propriétés d'un seul objet.

Les cmdlets courantes de base

Get-ChildItem C:\Windows -File # lister des fichiers (alias : dir, ls)
Get-ChildItem C:\Windows -Recurse -Filter *.log
Get-Process
Get-Service
Get-Content fichier.txt
Get-Date
Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DriveType=3" # les disques
info

Préférez Get-CimInstance à l'ancienne cmdlet Get-WmiObject, aujourd'hui dépréciée.

Les cmdlets de traitement du pipeline

Where-Object filtre les objets. Deux écritures sont possibles :

Get-Service | Where-Object { $_.Status -eq "Stopped" } # bloc de script, la forme générale
Get-Service | Where-Object Status -eq "Stopped" # syntaxe simplifiée

$_ (ou son synonyme $PSItem) désigne l'objet en cours de traitement dans le pipeline.

Select-Object choisit les propriétés à conserver :

Get-Process | Select-Object Name, CPU
Get-Process | Select-Object -First 5
Get-Process | Select-Object -Last 3
Get-Process | Select-Object -Unique

Sort-Object trie :

Get-Process | Sort-Object CPU -Descending
Get-Process | Sort-Object Name

Measure-Object calcule des statistiques :

Get-ChildItem | Measure-Object -Property Length -Sum -Average
info

L'ordre compte : filtrez avec Where-Object avant de trier et de sélectionner, pour ne pas trier ou sélectionner des objets qui seront de toute façon écartés.

Mise en forme et export : toujours en dernier

Get-Process | Format-Table -AutoSize
Get-Process | Format-List
attention

Après un Format-*, l'objet original est détruit et remplacé par des instructions de mise en forme. Aucune cmdlet placée après ne peut plus rien filtrer ni trier : Format-* doit toujours être la dernière commande du pipeline.

Pour exporter des données exploitables (et non de la mise en forme), on utilise plutôt :

Get-Process | Export-Csv -Path "processus.csv" -NoTypeInformation -Encoding UTF8
Get-Process | ConvertTo-Json
Get-Process | ConvertTo-Html

Write-Host contre Write-Output

  • Write-Host écrit à l'écran, pour l'humain, et ne renvoie rien dans le pipeline.
  • Write-Output émet un objet dans le pipeline, exploitable par la suite du script.

Règle simple : message destiné à l'utilisateur → Write-Host ; donnée destinée à être réutilisée → Write-Output (ou simplement laisser la valeur en sortie, sans rien écrire).

Et en Bash ?
BashPowerShell
Le pipeline transporte du texteLe pipeline transporte des objets typés
grep, cut, awk pour extraire une infoWhere-Object, Select-Object sur les propriétés
sort, sort -nSort-Object
wc -lMeasure-Object
echoWrite-Host

Exemple pratique

# 1. Les 5 processus qui consomment le plus de mémoire vive
Get-Process |
Sort-Object -Property WorkingSet64 -Descending |
Select-Object -First 5 -Property Name, Id, @{Name="Mo"; Expression={[math]::Round($_.WorkingSet64 / 1MB, 1)}} |
Format-Table -AutoSize

# 2. Les services automatiques mais actuellement arrêtés
Get-Service |
Where-Object { $_.Status -eq "Stopped" -and $_.StartType -eq "Automatic" } |
Select-Object Name, DisplayName |
Export-Csv -Path "C:\Rapports\services-arretes.csv" -NoTypeInformation -Encoding UTF8

# 3. Les 10 plus gros fichiers journaux
Get-ChildItem -Path "C:\Windows\Logs" -Filter *.log -Recurse -ErrorAction SilentlyContinue |
Sort-Object Length -Descending |
Select-Object -First 10 Name, Length
astuce

Les multiplicateurs 1KB, 1MB, 1GB sont reconnus nativement par PowerShell : [math]::Round($taille / 1MB, 1) convertit des octets en mégaoctets sans calcul manuel. Notez aussi qu'un retour à la ligne est autorisé juste après un |, ce qui rend un long pipeline plus lisible.

Test de mémorisation/compréhension


Que fait circuler le pipeline PowerShell d'une commande à l'autre ?


Que représente $_ dans Where-Object { $_.Status -eq "Stopped" } ?


Pourquoi Get-Process | Format-Table | Where-Object {...} ne fonctionne-t-il pas comme attendu ?


Quelle cmdlet permet de découvrir les propriétés disponibles sur un objet ?


Quel pipeline affiche les 3 processus les plus gourmands en CPU ?


TP pour réfléchir et résoudre des problèmes

Étape 1 — Lister les 5 processus les plus gourmands en mémoire


Bonne pratique - Trier avant de sélectionner

Placez toujours Sort-Object avant Select-Object -First N : trier d'abord garantit que vous récupérez bien les N premiers éléments dans l'ordre voulu, pas un échantillon quelconque.

Étape 2 — Ne garder que les services automatiques arrêtés


Bonne pratique - Filtrer le plus tôt possible

Placez Where-Object en tout début de pipeline : cela évite de trier ou de mettre en forme des objets qui seront de toute façon écartés ensuite.

Étape 3 — Récupérer les disques et leur espace libre


Bonne pratique - Préférer Get-CimInstance à Get-WmiObject

Get-WmiObject est déprécié depuis PowerShell 3 et absent de PowerShell 7. Get-CimInstance offre les mêmes informations avec une syntaxe compatible entre toutes les versions.

Étape 4 — Exporter le résultat en CSV


Bonne pratique - Garder des objets jusqu'au bout

En n'utilisant jamais Format-* avant l'export, le CSV obtenu reste exploitable par Excel ou par Import-Csv : c'est tout l'intérêt d'avoir conservé de vrais objets tout au long du pipeline.

📌 Une solution