Comment faire un ping sur plusieurs machines avec PowerShell ?
Sommaire
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
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.
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 :
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 :
- 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
- Ressource : Microsoft Docs - Test-Connection
Maintenant, c'est à vous de jouer !
Excellent tutoriel, très utile!
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
?
Toujours des tutos de qualité.
Merci Florian, tu es d’une aide très précieuse.
Portes toi bien