Pinger une liste de machines rapidement en Powershell

Description

Bonjour,

Tout d’abord vous pouvez récupérer le pdf de cette explication : PDF

Beaucoup de personnes sont amenées à vouloir effectuer des requêtes ICMP sur des centaines voire des milliers de machines. Pour cela, nous pouvons utiliser des scripts Powershell. Cependant, il existe plusieurs méthodes plus ou moins rapide. Lors de ce tutoriel nous allons comparer deux méthodes pour « pinger » des machines. Vous serez très surpris par les différences de performances entre les deux méthodes. La première sera une méthode classique et pour la seconde, nous utiliserons les workflows sous Powershell.

Méthode Classique

Lorsque nous souhaitons tester un ensemble de machine voici la méthode classique utilisée :

function Test-Computer{
 
param(
 
[parameter(Position=0, Mandatory=$true, Helpmessage="Hostname")]$hostname
 
)
 
foreach($item in $hostname)
{
 
$state = Test-Connection -ComputerName $item -count 1 -Quiet
 
$objet = New-Object PSObject -property @{
 
Hostname = $item
State = $state
 
}
 
$objet
 
}

Cette fonction simple sans contrôle des erreurs prend en paramètre une machine ou une liste de machine. Ensuite, un « Test-Connection » est effectué sur la ou les machines en questions. Enfin, nous retournons un objet contenant le nom de la machine et son état afin de savoir si elle répond ou pas à l’icmp. Nous allons tester cette fonction avec une extraction de machine de l’Active Directory.

$list = (Get-ADComputer -filter * | select -first 100).name
 
Measure-command -expression {Test-Computer $list}

Afin d’améliorer la compréhension, nous avons volontairement décomposé les étapes. Nous avons donc une requête sur l’Active Directory pour récupérer une liste de 100 machines. Cette liste est ensuite passée en paramètre à notre fonction. La cmdlet « Measure-Command » va nous permettre de mesurer le temps d’exécution complet.

Resultat Méthode classique

Le temps d’exécution de notre fonction est de 3 minutes et 19 secondes. C’est-à-dire que notre fonction à mis 3 minutes et 19 secondes pour tester une requête icmp sur l’ensemble des machines figurant dans notre liste qui est passée en paramètre. Nous allons maintenant utiliser notre seconde méthode et nous comparerons les résultats.

Workflows

Les Workflows sont apparues avec Windows Powershell 3.0. Ils vont nous permettre d’effectuer des traitements en séquence ou en parallèle sur une multitude de serveurs. Les workflows supportent aussi les redémarrages et les déconnexions. Voici la même fonction que la précédente à l’exception que celle-ci est faîte à partir d’un workflow.

workflow Test-WComputer{
 
param(
 
    [parameter(Position=0, Mandatory=$true, Helpmessage="Hostname")]$hostname
 
)
 
foreach -parallel ($item in $hostname)
{
   $state = Test-Connection -ComputerName $item -count 1 -Quiet
 
   $objet = New-Object PSObject -property @{
 
    Hostname = $item
    State = $state
 
   }
 
  $objet       
 
}
 
}

Le plus important est l’utilisation du mot clé « Workflow ». Grâce à celui-ci nous nous trouvons dans le contexte d’un workflow. Ainsi, lors de notre itération « foreach », nous utilisons le paramètre « -parallel ». Ce paramètre comme son nom l’indique va permettre d’effectuer un traitement en parallèle. Dans notre exemple, plusieurs machines seront testées en même temps alors que précédemment la boucle parcourait la liste puis testait les machines l’une après l’autre. Nous lançons notre Workflow :

$list = (Get-ADComputer -filter * | select -first 100).name

Measure-command -expression {Test-WComputer $list}

Comme précédemment nous récupérons une liste de 100 machines de notre Active Directory que nous passons en paramètre à notre workflow.

Résultat Workflow

Pour le même traitement que dans notre méthode classique, nous passons de 3 minutes à 9 secondes !!!!

Méfiez-vous cependant par moment car les workflows sont plus consommateurs de ressources que les méthodes classiques.

Merci d’avoir suivi ce comparatif.