PowerShell Remoting

Si vous êtes familiers avec l'administration Linux, vous utilisez certainement bash et ssh pour accéder interactivement à des systèmes distants, ou pour exécuter des commandes unitaires à distance. Je dois avouer que depuis toujours j'ai regretté l'absence d'un serveur ssh natif sur Windows… Parallèlement à cela PowerShell s'est imposé depuis plusieurs années comme la ligne de commande privilégiée pour l'administrateur Windows, au point où il a bien fallu se faire à ce pipe « d'objets » plutôt que de texte.

Mettons donc de côté quelques instants le vénérable couple bash et ssh pour nous intéresser à leurs équivalents PowerShell et Windows Remote Management (WinRM).

WinRM est l'implémentation Microsoft du standard WS-Management, basé sur SOAP. De ce fait il ne s'agit plus d'un protocole RPC, délicat à faire passer par des firewalls. Il ne nécessite qu'un port : 5985 pour HTTP, ou 5986 pour HTTPS.

Afin d'utiliser PowerShell à distance, il est nécessaire que WinRM soit activé sur le système distant. C'est le cas par défaut sur Windows Server 2012. Ce n'est pas le cas pour les systèmes clients tels que Windows 7 ou Windows 8, ou pour les systèmes serveurs plus anciens. Pour activer WinRM sur un système sur lequel il n'est pas activé, il suffit d'utiliser la commande : Enable-PSRemoting.

Il existe trois méthodes d'utilisation de PowerShell à distance :

  • Les commandes qui acceptent un paramètre -ComputerName
  • L'exécution d'une commande à distance avec Invoke-Command
  • L'accès à une session distante avec Enter-PSSession

La première méthode ne fait pas intervenir PowerShell Remoting, et ne sera donc pas détaillée ici. Voir la section Remoting Without Configuration de l'article Running Remote Commmands sur Technet.

La seconde méthode utilise la commande Invoke-Command, qui permet d'exécuter une commande ou un script sur un ou plusieurs systèmes distants. Dans le cas le plus simple, cela s'apparente, sous Linux, à une commande du type :

ssh user@server command

En PowerShell cela donne, pour simplifier :

Invoke-Command <scriptblock> -ComputerName server

Par exemple, pour lister les 5 derniers événements du journal sécurité du serveur srv1 :

Invoke-command { Get-EventLog -LogName Security -Newest 5 } -ComputerName srv1

Cela peut s'appliquer à plusieurs systèmes distants :

Invoke-command { Get-EventLog -LogName Security -Newest 5 } -ComputerName srv1,srv2,srv3

Ou à une liste de machines, par exemples toutes les machines du domaine dont le nom commence par srv :

Invoke-command { Get-EventLog -LogName Security -Newest 5 } -ComputerName (Get-ADComputer -filter {Name -like "srv*"} | Select -expand Name)

Invoke-Command peut également utiliser une session existant sur le serveur distant, de façon à conserver un état. En voici une illustration avec une variable utilisée dans deux Invoke-Command consécutifs :

La troisième méthode consiste à établir une session Powershell distante interactive grâce à la commande Enter-PSSession.

L'équivalent ssh :

ssh user@server

devient avec PowerShell :

Enter-PSSession server

Pour plus d'informations sur les possibilités d'authentification ou de reconnexion à une session existante, voir le détail de la commande Enter-PSSession.

Pour plus d'informations sur PowerShell Remoting :

Si vous cherchez une solution pour accéder à un serveur ssh depuis PowerShell, vous pouvez jeter un œil sur le projet SSH.NET.

Tous les exemples ci-dessus ont été testés des systems Windows Server 2012 RC dans un domaine. Pour installer PowerShell 3.0 sur Windows Server 2008 R2 ou Windows 7, il faut installer Windows Management Framework 3.0 RC, qui contient PowerShell 3.0, WMI et WinRM. WMF 3.0 contient également un provider CIM qui permet de gérer ces systèmes depuis le Server Manager de Windows Server 2012 RC.

Téléchargez Windows Server 2012 RC sous la forme d'un fichier ISO ou d'un VHD préinstallé : https://technet.microsoft.com/fr-fr/evalcenter/hh670538.aspx.