Comment ajouter une barre de progression dans un script PowerShell ?
Sommaire
I. Présentation
Dans ce tutoriel, nous allons apprendre à ajouter une barre de progression, appelée aussi "Progress Bar", à un script PowerShell ! La barre de progression va permettre de suivre l'avancement de l'exécution d'un script PowerShell, ce qui s'avère pratique lorsque le script doit traiter un grand nombre d'éléments. Nous pourrions presque dire que ceci va améliorer l'expérience utilisateur grâce à l'affichage d'informations sur l'état d'avancement.
Si vous souhaitez apprendre PowerShell, découvrez notre cours complet :
Vous pouvez aussi retrouver mon livre PowerShell sur Amazon.
II. Le cmdlet Write-Progress de PowerShell
PowerShell intègre le cmdlet "Write-Progress" pour créer des barres de progression personnalisées dans les scripts. Pour utiliser ce cmdlet, nous allons configurer plusieurs de ses paramètres :
- -PercentComplete : spécifier le pourcentage d'avancement de la tâche, ce qui implique de réaliser un calcul pour retourner une information précise.
- -Activity : indique la tâche en cours, avec des informations plus précises.
- -Status : indique la tâche en cours.
Nous avons donc deux paramètres pour gérer les informations affichées à l'écran, ainsi qu'un paramètre pour calculer le pourcentage d'avancement. Ce dernier paramètre est important, car c'est lui qui joue directement sur la barre de progression visible à l'écran.
Il existe d'autres paramètres pour le cmdlet "Write-Progress". En complément de ce tutoriel, vous pouvez consulter la page d'aide sur le site de Microsoft :
III. Créer sa première barre de progression
Pour nous familiariser avec le principe de la barre de progression, nous allons commencer par un exemple très basique pour mettre en pratique le cmdlet "Write-Progress".
Dans cet exemple, nous avons une boucle "for" qui s'exécute 10 fois, avec une pause de 1 seconde entre chaque itération (ceci simule une tâche). Ceci permet de temporiser et de voir facilement la progressivement du traitement. Le calcul "($i/10*100)" sert à calculer un pourcentage cohérent.
for ($i = 1 ; $i -le 10 ; $i++) {
Write-Progress -Activity "Traitement en cours" -Status "$($i/10*100)% effectué" -PercentComplete ($i/10*100)
Start-Sleep -Seconds 1
}
Ce bout de code donne le résultat suivant (cliquez sur l'image pour voir l'animation) :
Nous pouvons voir qu'il y a une réelle cohérence entre le pourcentage indiqué et l'avancement de la tâche. C'est la principale difficulté lors de la création d'une barre de progression.
IV. Suivi d'une tâche avec Write-Progress
Nous pouvons utiliser une barre de progression pour suivre l'évolution d'une tâche, sans pour autant indiquer un pourcentage de progression (bien qu'il sera calculé pour que la progression soit cohérente). À la place, nous allons indiquer le nombre total d'éléments à traiter et le nombre d'éléments déjà traités.
L'exemple ci-dessous sert à parcourir une liste d'identifiants définie dans un tableau (variable "ListeDesIdentifiants") à l'aide d'une boucle "Foreach". Nous pourrions exploiter cette liste pour créer des comptes utilisateurs, etc... L'important ici, c'est surtout de voir la mécanique pour la barre de progression.
Voici le code complet :
# Liste des identifiants
$ListeDesIdentifiants = @("florian.burnel","guy.mauve","gerard.mensoif","jeanmichel.diledefrance")
# Nombre total d'identifiants à traiter
$ListeDesIdentifiantsCount = $ListeDesIdentifiants.Count
# Compteur d'identifiant traité
$NbIdentifiantsTraites = 1
# Traiter chaque identifiant grâce à une boucle
foreach($Identifiant in $ListeDesIdentifiants) {
Write-Progress -PercentComplete ($NbIdentifiantsTraites/$ListeDesIdentifiantsCount*100) -Status "Création des comptes en cours" -Activity "Identifiants traités : $NbIdentifiantsTraites sur $ListeDesIdentifiantsCount"
# Actions pour chaque compte
# New-LocalUser...
# New-ADUser...
Start-Sleep -Seconds 1
# Incrémenter le nombre de comptes traités
$NbIdentifiantsTraites++
}
Nous gérons deux valeurs importantes pour calculer la progression :
- Le nombre total d'éléments à traiter, stocké dans la variable "ListeDesIdentifiantsCount" et récupéré via la propriété "Count".
- Le nombre d'éléments déjà traités, afin de suivre de la progression. Cette valeur est stockée dans la variable "NbIdentifiantsTraites". Elle est incrémentée de 1 à chaque itération de la boucle.
Voici le résultat obtenu (cliquez sur l'image pour voir l'animation) :
Enfin, voici un autre exemple où nous assurons le suivi d'un téléchargement de plusieurs fichiers en utilisant la barre de progression pour afficher le nom du fichier en cours de téléchargement. Ici, une boucle "For" est utilisée pour parcourir la liste de fichiers, mais nous pourrions utiliser une boucle "Foreach".
# Liste des fichiers à télécharger
$ListeDesFichiers = @("Archive1.zip", "Archive2.zip", "Document1.zip")
for ($i = 0 ; $i -lt $ListeDesFichiers.Length ; $i++) {
$Fichier = $ListeDesFichiers[$i]
Write-Progress -Activity "Téléchargement de fichiers" -Status "Téléchargement de $Fichier " -PercentComplete (($i + 1) / $ListeDesFichiers.Length * 100)
# Action de téléchargement (simulé ici)
# Invoke-WebRequest...
Start-Sleep -Seconds 1
}
Write-Host "Téléchargement des fichiers terminé !"
Voici le résultat en image (cliquez sur l'image pour voir l'animation) :
V. Gérer la progression avec des étapes fixes
Le calcul du pourcentage n'est pas obligatoire si vous désirez simplement suivre le déroulement de vos scripts à partir d'étapes clés définies de façon statique. Si vous avez un script qui effectue des actions réparties dans 4 grandes étapes et que vous souhaitez simplement savoir à quelle étape il en est, le cmdlet "Write-Progress" peut tout à fait être utilisé.
Write-Progress -Activity "Tâche n°1 : <description>" -Status "Tâche 1 sur 4" -PercentComplete 25
# Opération à effectuer... (pause de 1 seconde)
Start-Sleep -Seconds 1
Write-Progress -Activity "Tâche n°2 : <description>" -Status "Tâche 2 sur 4" -PercentComplete 50
# Opération à effectuer... (pause de 1 seconde)
Start-Sleep -Seconds 1
Write-Progress -Activity "Tâche n°3 : <description>" -Status "Tâche 3 sur 4" -PercentComplete 75
# Opération à effectuer... (pause de 1 seconde)
Start-Sleep -Seconds 1
Write-Progress -Activity "Tâche n°4 : <description>" -Status "Tâche 4 sur 4" -PercentComplete 100
# Opération à effectuer... (pause de 1 seconde)
Start-Sleep -Seconds 1
Nous obtenons le résultat suivant (cliquez sur l'image pour voir l'animation) :
VI. Gérer une interruption dans la progression
Nous pouvons personnaliser les messages affichés en modifiant la valeur des paramètres "-Activity" et "-Status" du cmdlet "Write-Progress". Ceci peut être utile pour gérer une interruption dans le traitement et en avertir l'utilisateur.
Voici un exemple où nous simulons une interruption de la tâche à 50%, avant de reprendre 2 secondes plus tard. Donc, en pratique, la barre de progression affichera un message d'interruption avant de reprendre la tâche et d'en informer l'utilisateur. Cette technique peut être utile pour informer l'utilisateur de moment de pause ou d'attente pendant l'exécution du traitement.
for ($i = 1; $i -le 100; $i++) {
if ($i -eq 50) {
Write-Progress -Activity "Interruption" -Status "Tâche interrompue à 50%" -PercentComplete $i
Start-Sleep -Seconds 2
Write-Progress -Activity "Reprise" -Status "Reprise de la tâche" -PercentComplete $i
} else {
Write-Progress -Activity "Traitement en cours" -Status "$i% complété" -PercentComplete $i
}
Start-Sleep -Milliseconds 50
}
VII. Conclusion
Nous venons de voir comment utiliser le cmdlet "Write-Progress" pour créer des barres de progression avec PowerShell. Il y a différents scénarios possibles, en fonction des besoins et des scénarios d'usage. Mais, une barre de progression, cela fait toujours son petit effet lors de l'exécution d'un script PowerShell en plus d'apporter un suivi précis (et précieux).
Il est possible d'aller plus loin en déclaration plusieurs barres de progression pour gérer la progression globale et la progression d'une sous-tâche. Ceci revient à utiliser deux fois "Write-Progress" et à jouer sur le calcul du paramètre "-PercentComplete" pour calculer le pourcentage de la sous-tâche. Nous pourrions aussi utiliser le paramètre "-SecondsRemaining" pour préciser le nombre de secondes restantes avant la fin du traitement, mais là encore ceci implique des calculs (notamment en s'appuyant sur le temps d'exécution moyen des précédents éléments pour donner une estimation).
merci, c’est utile ce truc
Merci, c’est très intéressant