PowerShell à distance et les environnements distants
Qu'est-ce que PowerShell à distance (PowerShell Remoting) ?
PowerShell à distance est une fonctionnalité de PowerShell qui permet d'exécuter des commandes et des scripts sur des ordinateurs distants. Cela facilite la gestion et l'automatisation des tâches administratives sur plusieurs machines à partir d'une seule console PowerShell.
Il s'agit de l'équivalent de SSH pour les environnements Windows, mais avec des capacités supplémentaires spécifiques à PowerShell.
Le fonctionnement de PowerShell à distance
PowerShell à distance utilise le protocole WS-Management (WS-Man) pour communiquer avec les machines distantes. WS-Man est un protocole basé sur SOAP qui permet la gestion des systèmes à distance. PowerShell s'appuie sur ce protocole pour établir des sessions distantes et exécuter des commandes sur des ordinateurs distants. Pour utiliser PowerShell à distance, le service Windows Remote Management (WinRM) doit être activé et configuré sur les machines distantes. Par défaut, WinRM est désactivé sur les versions récentes de Windows pour des raisons de sécurité.
Depuis quelques années, PowerShell à distance fonctionne également avec SSH, ce qui permet une plus grande compatibilité avec les environnements non-Windows.
Fonctionnement de WinRM
WinRM est le service qui permet la communication entre les machines via PowerShell Remoting. Il écoute les requêtes entrantes sur des ports spécifiques (par défaut, le port 5985 pour HTTP et 5986 pour HTTPS) et gère les sessions distantes.
Il faut activer et configurer WinRM sur les machines distantes (celles qui recevront les commandes) pour permettre les connexions PowerShell distantes. Cela peut être fait en exécutant la commande Enable-PSRemoting -Force dans une session PowerShell avec des privilèges administratifs.
Les sessions PowerShell distantes
Une session PowerShell distante est une connexion établie entre votre machine locale et une machine distante. Vous pouvez créer une session distante en utilisant la commande Enter-PSSession pour une connexion interactive ou Invoke-Command pour exécuter des commandes non interactives sur une ou plusieurs machines distantes.
Plusieurs sessions peuvent être ouvertes simultanément sur une machine distante, comme le montre le schéma ci-dessous :
Nous verrons comment se connecter à distance de deux façons différentes :
- une connexion 1-à-1 puisque nous établirons une session interactive entre le contrôleur de domaine et le serveur membre. Nous appelons également cela une session "interactif" ou "exclusif" car une seule machine est connectée à la fois. Cette méthode utilise la commande
Enter-PSSession. - une connexion 1-à-plusieurs où nous exécuterons des commandes sur plusieurs machines distantes simultanément. Cette méthode utilise la commande
Invoke-Command.
Domaine (domain) vs Groupe de travail (workgroup)
Sous Windows, les ordinateurs peuvent appartenir soit à un domaine Active Directory, soit à un groupe de travail. Dans un domaine, la gestion des utilisateurs, des permissions et des ressources est centralisée, ce qui simplifie la configuration et l’administration, comme c’est le cas au Collège Maisonneuve avec le domaine cmaisonneuve.qc.ca. Les machines et utilisateurs font automatiquement confiance aux autres membres du domaine, facilitant l’utilisation de PowerShell Remoting.
À l’inverse, dans un groupe de travail, chaque machine gère ses propres utilisateurs et permissions localement, sans contrôle centralisé. Il est possible d’utiliser PowerShell Remoting dans ce type d’environnement, mais cela demande des configurations supplémentaires pour établir la confiance et assurer la sécurité entre les machines.
En résumé, PowerShell Remoting est plus simple à mettre en place dans un domaine Active Directory grâce à la gestion centralisée et aux politiques de groupe (GPO, que nous verrons à la semaine 9), tandis qu’un groupe de travail nécessite des étapes additionnelles pour fonctionner correctement.
La commande Enable-PSRemoting
La commande Enable-PSRemoting est utilisée pour activer PowerShell Remoting sur une machine Windows. Elle configure automatiquement le service WinRM, ajuste les règles de pare-feu nécessaires et prépare la machine à accepter les connexions distantes. Spécifiquement, cette commande effectue les actions suivantes :
- Active le service WinRM et le configure pour démarrer automatiquement.
- Configure les règles de pare-feu pour permettre les connexions entrantes sur les ports utilisés par WinRM (5985 pour HTTP et 5986 pour HTTPS).
- Configure les paramètres de sécurité pour permettre les connexions distantes.
- Crée un listener WinRM pour écouter les requêtes entrantes.
- Configure les paramètres de session pour permettre les connexions distantes.
Il est important d’exécuter cette commande dans une session PowerShell avec des privilèges administratifs. L’option -Force permet de bypasser les confirmations interactives, ce qui est utile pour les scripts automatisés.
Voici donc la commande à exécuter sur chaque machine qui doit accepter des connexions PowerShell distantes :
Enable-PSRemoting -Force
Nous verrons à la semaine 9 comment automatiser cette configuration via des GPO (Group Policy Objects).
La commande Enter-PSSession (1-à-1)
La commande Enter-PSSession est utilisée pour établir une session PowerShell interactive avec une machine distante. Cela permet à l’utilisateur d’exécuter des commandes sur la machine distante comme s’il était connecté localement. Voici comment utiliser cette commande :
Enter-PSSession -ComputerName <NomOuIPDeLaMachineDistante> -Credential (Get-Credential)
-ComputerName: Spécifie le nom ou l’adresse IP de la machine distante à laquelle vous souhaitez vous connecter.-Credential: Permet de fournir les informations d’identification (nom d’utilisateur et mot de passe) nécessaires pour se connecter à la machine distante. La commandeGet-Credentialouvre une fenêtre contextuelle pour saisir ces informations.
Une fois connecté, l’invite de commande change pour indiquer que vous êtes dans une session distante. Vous pouvez alors exécuter des commandes PowerShell qui seront exécutées sur la machine distante.
Pour quitter la session distante et revenir à votre machine locale, utilisez la commande :
Exit-PSSession
La commande Invoke-Command (1-à-plusieurs)
La commande Invoke-Command est utilisée pour exécuter des commandes ou des scripts PowerShell sur une ou plusieurs machines distantes de manière non interactive. Contrairement à Enter-PSSession, qui établit une session interactive, Invoke-Command permet d’exécuter des commandes et de récupérer les résultats sans ouvrir une session interactive. Voici comment utiliser cette commande :
Invoke-Command -ComputerName <NomOuIPDeLaMachineDistante> -ScriptBlock { <CommandesPowerShell> } -Credential (Get-Credential)
-ComputerName: Spécifie le nom ou l’adresse IP de la machine distante (ou une liste de machines) sur laquelle vous souhaitez exécuter les commandes.-ScriptBlock: Contient les commandes PowerShell à exécuter sur la machine distante. Les commandes sont placées entre accolades{}.-Credential: Permet de fournir les informations d’identification nécessaires pour se connecter à la machine distante. La commandeGet-Credentialouvre une fenêtre contextuelle pour saisir ces informations.
Voici un exemple d’utilisation de Invoke-Command pour exécuter la commande Get-Process sur plusieurs machines distantes :
$servers = @("Server1", "Server2", "Server3")
Invoke-Command -ComputerName $servers -ScriptBlock { Get-Process } -Credential (Get-Credential)
Cette commande exécute Get-Process sur chaque serveur de la liste $servers et affiche les résultats dans votre console locale.
La commande New-PSSession et la gestion des sessions persistantes
Une session PowerShell persistante est une connexion distante qui reste ouverte entre votre machine locale et une machine distante, permettant d’exécuter plusieurs commandes dans le même contexte de session. Cela est particulièrement utile pour les tâches répétitives ou lorsque vous devez conserver l’état entre les commandes (par exemple, les variables définies, les modules importés, etc.).
Pour créer une session persistante, vous utilisez la commande New-PSSession :
$session = New-PSSession -ComputerName <NomOuIPDeLaMachineDistante> -Credential (Get-Credential)
-ComputerName: Spécifie le nom ou l’adresse IP de la machine distante.-Credential: Permet de fournir les informations d’identification nécessaires pour se connecter à la machine distante. La variable$sessioncontient maintenant un objet de session que vous pouvez utiliser pour exécuter des commandes à distance.
Pour exécuter des commandes dans cette session persistante, vous utilisez Invoke-Command avec le paramètre -Session :
Invoke-Command -Session $session -ScriptBlock { <CommandesPowerShell> }
-Session: Spécifie la session distante dans laquelle exécuter les commandes.-ScriptBlock: Contient les commandes PowerShell à exécuter dans la session distante.
Finalement, lorsqu'on a terminé avec la session, il est important de la fermer pour libérer les ressources. Vous pouvez le faire avec la commande Remove-PSSession :
Remove-PSSession -Session $session
Illustration de la différence entre Enter-PSSession, Invoke-Command et New-PSSession
Afin de mieux comprendre les différences entre des sessions interactives avec Enter-PSSession, des sessions non interactives avec Invoke-Command et des sessions persistantes avec New-PSSession, nous allons utiliser l'exemple suivant: La vérification de l'espace disque disponible sur plusieurs serveurs avec la commande suivante :
Get-PSDrive -PSProvider FileSystem | Select-Object Name, Free, Used, @{Name="Total";Expression={$_.Free + $_.Used}}
Utilisation de
Enter-PSSession(1-à-1)Pour vérifier l'espace disque sur un serveur spécifique, vous pouvez utiliser
Enter-PSSessionpour établir une session interactive avec ce serveur :Enter-PSSession -ComputerName Server1 -Credential (Get-Credential) Get-PSDrive -PSProvider FileSystem | Select-Object Name, Free, Used, @{Name="Total";Expression={$_.Free + $_.Used}} Exit-PSSessionIci, vous vous connectez à
Server1, exécutez la commande pour vérifier l'espace disque, puis quittez la session.Avantages :
- Permet une interaction directe avec le serveur distant.
- Idéal pour les tâches ad hoc ou les dépannages.
- Vous pouvez voir les résultats immédiatement dans votre console locale.
Inconvénients :
- Dès qu'il y a plusieurs serveurs, cela devient fastidieux car il faut se connecter, effectuer les commandes, puis se déconnecter pour chaque serveur individuellement
Utilisation de
Invoke-Command(1-à-plusieurs)Pour vérifier l'espace disque sur plusieurs serveurs, vous pouvez utiliser
Invoke-Commandpour exécuter la commande à distance sur tous les serveurs en une seule fois :$servers = @("Server1", "Server2", "Server3") Invoke-Command -ComputerName $servers -ScriptBlock { Get-PSDrive -PSProvider FileSystem | Select-Object Name, Free, Used, @{Name="Total";Expression={$_.Free + $_.Used}} }Ici, vous exécutez la commande pour vérifier l'espace disque sur tous les serveurs de la liste
$serversen une seule fois.Avantages :
- Permet d'exécuter des commandes sur plusieurs serveurs simultanément.
- Réduit le temps nécessaire pour effectuer des tâches répétitives sur plusieurs machines.
- Les résultats sont renvoyés à votre console locale, ce qui facilite l'analyse.
Inconvénients :
- Moins d'interaction directe avec chaque serveur, ce qui peut rendre le dépannage plus difficile.
- Si une commande échoue sur un serveur, cela peut ne pas être immédiatement apparent.
Utilisation de
New-PSSession(sessions persistantes) Pour vérifier l'espace disque sur plusieurs serveurs tout en conservant l'état entre les commandes, vous pouvez utiliserNew-PSSessionpour créer des sessions persistantes avec chaque serveur :$servers = @("Server1", "Server2", "Server3") $sessions = @() foreach ($server in $servers) { $sessions += New-PSSession -ComputerName $server -Credential (Get-Credential) } Invoke-Command -Session $sessions -ScriptBlock { Get-PSDrive -PSProvider FileSystem | Select-Object Name, Free, Used, @{Name="Total";Expression={$_.Free + $_.Used}} } # Ici, nous aurions pu ajouter d'autres commandes à exécuter dans les mêmes sessions si nécessaire. Cela permet de conserver l'état entre les commandes (variables, modules, etc.). De plus, cela réduit la surcharge de connexion en réutilisant les sessions existantes. # Fermer les sessions après utilisation Remove-PSSession -Session $sessionsIci, vous créez une session persistante pour chaque serveur dans la liste
$servers, puis vous exécutez la commande pour vérifier l'espace disque sur toutes les sessions ouvertes.Avantages :
- Permet de conserver l'état entre les commandes, ce qui est utile pour les tâches complexes. Par exemple, ici, nous aurions pu ajouter d'autres commandes à exécuter dans les mêmes sessions si nécessaire.
- Réduit la surcharge de connexion en réutilisant les sessions existantes.
- Idéal pour les scripts d'automatisation qui nécessitent plusieurs étapes.
Inconvénients :
- Nécessite une gestion supplémentaire des sessions (création et suppression).
- Peut consommer plus de ressources si de nombreuses sessions sont ouvertes simultanément.
Tiré de :