tiero - Fotolia

Administration PowerShell : automatisez les processus avec des boucles While

Les boucles améliorent les scripts d'automatisation en appliquant des conditions avant que le script ne progresse. Cet article explique les concepts et offre des conseils pour éviter les boucles infinies.

PowerShell dispose de toutes les fonctionnalités de boucle que vous attendez d'un langage de programmation, mais un type particulier présente une valeur ajoutée pour les équipes responsables de l’administration et de la surveillance de l'infrastructure.

L'automatisation des tâches répétitives est une compétence essentielle pour une gestion efficace des systèmes. Lors de la rédaction d'un script d'automatisation, un administrateur utilisera très probablement une boucle lorsque le script doit attendre une condition particulière ou exécuter une tâche jusqu'à ce qu'une condition spécifique soit remplie.

Parmi les différents types de boucles disponibles dans PowerShell, la boucle while est particulièrement utile, car elle peut attendre la fin d'une séquence de déploiement d'infrastructure ou surveiller des services, réduisant ainsi la charge de travail manuelle de l'administrateur.

Cet article explique les boucles disponibles dans PowerShell, comment les utiliser dans les environnements Microsoft et comment corriger les scripts avec des boucles lorsque les choses ne fonctionnent pas comme prévu.

Quels sont les types de boucles utilisés dans PowerShell ?

Avant d'aborder le fonctionnement des boucles while dans PowerShell, il est important de comprendre quand utiliser chacune des boucles :

  • Boucle for. La boucle for est idéale pour exécuter un bloc de code un nombre particulier de fois spécifié à l'aide d'une variable de comptage.
  • Boucle foreach. La boucle foreach itère à travers un tableau et exécute du code pour chaque élément de ce tableau.
  • Boucle while. Une expression exécute en continu une section de code tant qu'une condition est évaluée comme vraie. Si la condition n'est pas vraie lors de la première vérification, le code ne s'exécute jamais.
  • Boucle do-while. La boucle do-while est similaire à la boucle while, sauf que la section de code s'exécute puis le script évalue la condition. Le code s'exécute au moins une fois, quelle que soit la condition.
  • Boucle do-until. Similaire à la boucle do-while, le code s'exécute au moins une fois, quelle que soit la condition. Une fois l'expression exécutée, la condition est évaluée. Une fois que la condition est vraie, la boucle s'arrête.

Quels sont les scénarios d'utilisation des boucles while dans PowerShell ?

Toutes les différentes boucles de PowerShell sont utiles dans des circonstances spécifiques. La boucle while est particulièrement utile lorsque vous devez exécuter plusieurs fois un code jusqu'à ce que la condition soit remplie. Contrairement à une boucle for ou foreach, le code n'a pas besoin de définir le nombre d'itérations.

Voici quelques exemples simples et généraux d'utilisation d'une boucle while :

  • Attendre qu'un événement se produise.
  • Itérer sur une section de code sans nombre défini.

Voici quelques exemples spécifiques :

  • Provisionnement de l'infrastructure. Attendre que l'infrastructure soit provisionnée avant de continuer.
  • Surveillance des services. Attendre que quelque chose démarre ou s'arrête avant d'exécuter du code.
  • Surveillance de l'état. Vérifier l'état d'une ressource jusqu'à ce qu'elle remplisse une condition spécifique avant d'exécuter du code.
  • Validation des entrées. Demander continuellement des entrées jusqu'à ce qu'elles remplissent une condition spécifique.

Quelle est la syntaxe de base d'une boucle while dans PowerShell ?

Une boucle while a une syntaxe simple par rapport aux autres boucles. Le code suivant montre la syntaxe de base d'une boucle while dans PowerShell.

while ('<condition>') {
 '<code>'
}

Pour remplir ce modèle avec un exemple simple, cela pourrait ressembler au code suivant qui exécute un exemple de compteur simple.

$x = 0
while ($x -lt 10) {
 $x++
}
$x

Voici ce qui se passe dans l'exemple de code :

1/ $x est défini sur 0.

2/ La condition de la boucle while est évaluée et renvoie $true, car 0 est inférieur à 10.

3/ $x est incrémenté ($x++), ce qui le porte à 1.

4/ Répétez les étapes 2 et 3 jusqu'à ce que $x devienne 10.

5/ La condition de la boucle while est évaluée et renvoie $false, car $x (qui vaut désormais 10) n'est plus inférieur à 10.

§/ Le code de la boucle while est ignoré et la dernière ligne est exécutée.

Provisionnez l'infrastructure à l'aide d'une boucle while

Supposons que vous travaillez sur un script pour déployer une infrastructure sur Azure et que vous souhaitez que le script attende jusqu'à ce que le déploiement soit terminé. La boucle while dans le code PowerShell suivant attend que la ressource existe avant de poursuivre le script.

