Tutoriels gratuits et ouverts à toutes et à tous · conçus au Lycée Chevrollier — AngersÀ propos

Série « Parcours PowerShell » · partie 2 / 8

PowerShell niveau 1 — Objets et pipeline

Enchaîner les commandes, filtrer, trier, sélectionner et exporter des résultats : niveau 1 du parcours PowerShell, avec exercices corrigés et QCM.

Systèmes✎ B. Jousseaume📅 17 octobre 2026⏱ 4 h📶 Débutant

1. Le pipeline

La barre verticale | envoie le résultat d’une commande vers la commande suivante, qui le reçoit comme entrée. On lit la ligne de gauche à droite, comme une phrase.

PS> Get-Service | Where-Object Status -eq "Running" | Sort-Object DisplayName

#  « prends les services, garde ceux qui tournent, trie-les par nom d'affichage »

Chaque étage reçoit des objets complets, pas du texte. Rien n’est perdu en route : après le filtre, on peut encore accéder à n’importe quelle propriété.

2. Explorer un objet : Get-Member

Pour savoir ce que contient un objet et ce qu’on peut en faire :

PS> Get-Service | Get-Member

   TypeName: System.ServiceProcess.ServiceController

Name                 MemberType    Definition
----                 ----------    ----------
Start                Method        void Start()
Stop                 Method        void Stop()
DisplayName          Property      string DisplayName {get;set;}
Status               Property      ServiceControllerStatus Status {get;}
StartType            Property      ServiceStartMode StartType {get;set;}
  • Les propriétés sont les informations que porte l’objet : c’est sur elles que l’on filtre, trie et sélectionne.
  • Les méthodes sont les actions qu’il sait faire.
  • La ligne TypeName indique la nature de l’objet ; c’est le mot-clé à chercher dans la documentation.

3. Filtrer : Where-Object

Where-Object (alias ?) ne laisse passer que les objets qui satisfont une condition.

# Syntaxe simple, lisible (un seul critère)
Get-Service | Where-Object Status -eq "Stopped"

# Syntaxe avec bloc de script : $_ représente l'objet en cours
Get-Process | Where-Object { $_.WorkingSet -gt 200MB }

# Plusieurs critères
Get-ChildItem C:\Windows | Where-Object { $_.Length -gt 1MB -and $_.Extension -eq ".exe" }
OpérateurSignificationExemple
-eq / -neégal / différent$_.Status -eq "Running"
-gt / -ltsupérieur / inférieur$_.CPU -gt 10
-ge / -lesupérieur ou égal / inférieur ou égal$_.Length -ge 1MB
-likecomparaison avec * et ?$_.Name -like "win*"
-matchexpression régulière$_.Name -match "^svc"
-and / -or / -notcombinaisons logiquesA -and B

PowerShell comprend les suffixes KB, MB, GB, TB : 500MB s’écrit tel quel.

4. Trier, choisir, compter

# Trier
Get-Process | Sort-Object CPU -Descending

# Choisir des colonnes, limiter le nombre de lignes
Get-Process | Sort-Object WorkingSet -Descending | Select-Object Name, Id, WorkingSet -First 5

# Propriété calculée : on renomme et on transforme
Get-Process | Select-Object Name, @{Name = "Mémoire (Mo)"; Expression = { [math]::Round($_.WorkingSet / 1MB, 1) }}

# Valeurs uniques
Get-Service | Select-Object -ExpandProperty Status -Unique
# Compter, additionner, faire une moyenne
Get-ChildItem C:\Windows -File | Measure-Object -Property Length -Sum -Average -Maximum

# Regrouper
Get-Service | Group-Object Status | Select-Object Name, Count

5. Afficher ou exploiter : une distinction essentielle

Les commandes Format-* produisent un affichage agréable mais détruisent les objets : plus rien d’exploitable ne sort derrière.

# Correct : on met en forme en toute fin de ligne
Get-Service | Where-Object Status -eq "Running" | Format-Table Name, DisplayName -AutoSize

# À éviter : le tri qui suit ne fonctionnera pas comme prévu
Get-Service | Format-Table | Sort-Object Name
CommandeUsage
Format-TableTableau en colonnes (par défaut au-delà de 4 propriétés)
Format-ListUne propriété par ligne : idéal pour tout voir d’un objet
Out-GridViewFenêtre graphique triable et filtrable (Windows PowerShell)

Astuce fréquente : Get-Service -Name Spooler | Format-List * affiche toutes les propriétés d’un objet.

6. Exporter les résultats

# Tableur : le séparateur et l'encodage comptent
Get-Service | Select-Object Name, Status, StartType |
    Export-Csv -Path "$env:USERPROFILE\Desktop\services.csv" -Delimiter ";" -Encoding UTF8 -NoTypeInformation

# Relire un CSV : on récupère de vrais objets
Import-Csv "$env:USERPROFILE\Desktop\services.csv" -Delimiter ";" | Where-Object Status -eq "Stopped"

# JSON, pratique pour les structures imbriquées
Get-Process | Select-Object Name, Id | ConvertTo-Json | Out-File proc.json -Encoding utf8

# Texte brut
Get-Date | Out-File -Append journal.txt

7. Mini-projet : le tableau de bord du poste

8. Bilan

Exercices corrigés

Construis chaque pipeline étage par étage : tape la première commande, observe, ajoute le | suivant. Si ton résultat diffère du corrigé, compare d’abord les propriétés utilisées avec Get-Member.

Exercice 1.1 — Explorer

Voir le corrigé
# 1.
Get-Process | Get-Member -MemberType Property

