15/07/2024

PowerShell

Comment faire un ping sur plusieurs machines avec PowerShell ?

I. Présentation

Dans ce tutoriel, nous allons voir comment faire un ping sur plusieurs machines à l'aide d'un script PowerShell : un bon moyen de voir quelles sont les machines en ligne ou hors ligne.

Lorsque l'on cherche à savoir si plusieurs machines, que ce soit des serveurs ou des postes de travail, sont en ligne, on effectue bien souvent un "ping". Si la machine répond, on sait qu'elle est joignable au travers du réseau : ce qui est bon point de départ pour communiquer avec elle.

Plutôt que de faire les ping un par un en modifiant le nom (ou l'adresse IP) de la machine à chaque fois, on peut s'appuyer sur un script PowerShell pour pinger facilement plusieurs machines (ou équipements, d'ailleurs).

Ce qu'il faut, c'est simplement une liste de machines. Pour constituer cette liste de machines, on peut s'appuyer sur l'annuaire Active Directory, sur un fichier CSV, etc... Je pense que les deux exemples que je viens de citer sont assez courants.

II. Découverte de Test-Connection

Vous connaissez tous la commande "ping" accessible depuis très longtemps, bien avant que PowerShell pointe le bout de son nez. Cette commande s'appuie sur le protocole ICMP, et avec PowerShell, on peut effectuer un équivalent avec la commande Test-Connection.

Concrètement, elle s'utilise de la même façon : on précise le nom de la commande et l'hôte à contacter. Par exemple :

Test-Connection 192.168.100.1

ou encore :

Test-Connection MonServeur1

Par défaut, 4 ping sont effectués, mais on peut en effectuer un seul en précisant l'option -Count avec la valeur 1.

Test-Connection 192.168.100.1 -Count 1

Un seul ping, c'est suffisant si l'on cherche seulement à savoir si la machine est en ligne ou non. La commande retourne plusieurs informations : hôte source (ici, le serveur SRV-ADDS-01 que j'utilise pour la démo), hôte destination, IPv4 et IPv6 de l'hôte distant, ainsi que le temps de réponse. Là encore, on pourrait ajouter un paramètre pour retourner seulement un booléen (True ou False) en fonction du résultat :

Test-Connection 192.168.100.1 -Count 1 -Quiet

PowerShell Test-Connection

Nous avons notre commande "ping" en PowerShell, voyons maintenant comment pinger plusieurs machines. Je dois vous avouer que la commande Test-Connection est capable d'accepter plusieurs machines en paramètres. Par exemple :

Test-Connection 192.168.100.1,192.168.100.2,192.168.100.3

Elle va pinger les machines tour à tour et afficher une sortie avec le résultat. Avec Windows PowerShell 5.1, lorsqu'une adresse IP est injoignable, on obtient un message d'erreur dans la console.

Test-Connection avec Windows PowerShell
Test-Connection avec Windows PowerShell

Par contre, avec PowerShell 7, c'est mieux géré puisque l'on a le statut TimedOut lorsque l'hôte distant n'est pas joignable. Ce qui donne :

Test-Connection avec PowerShell 7

Maintenant, creusons un peu plus le sujet du "multiple ping" avec PowerShell.

III. Pinger plusieurs machines avec PowerShell

Pour constituer notre liste d'ordinateurs à pinger, on va s'appuyer sur l'annuaire Active Directory. Au sein de la variable $ComputersList, nous allons stocker l'ensemble des ordinateurs de l'Active Directory en conservant seulement l'attribut "name". Bien sûr, vous pouvez ajouter un filtre ou prendre une OU de référence pour la recherche (-SearchBase).

$ComputersList = (Get-ADComputer -Filter *).Name

Pour exploiter cette liste, nous avons plusieurs choix :

  • Utiliser Test-Connection et lui envoyer le contenu de notre variable $ComputersList
  • Utiliser une boucle Foreach pour parcourir $ComputersList et effectuer un ping vers chaque hôte

Pour la première option, cela donne tout simplement la commande suivante (de préférence à exécuter avec PowerShell 7+ pour avoir une sortie propre) :

Test-Connection $ComputersList -Count 1

Ce qui fonctionne plutôt bien comme vous pouvez le voir sur l'image suivante :

Concernant la seconde méthode, basée sur une boucle Foreach, elle va permettre d'agir en fonction de l'état de chaque poste. Par exemple, si le poste est en ligne on pourrait imaginer exécuter une action sur le poste, tandis que s'il est hors ligne, on ne fait rien.

Pour cet exemple, je vais me contenter d'indiquer l'état du PC dans la console PowerShell : en ligne ou hors ligne. Dans le cas où le poste est en ligne, on précisera l'adresse IP associée en complément.

Note : dans le script ci-dessous, la variable $Ping contient le résultat du ping pour l'hôte en cours de traitement.

Puisque Windows PowerShell et PowerShell fonctionne différemment lors de l'utilisation de Test-Connection, notamment lorsqu'un hôte est injoignable, le script va être différent entre ces deux versions.

  • Windows PowerShell
$ComputersList = (Get-ADComputer -Filter *).Name

foreach($Computer in $ComputersList){

   $Ping = Test-Connection -ComputerName $Computer -Count 1 -ErrorAction SilentlyContinue
   if($Ping) {
       Write-Host "$Computer (adresse IP : $($Ping.IPV4Address)) : en ligne" -ForegroundColor Green 
   }else {
       Write-Host "$Computer : hors ligne" -ForegroundColor Red
   } 
}

En exécutant ce script, on obtient un état pour chaque machine de la liste :

Pinger plusieurs machines avec PowerShell

  • PowerShell Core / PowerShell 7+

Avec PowerShell Core, si l'on veut obtenir le même style de résultat, il faut réaliser quelques adaptations dans le script. Tout d'abord, si l'on vérifie l'état de $ping, il y aura un retour si l'hôte est injoignable (TimedOut) contrairement à Windows PowerShell qui retourne une erreur, donc cela va générer de faux positifs. Avec PowerShell Core, il y a une erreur seulement quand le nom d'hôte ne peut pas être résolu.

Ensuite, la propriété "IPv4Address" qui permet de récupérer l'adresse IP de l'hôte de destination n'existe plus. En fait, elle est remplacée par "DisplayAddress".

Ce qui donne un bout de code légèrement différent :

$ComputersList = (Get-ADComputer -Filter *).Name

foreach($Computer in $ComputersList){

   $Ping = Test-Connection -ComputerName $Computer -Count 1 -ErrorAction SilentlyContinue
   if($Ping.Status -eq "Success") {
       Write-Host "$Computer (adresse IP : $($Ping.DisplayAddress)) : en ligne" -ForegroundColor Green 
   }else {
       Write-Host "$Computer : hors ligne" -ForegroundColor Red
   } 
}

Dans la console par contre, on peut s'attendre à un résultat équivalent.

Voilà, nous venons de réaliser un ping sur plusieurs machines avec PowerShell ! Comme je le disais, la liste de la variable $ComputersList peut être constituée de différentes façons. Par exemple, on peut constituer une liste en dur :

$ComputersList = @("srv-apps","1.1.1.1")

Dans le même esprit, on peut exploiter un fichier CSV que l'on va importer dans le script. Il faudra penser à sélectionner la colonne correspondant aux noms des machines (la colonne "name" dans l'exemple ci-dessous).

$ComputersList = (Import-Csv -Path "C:\Temp\machines.csv" -Delimiter ";").Name

Maintenant, c'est à vous de jouer !

author avatar
Florian BURNEL Co-founder of IT-Connect
Ingénieur système et réseau, cofondateur d'IT-Connect et Microsoft MVP "Cloud and Datacenter Management". Je souhaite partager mon expérience et mes découvertes au travers de mes articles. Généraliste avec une attirance particulière pour les solutions Microsoft et le scripting. Bonne lecture.
Partagez cet article Partager sur Twitter Partager sur Facebook Partager sur Linkedin Envoyer par mail

3 commentaires sur “Comment faire un ping sur plusieurs machines avec PowerShell ?

    • Bonjour J’ai adoré votre tutoriel !!
      J’ai réussi a le comprendre et a l’exécuter comme je le voulais pour mon travail, mais !
      J’aimerais savoir si il est possible d’utiliser un tableau a deux colonnes !
      J’utilise un Excel en CSV, avec un colonne A [Nom] et la colonne B [IP]
      Je m’explique,
      Je voudrais faire afficher le nom des machines devant chaque test :
      Exemple :
      198 : hors ligne
      250 : en ligne adresse ip 10.0.1.50

      Donc a la place de mettre :
      -Write-Host « $IP (Adresse IP : $($ping.DisplayAdresse)) : en ligne » -ForegroundColor Green

      Pourrais je marquer :

      -Write-Host « $Nom (Adresse IP : $($ping.DisplayAdresse)) : en ligne » -ForegroundColor Green

      ?

      Répondre
  • Toujours des tutos de qualité.
    Merci Florian, tu es d’une aide très précieuse.
    Portes toi bien

    Répondre

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.