New-AzContainerGroup @splat
while ((Get-AzContainerGroup -ResourceGroupName $splat.ResourceGroupName | Where-Object{$_.Name -eq $splat.Name}).Count -eq 0) {
 Start-Sleep -Seconds 10
}
# Code to execute after infra is deployed

Dans ce script, voici ce qui se passe :

1/ Une applet de commande crée l'instance de container Azure.

2/ La condition de boucle while vérifie l'instance de container.

3/ Le script vérifie s'il existe une instance de container portant le nom créé par le code et renvoie $true si l'instance est introuvable.

Si la condition de boucle while renvoie $true, le script se met en veille pendant 10 secondes.

Si la condition de la boucle while renvoie $false, le code après la boucle while est exécuté.

Surveillez l'infrastructure avec une boucle while

La surveillance est un autre scénario dans lequel il est intéressant d'utiliser une boucle while dans PowerShell. Par exemple, l'extrait de code suivant dans votre script vérifie si un service doit démarrer.

while ((Get-Service 'serviceName').Status -ne 'Running') {
 Start-Sleep -Seconds 5
}

Dans cette section du code, la boucle while s'exécute en continu jusqu'à ce que le statut du service soit Running (En cours d'exécution).

Pour vérifier si un service s'arrête et envoyer ensuite une alerte, le code pourrait définir la condition pour vérifier s'il est en cours d'exécution.

while ((Get-Service 'serviceName').Status -eq 'Running') {
 Start-Sleep -Seconds 5
}
Send-MailMessage @splat

La boucle while s'exécute en boucle jusqu'à ce que le statut du service ne soit plus Running.

Dépannez les boucles while

Il est difficile de corriger les erreurs dans les boucles while lorsqu'elles ne se comportent pas comme prévu. Comme elles n'ont pas de nombre prédéterminé d'exécutions, il est possible de créer une boucle while qui ne s'arrête jamais.

Pour éviter les boucles infinies, assurez-vous que la condition de la boucle while renvoie finalement $false. Cela semble simple, mais cela peut nécessiter des tests supplémentaires. Un bon moyen de déboguer une boucle while consiste à ajouter des instructions Write-Host ou Write-Output qui incluent des détails sur les valeurs évaluées dans l'instruction conditionnelle. Par exemple, l'exemple de déploiement d'instances de container pourrait ajouter une ligne pour afficher les instances de container actuelles.

New-AzContainerGroup @splat
while ((Get-AzContainerGroup -ResourceGroupName $splat.ResourceGroupName | Where-Object{$_.Name -eq $splat.Name}).Count -eq 0) {
 Write-Host "Container instances: $((Get-AzContainerGroup -ResourceGroupName $splat.ResourceGroupName).Name -join ', ')"
 Start-Sleep -Seconds 10
}

Une autre façon de limiter le risque d'une boucle infinie dans une boucle while consiste à implémenter un nombre maximal de boucles dans le script. Par exemple, après avoir déployé une ressource sur Azure, il est raisonnable de supposer que les ressources devraient être déployées en quelques minutes. Ajoutez une variable de comptage et limitez sa valeur maximale à 120 dans le script.

$counter = 0
New-AzContainerGroup @splat
while ((Get-AzContainerGroup -ResourceGroupName $splat.ResourceGroupName | Where-Object{$_.Name -eq $splat.Name}).Count -eq 0) {
 $counter++
 if ($counter -ge 120) {
 Throw 'Deployment has taken longer than 20 minutes.'
 }
 Start-Sleep -Seconds 10
}
# Code to execute after infra is deployed

L'exemple utilise une instruction if à l'intérieur de la boucle while au lieu de l'inclure dans la condition pour montrer que le script se termine parce que $counter est supérieur à 120. L'utilisation de Throw interrompt le script à ce stade au lieu de le poursuivre.

Une autre façon d'utiliser un compteur dans une boucle while consiste à écrire périodiquement des données en sortie. Par exemple, dans le script de surveillance des services, un compteur et une instruction if peuvent être utilisés pour écrire périodiquement dans un fichier journal afin d'indiquer à l'administrateur que le script est toujours en cours d'exécution.

$counter = 0
while ((Get-Service 'serviceName').Status -eq 'Running') {
 $counter++
 if ($counter % 60 -eq 0) {
 'serviceName is still running...' | Out-file $logPath -Append
 }
 Start-Sleep -Seconds 5
}
Send-MailMessage @splat

Le script utilise l'opérateur modulo (%) pour vérifier si le compteur est divisible par 60. Si c'est le cas, le script écrit une entrée dans le journal. La sortie se produit toutes les 60 itérations, soit un peu plus d'une fois toutes les cinq minutes.

Pour approfondir sur Administration de systèmes