# 2.
Get-Process | Select-Object Name, Id

# 3.
Get-ChildItem C:\ | Get-Member
# TypeName : System.IO.DirectoryInfo et System.IO.FileInfo
# Un dossier et un fichier ne sont pas le même type d'objet :
# seul le second possède par exemple la propriété Length.

Explication

Get-ChildItem renvoie deux types d’objets car un dossier et un fichier n’ont pas les mêmes propriétés : seul FileInfo possède Length. C’est pourquoi -File ou -Directory clarifient souvent les commandes.

Exercice 1.2 — Interroger sa machine

Voir le corrigé
# 1.
Get-Service | Where-Object { $_.Status -eq "Stopped" -and $_.DisplayName -like "*Windows*" }

# 2.
Get-ChildItem C:\Windows\System32 -File |
    Sort-Object Length -Descending |
    Select-Object Name, @{Name = "Mo"; Expression = { [math]::Round($_.Length / 1MB, 2) }} -First 10

# 3.
(Get-Process).Count

# 4.
Get-Service | Group-Object Status | Select-Object Name, Count

Explication

La propriété calculée @{Name = ...; Expression = ...} sert à la fois à renommer une colonne et à transformer une valeur. Elle s’abrège en @{N = ...; E = ...}.

Pour aller plus loin

# Group-Object renvoie aussi les objets de chaque groupe
Get-Service | Group-Object Status | ForEach-Object {
    "{0} : {1} service(s)" -f $_.Name, $_.Count
}

Exercice 1.3 — Un premier inventaire

Voir le corrigé
Get-Process |
    Select-Object Name, Id, @{Name = "MemoireMo"; Expression = { [math]::Round($_.WorkingSet / 1MB, 1) }} |
    Sort-Object MemoireMo -Descending |
    Export-Csv "$env:USERPROFILE\Desktop\processus.csv" -Delimiter ";" -Encoding UTF8 -NoTypeInformation

Explication

On calcule la colonne avant le tri, ce qui permet ensuite de trier sur son nom. L’export produit un vrai fichier exploitable, pas une capture de l’affichage.

Mini-projet

Voir le corrigé
$date = Get-Date -Format "yyyy-MM-dd_HH-mm"
$fichier = "$env:USERPROFILE\Desktop\tableau-de-bord_$date.txt"

"=== Top 5 mémoire ===" | Out-File $fichier -Encoding utf8
Get-Process | Sort-Object WorkingSet -Descending |
    Select-Object Name, @{Name = "Mo"; Expression = { [math]::Round($_.WorkingSet / 1MB, 1) }} -First 5 |
    Out-File $fichier -Append -Encoding utf8

"=== Services par état ===" | Out-File $fichier -Append -Encoding utf8
Get-Service | Group-Object Status | Select-Object Name, Count | Out-File $fichier -Append -Encoding utf8

"=== Top 5 téléchargements ===" | Out-File $fichier -Append -Encoding utf8
Get-ChildItem "$env:USERPROFILE\Downloads" -File |
    Sort-Object Length -Descending |
    Select-Object Name, @{Name = "Mo"; Expression = { [math]::Round($_.Length / 1MB, 1) }} -First 5 |
    Out-File $fichier -Append -Encoding utf8

"=== Disques ===" | Out-File $fichier -Append -Encoding utf8
Get-PSDrive -PSProvider FileSystem |
    Select-Object Name, @{Name = "LibreGo"; Expression = { [math]::Round($_.Free / 1GB, 1) }} |
    Out-File $fichier -Append -Encoding utf8

Get-Content $fichier

Explication

Chaque section suit le même schéma : sélectionner, calculer, trier, limiter, écrire. Le nom de fichier horodaté évite d’écraser le relevé précédent, ce qui permet de comparer dans le temps.

Pour aller plus loin

Ce script est encore une suite de commandes. Au niveau 4, il deviendra paramétrable et journalisé ; au niveau 7, il pourra interroger plusieurs machines.

🧠 Testez vos connaissances

5 questions. Répondez puis cliquez sur « Corriger ». Rien n’est enregistré : c’est de l’auto-évaluation.

1. Que transporte le pipeline | en PowerShell ?

💬 Rien n’est perdu entre deux étages : après un filtre, toutes les propriétés restent accessibles.

2. À quoi sert Get-Member ?

💬 C’est la boussole : LaCommande | Get-Member montre sur quoi filtrer et trier.

3. Comment s’écrit « supérieur à » dans un filtre PowerShell ?

💬 Le symbole > redirige vers un fichier. Les opérateurs de comparaison s’écrivent -eq, -ne, -gt, -lt, -like…

4. Pourquoi ne faut-il pas placer Format-Table au milieu d’un pipeline ?

💬 Les commandes Format-* se placent toujours en fin de ligne, juste avant l’affichage.

5. Quels paramètres rendent un Export-Csv exploitable dans un tableur français ?

💬 Sans -NoTypeInformation, une ligne technique parasite le fichier ; sans UTF8, les accents sont illisibles.

© 2026 Bruno Jousseaume. Ce cours est publié sous licence CC BY-NC-SA 4.0 : vous pouvez le partager et l’adapter en citant l’auteur et un lien vers cette page, sans usage commercial, et en partageant vos adaptations sous la même licence.

Pour aller plus loin

Bastion Guacamole : dépanner les connexions RDP

Une démarche méthodique pour diagnostiquer une connexion RDP qui échoue à travers le bastion : journal de guacd, tableau de diagnostic, NLA et NTLM, réseau, fiche de suivi d’incident.

Avancé⏱ 1 h 30 · 8 octobre 2026