Gestion des sessions PowerShell
Jusqu'à présent, nous avons vu comment établir une connexion PowerShell distante entre deux machines avec les commandes Enter-PSSession et Invoke-Command. Dans ces deux cas, nous avons spécifié le nom de l'ordinateur, ainsi que les informations d'identification nécessaires pour se connecter. Dans un environnement plus complexe, il aurait également pu être nécessaire de spécifier un port différent ou d'autres paramètres de connexion.
Dans un environnement réel, il est souvent nécessaire de gérer plusieurs sessions simultanément, surtout lorsqu'on administre plusieurs serveurs. Ainsi, se connecter avec Enter-PSSession ou Invoke-Command à chaque fois peut devenir fastidieux. C'est là qu'intervient la gestion des sessions PowerShell.
Nous allons voir comment créer et gérer des sessions PowerShell persistantes, ce qui nous permettra de réutiliser une connexion existante pour exécuter plusieurs commandes sur le même ordinateur distant. En français, selon le Larousse, "persistant" signifie "Qui dure longtemps, continue malgré les obstacles". Dans le contexte des sessions PowerShell, une session persistante est une connexion qui reste active entre plusieurs commandes, contrairement à une connexion éphémère qui se termine après l'exécution d'une commande. Le mot "persistant" est souvent utilisé en informatique pour décrire des données ou des connexions qui survivent au-delà de la durée de vie d'un processus ou d'une session utilisateur. Par exemple, nous parlons de stockage persistant pour désigner des données qui sont conservées même après la fermeture d'une application ou le redémarrage d'un système.
Création et gestion des sessions PowerShell
Pour créer une session PowerShell, nous utilisons la commande New-PSSession. Cette commande établit une session distante sécurisée avec un ordinateur distant et retourne un objet de session que nous pouvons utiliser pour exécuter des commandes à distance.
Pour créer une session vers CLIENT-01 et une autre vers localhost, nous utilisons la commande suivante depuis DC-01 :
$sessions = New-PSSession -ComputerName CLIENT-01, localhost -Credential (Get-Credential)
En exécutant cette commande, vous serez invité à entrer les informations d'identification d'un utilisateur ayant les droits nécessaires sur CLIENT-01 et localhost. La variable $sessions contient maintenant une collection d'objets de session, chacun représentant une connexion à un ordinateur distant.
Pour en avoir le coeur net, vous pouvez exécuter 'Get-Member' sur la variable $sessions :
$sessions | Get-Member
Vous devriez voir que $sessions est un tableau d'objets de type PSSession. Nous pouvons également voir toutes les méthodes et propriétés disponibles pour ces objets, entre autres la propriété ComputerName qui indique le nom de l'ordinateur distant.
La variable $sessions contient toutes les sessions que nous avons créées. Nous pouvons accéder à une session spécifique en utilisant son index dans le tableau. Par exemple, pour accéder à la première session (vers CLIENT-01), nous utilisons $sessions[0], et pour la deuxième session (vers localhost), nous utilisons $sessions[1]. Cependant, il est souvent plus pratique d'utiliser la commande Where-Object pour filtrer les sessions en fonction de critères spécifiques, comme le nom de l'ordinateur.
Une autre façon d'accéder à une session spécifique est d'utiliser la commande Get-PSSession avec le paramètre -ComputerName. Par exemple, pour obtenir la session vers CLIENT-01, nous utilisons :
$sessionClient01 = Get-PSSession -ComputerName CLIENT-01
Une fois que nous avons une session, nous pouvons exécuter des commandes à distance en utilisant Invoke-Command avec le paramètre -Session. Par exemple, pour obtenir la liste des services en cours d'exécution sur CLIENT-01, nous utilisons :
Invoke-Command -Session $sessionClient01 -ScriptBlock { Get-Service | Where-Object {$_.Status -eq 'Running'} }
Détaillons cette commande :
Invoke-Command: La commande utilisée pour exécuter des scripts ou des commandes à distance.-Session $sessionClient01: Spécifie la session distante dans laquelle exécuter la commande.-ScriptBlock { ... }: Définit le bloc de script à exécuter sur la machine distante. Dans ce cas, nous utilisonsGet-Servicepour obtenir la liste des services, puisWhere-Objectpour filtrer ceux qui sont en cours d'exécution.
Persistance des variables
Tel que mentionné, un des avantages des sessions PowerShell est la persistance de l'état entre les commandes. Pour illustrer cela, nous allons créer une variable dans une session distante et vérifier qu'elle est toujours accessible lors d'une commande ultérieure.
Depuis DC-01, nous allons entrer dans la session vers CLIENT-01 et créer une variable $maVariable :
$sessionClient01 = Get-PSSession -ComputerName CLIENT-01
Invoke-Command -Session $sessionClient01 -ScriptBlock {
$count = 0
"Init:$count"
}
Ici, dans la session ouverte vers CLIENT-01, nous avons initialisé une variable $count à 0 et affiché sa valeur. Maintenant, si nous exécutons une autre commande dans la même session, nous pouvons accéder à cette variable :
Invoke-Command -Session $sessionClient01 -ScriptBlock {
$count++
"Variable incrémentée :$count"
}
Nous voyons ici que la variable $count a "survécu" entre les deux commandes. Vous pouvez exécuter cette commande plusieurs fois, et à chaque fois, la variable $count sera incrémentée.
En résumé, utiliser New-PSSession pour créer des sessions persistantes, puis Invoke-Command avec le paramètre -Session pour exécuter des commandes dans ces sessions, permet de conserver une seule connexion par ordinateur et de maintenir l'état entre les commandes. Cela rend la gestion des tâches d'administration à distance plus efficace et plus pratique.
Il ne faut pas oublier de fermer les sessions ouvertes une fois que vous avez terminé, afin de libérer les ressources. Pour fermer une session, utilisez la commande Remove-PSSession :
Remove-PSSession -Session $sessionClient01
Différences de performance
L'utilisation de sessions persistantes avec New-PSSession et Invoke-Command -Session est généralement plus performante que d'utiliser Enter-PSSession ou Invoke-Command sans session, surtout lorsque vous devez exécuter plusieurs commandes sur le même ordinateur distant. En effet, chaque appel à Invoke-Command sans session crée une nouvelle connexion, ce qui ajoute une surcharge de temps et de ressources. Avec des sessions persistantes, la connexion est établie une seule fois, et toutes les commandes suivantes réutilisent cette connexion, ce qui réduit la latence et améliore la performance globale.
Pour illuster cela, vous pouvez mesurer le temps d'exécution de plusieurs commandes avec et sans session persistante en utilisant la commande Measure-Command. Par exemple :
# Sans session persistante
Measure-Command {
for ($i = 0; $i -lt 10; $i++) {
Invoke-Command -ComputerName CLIENT-01 -ScriptBlock { Get-Date }
}
}
# Avec session persistante
$session = New-PSSession -ComputerName CLIENT-01 -Credential (Get-Credential)
Measure-Command {
for ($i = 0; $i -lt 10; $i++) {
Invoke-Command -Session $session -ScriptBlock { Get-Date }
}
}
Remove-PSSession -Session $session
En comparant les résultats des deux mesures, vous devriez constater que l'exécution avec une session persistante est significativement plus rapide.