Introduction
PowerShell, le shell objet de Microsoft, révolutionne l'automatisation sur Windows et cross-platform depuis PowerShell 7. En 2026, avec l'essor de l'IA et des environnements hybrides, maîtriser ses cmdlets avancés, pipelines objets et jobs parallèles est essentiel pour les DevOps et sysadmins. Ce tutoriel intermédiaire vous guide pas à pas pour créer des scripts robustes : de la gestion des services à l'export de données via WMI, en passant par les fonctions paramétrées et la gestion d'erreurs.
Pourquoi c'est crucial ? Un script PowerShell bien écrit peut remplacer des heures de clics manuels, scaler sur Azure ou AWS, et intégrer des pipelines CI/CD. Imaginez monitorer 100 serveurs en parallèle sans sueur. Nous partons de scripts fonctionnels basiques vers des automatisations complexes, avec du code 100% copier-collable. À la fin, vous bookmarkederez ce guide comme référence pro. (128 mots)
Prérequis
- PowerShell 7.4+ installé (via winget ou Microsoft Store)
- Connaissances de base en scripting (variables, boucles)
- Windows 10/11 ou Server 2022 (cross-platform compatible)
- Éditeur : VS Code avec extension PowerShell
- Droits admin pour certains exemples (services, WMI)
Script de base : Lister et filtrer les processus
param(
[string]$NomProcessus = '*'
)
$processus = Get-Process | Where-Object { $_.ProcessName -like $NomProcessus }
if ($processus.Count -eq 0) {
Write-Warning "Aucun processus trouvé pour '$NomProcessus'"
} else {
$processus | Select-Object Name, Id, CPU, WorkingSet | Format-Table -AutoSize
Write-Output "Trouvé $($processus.Count) processus."
}Ce script paramétré utilise Get-Process et Where-Object pour filtrer dynamiquement les processus. Le pipeline objet PowerShell permet de chaîner sans parsing string, contrairement à bash. Piège : toujours vérifier Count pour éviter les faux positifs ; utilisez Format-Table pour une sortie lisible.
Comprendre les pipelines objets
Contrairement aux shells textuels, PowerShell passe des objets .NET dans les pipelines, préservant métadonnées (propriétés comme CPU). Cela permet des filtres intelligents avec Where-Object et Select-Object. Analogie : comme un convoyeur d'objets manufacturés, pas de chaînes de texte à découper.
Fonction avancée : Gérer les services Windows
function Invoke-ServiceAction {
param(
[Parameter(Mandatory=$true)]
[string]$NomService,
[ValidateSet('Start', 'Stop', 'Restart')]
[string]$Action
)
$service = Get-Service -Name $NomService -ErrorAction SilentlyContinue
if (-not $service) {
throw "Service '$NomService' introuvable."
}
switch ($Action) {
'Start' { $service | Start-Service }
'Stop' { $service | Stop-Service }
'Restart' { $service | Restart-Service }
}
Write-Output "Service '$NomService' $Action avec succès. Statut : $($service.Status)."
}
# Exemple d'usage
Invoke-ServiceAction -NomService 'Spooler' -Action 'Restart'Cette fonction encapsule les cmdlets Get-Service/Start-Service avec validation stricte via ValidateSet. Le switch optimise les actions. Piège : utilisez -ErrorAction pour éviter les crashes ; Mandatory force les params essentiels, rendant le script réutilisable comme module.
Gestion des paramètres et validation
Les param() avec attributs comme Mandatory et ValidateSet rendent les scripts professionnels. Cela prévient les erreurs runtime et améliore l'autocomplétion dans VS Code.
Gestion d'erreurs avec Try-Catch
try {
$fichier = Get-Content 'C:\non-existent.txt' -ErrorAction Stop
} catch [System.Management.Automation.ItemNotFoundException] {
Write-Error "Fichier non trouvé. Création automatique..."
New-Item -Path 'C:\non-existent.txt' -ItemType File -Force | Out-Null
} catch {
Write-Error "Erreur inattendue : $($_.Exception.Message)"
exit 1
} finally {
Write-Output "Nettoyage terminé."
}
# Test spécifique
$user = Get-LocalUser 'NonExistant' -ErrorAction Stop
Write-Output $user.NameTry-Catch-Finally gère les exceptions spécifiques (.NET types) pour une résilience pro. -ErrorAction Stop convertit les erreurs non-terminantes en exceptions. Piège : toujours inclure un catch générique ; finally pour cleanup garanti, critique en prod.
Jobs parallèles pour scalabilité
Start-Job exécute en arrière-plan, idéal pour monitorer plusieurs machines. Receive-Job récupère les résultats. Analogie : comme des threads asynchrones sans blocage.
Jobs asynchrones : Monitorer disques multiples
$jobs = @()
1..3 | ForEach-Object {
$job = Start-Job -ScriptBlock {
param($drive)
Get-WmiObject -Class Win32_LogicalDisk -Filter "DeviceID='$drive'" | Select-Object DeviceID, Size, FreeSpace
} -ArgumentList "C:`$"
$jobs += $job
}
$jobs | Wait-Job | Receive-Job
$jobs | Remove-Job
Write-Output "Monitoring terminé."Boucle ForEach-Object lance 3 jobs WMI parallèles sur disques. Wait-Job synchronise, Receive-Job extrait objets. Piège : passez args via -ArgumentList ; nettoyez avec Remove-Job pour éviter fuites mémoire en boucle infinie.
Module custom : Exporter rapports CSV
function Export-SystemReport {
param([string]$CheminSortie = 'rapport.csv')
$rapport = [PSCustomObject]@{
HostName = $env:COMPUTERNAME
OS = (Get-CimInstance Win32_OperatingSystem).Caption
Processes = (Get-Process).Count
Disques = (Get-WmiObject Win32_LogicalDisk).Count
}
$rapport | Export-Csv -Path $CheminSortie -NoTypeInformation -Encoding UTF8
Write-Output "Rapport exporté vers $CheminSortie"
}
Export-SystemReport -CheminSortie 'C:\rapport-$(Get-Date -Format "yyyyMMdd").csv'PSCustomObject crée objets structurés pour Export-Csv propre. CimInstance/WMI pour infos système. Piège : -NoTypeInformation évite headers inutiles ; UTF8 pour accents FR ; nom fichier dynamique avec Get-Date.
Bonnes pratiques
- Toujours utiliser des objets : Évitez Out-String sauf logs.
- Validez params : Mandatory, ValidateSet pour UX pro.
- Gestion erreurs complète : Try-Catch + ErrorAction Stop.
- Modularisez : Fonctions > scripts linéaires ; publiez comme modules.
- Sécurisez : ExecutionPolicy RemoteSigned ; ne pas hardcoder creds.
Erreurs courantes à éviter
- Oublier -ErrorAction Stop : Erreurs silencieuses en try-catch.
- Pipelines string vs objet : Perte propriétés avec | Out-String.
- Jobs orphelins : Memory leak sans Remove-Job.
- Ignorer ExecutionPolicy : Bloque scripts ; set via Set-ExecutionPolicy.
Pour aller plus loin
Plongez dans Desired State Configuration (DSC) pour infra as code, ou PSGraph pour visualiser pipelines. Intégrez à Azure DevOps. Découvrez nos formations Learni sur PowerShell et DevOps. Docs officielles : PowerShell Gallery.