Qu’est-ce que c’est
Cet article propose un guide complet des meilleures pratiques pour le scripting PowerShell, en mettant l’accent sur la structure du code, le formatage des sorties, la gestion des erreurs, l’optimisation des performances et les mesures de sécurité.
Pourquoi
Appliquer les meilleures pratiques en PowerShell garantit des scripts lisibles, maintenables, sécurisés et performants. Cela réduit la dette technique, améliore la collaboration et minimise les risques en environnement de production.
Comment
Conception des Outils et Contrôleurs
Décidez si vous développez un "Outil" ou un "Contrôleur"
- Outil : Fonctions/modules réutilisables.
- Contrôleur : Automatisation d’une tâche spécifique, non destiné à être réutilisé.
Rendez votre code modulaire
- Utilisez des fonctions et modules pour maximiser la réutilisabilité.
Utilisez des conventions de nommage standard
- Suivez le format Verbe-Nom avec les verbes approuvés par PowerShell (
Get-Verb
).
Standardisez les noms des paramètres
- Préférez des noms comme
$ComputerName
plutôt que des préfixes personnalisés.
Les outils doivent renvoyer des données brutes
- Fournir des données peu transformées pour plus de flexibilité.
Les contrôleurs doivent renvoyer des données formatées
- Formatez la sortie pour des rapports lisibles.
Exemple
function Get-DiskInfo {
param ([string]$ComputerName)
Get-WmiObject Win32_LogicalDisk -ComputerName $ComputerName
}
Ne réinventez pas la roue
Utilisez les cmdlets intégrés comme Test-Connection
au lieu de créer vos propres fonctions.
# Recommandé
Test-Connection $ComputerName -Quiet
Écriture des Blocs de Paramètres
Rédigez toujours l’aide
Incluez des commentaires avec .SYNOPSIS
, .DESCRIPTION
et au moins un .EXAMPLE
.
function Test-Help {
<#
.SYNOPSIS
Exemple de documentation d'aide correcte.
.EXAMPLE
Test-Help -MandatoryParameter "Exemple"
Exécute la fonction avec un paramètre obligatoire.
#>
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[Alias("MP")]
[String]$MandatoryParameter
)
}
Utilisez [CmdletBinding()]
Active les paramètres communs comme -Verbose
, -Debug
, -ErrorAction
.
Supportez -WhatIf et -Confirm
Pour les commandes qui modifient l’état, utilisez SupportsShouldProcess
.
[CmdletBinding(SupportsShouldProcess, ConfirmImpact = "Medium")]
param ([switch]$Force)
Typage fort des paramètres
Définissez toujours les types pour la clarté et la validation.
param (
[string]$Name,
[int]$Count
)
Utilisez correctement [switch]
- Par défaut, valeur
$false
. - Utilisez-le comme un booléen.
Formatage de la Sortie
Évitez Write-Host sauf nécessité
Privilégiez Write-Verbose
, Write-Debug
ou Write-Output
selon le contexte.
Utilisez Write-Progress pour indiquer l’avancement
Write-Progress -Activity "Traitement en cours" -Status "50% terminé" -PercentComplete 50
Utilisez des fichiers de format pour les objets personnalisés
Définissez des fichiers .format.ps1xml
plutôt que du formatage en ligne.
Ne retournez qu’un seul type d’objet à la fois
Employez [OutputType()]
et évitez de mélanger les types.
Meilleures Pratiques de Gestion des Erreurs
Utilisez -ErrorAction Stop avec les cmdlets
Forcez les erreurs pour les capturer via try-catch
.
try {
Get-Item "C:\CheminInvalide" -ErrorAction Stop
} catch {
Write-Warning "Élément introuvable."
}
Utilisez $ErrorActionPreference pour les opérations hors cmdlet
Passez temporairement à 'Stop'
pour les opérations sensibles.
Évitez les flags et $?
Utilisez des blocs try-catch
structurés.
Copiez $Error[0] ou $_ immédiatement dans le catch
catch {
$errorDetails = $_
Write-Error "Une erreur est survenue : $($errorDetails.Exception.Message)"
}
Optimisation des Performances
PERF-01 Mesurez les performances lorsque nécessaire
Utilisez Measure-Command
pour comparer les approches.
Measure-Command {
foreach ($item in $data) { Process-Item $item }
}
PERF-02 Trouvez l’équilibre entre performance et lisibilité
- Petites données : privilégiez la lisibilité.
- Grandes données : envisagez le streaming ou .NET.
Lisible mais moins performant :
$content = Get-Content -Path file.txt
foreach ($line in $content) {
Do-Something -Input $line
}
Optimisé :
Get-Content -Path file.txt | ForEach-Object {
Do-Something -Input $_
}
Haute performance avec .NET :
$sr = New-Object System.IO.StreamReader "file.txt"
while ($sr.Peek() -ge 0) {
$line = $sr.ReadLine()
Do-Something -Input $line
}
PERF-03 Privilégiez les constructions du langage
- Constructions (
foreach
) > Méthodes .NET > Scripts > Cmdlets/Pipeline. - Mesurez toujours avant d’optimiser.
Meilleures Pratiques de Sécurité
Utilisez toujours PSCredential pour les identifiants
Évitez les mots de passe en clair.
param (
[System.Management.Automation.PSCredential]
[System.Management.Automation.Credential()]
$Credential
)
Pour les API :
$Insecure.SetPassword($Credential.GetNetworkCredential().Password)
Utilisez SecureString pour les données sensibles
$Secure = Read-Host -Prompt "Entrez des données sécurisées" -AsSecureString
Conversion sécurisée :
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Secure)
$PlainText = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
[System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($BSTR)
Stockez les identifiants en toute sécurité
Get-Credential | Export-CliXml -Path C:\secure\cred.xml
$Credential = Import-CliXml -Path C:\secure\cred.xml
Enregistrez des chaînes cryptées
ConvertFrom-SecureString -SecureString $Secure | Out-File -Path "${Env:AppData}\secure.bin"
$Secure = Get-Content -Path "${Env:AppData}\secure.bin" | ConvertTo-SecureString
Conclusion
En suivant ces meilleures pratiques PowerShell en matière de conception, documentation, gestion des sorties, erreurs, performances et sécurité, vous pourrez créer des scripts robustes, efficaces et faciles à maintenir. Cherchez toujours à équilibrer lisibilité, performance et sécurité pour livrer des solutions d’automatisation de qualité.