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.
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.
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
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
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
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).
| Bash | PowerShell |
|---|---|
| Le pipeline transporte du texte | Le pipeline transporte des objets typés |
grep, cut, awk pour extraire une info | Where-Object, Select-Object sur les propriétés |
sort, sort -n | Sort-Object |
wc -l | Measure-Object |
echo | Write-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
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
TP pour réfléchir et résoudre des problèmes
Étape 1 — Lister les 5 processus les plus gourmands en mémoire
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
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
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
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.