Introduction à PowerShell Remoting (WinRM) ── gérer plusieurs machines Windows en une seule fois
· Go Komura · PowerShell, Windows, WinRM, Gestion à distance, Automatisation, Amélioration opérationnelle, Sécurité, Scripts
« Après la mise à jour Windows, va vérifier que les 20 serveurs ont bien redémarré » ; « J’aimerais que tu vérifies cette valeur de configuration sur les PC de tous les sites » — ne traitez-vous pas ce genre de demandes en vous connectant machine par machine via le Bureau à distance ? Même à 3 minutes par machine, cela fait une heure pour 20 machines. On finit par se lasser en cours de route, et des oublis de vérification surviennent.
PowerShell Remoting transforme ce « même travail sur plusieurs machines » en une seule commande. Windows intègre en standard un socle de gestion à distance appelé WinRM, activé par défaut sous Windows Server. Autrement dit, dans de nombreux environnements, vous pouvez commencer à l’utiliser dès aujourd’hui sans logiciel supplémentaire. Et pourtant, on entend souvent « ça fait un peu peur » ou « ça ne se connectait pas en groupe de travail, alors j’ai abandonné ».
Cet article s’adresse aux services informatiques et aux responsables de l’exploitation dans les PME. Il couvre le fonctionnement de Remoting (ce qui tourne, sur quel port, et qui peut se connecter), l’exécution en masse avec Invoke-Command, les différences entre environnement de domaine et groupe de travail, les pièges classiques comme le problème du second hop, le diagnostic en cas d’échec de connexion, et enfin l’exploitation sécurisée en « commençant par la lecture ».
Environnement prérequis
- Côté qui reçoit la connexion : sur Windows Server 2012 et versions ultérieures, PowerShell Remoting est activé par défaut.1 Sous les éditions clientes de Windows, le service WinRM est désactivé par défaut, ce qui nécessite une activation via
Enable-PSRemoting.1 - Côté qui se connecte : les exemples de commandes de cet article n’utilisent que des applets de commande présentes à la fois dans Windows PowerShell 5.1 et PowerShell 7. Cependant, les applets de commande liées à WS-Management comme le lecteur
WSMan:ouTest-WSManne sont disponibles que sous PowerShell pour Windows (sous Linux et macOS, utilisez le Remoting basé sur SSH du chapitre 6).2 - Droits : toute modification de configuration côté distant (Enable-PSRemoting, TrustedHosts, écouteur) nécessite PowerShell lancé en tant qu’administrateur.1
- Réseau : cet article traite à la fois l’environnement de domaine et l’environnement en groupe de travail. Les différences sont résumées au chapitre 3.
1. La conclusion, d’abord
- PowerShell Remoting fonctionne au-dessus de WinRM (l’implémentation de WS-Management) et utilise par défaut les ports HTTP 5985 / HTTPS 5986. Même en HTTP, le contenu de la communication est chiffré au niveau du message par le protocole d’authentification.3
- Par défaut, seuls les membres du groupe Administrators de la machine distante peuvent se connecter, et la session s’exécute dans le contexte de l’utilisateur connecté. Ce n’est pas parce que Remoting est activé que n’importe qui peut entrer.3
- Ce que fait Enable-PSRemoting est clairement défini. Démarrage du service WinRM et automatisation de son démarrage, création de l’écouteur, exception de pare-feu, activation de la configuration de session. Activé par défaut sous Windows Server, à activer manuellement sous les éditions clientes de Windows.43
- Un environnement de domaine fonctionne directement avec Kerberos ; un groupe de travail nécessite NTLM + TrustedHosts + identifiants explicites. TrustedHosts n’est pas un réglage qui « fait confiance à l’autre partie », mais une « liste qui renonce à vérifier son identité » : limitez-la au strict minimum.53
- L’exécution en masse utilise Invoke-Command, l’opération interactive Enter-PSSession, et si l’état doit être conservé pour un usage répété, New-PSSession. Invoke-Command traite par défaut jusqu’à 32 machines en parallèle.67
- Ce qui revient du côté distant est un objet désérialisé, sans méthodes. Les opérations doivent se dérouler entièrement dans le ScriptBlock (côté distant) ; en local, on ne fait qu’agréger les résultats.87
- On ne peut pas accéder depuis la machine cible à un autre serveur plus loin (problème du second hop). Ce n’est pas un défaut, mais la conséquence d’une conception sécurisée qui n’envoie pas les identifiants au serveur distant. Il existe plusieurs parades, à choisir selon les besoins.9
- PowerShell 7 permet aussi un Remoting basé sur SSH. Une option utile si vous devez gérer conjointement des machines Linux, ou dans un environnement où vous ne voulez pas ouvrir WinRM.2
2. Le fonctionnement ── qui entre, et comment, au-dessus de WinRM
Le socle de PowerShell Remoting est WinRM (Windows Remote Management). WinRM est l’implémentation Microsoft du protocole standard WS-Management, et PowerShell Remoting achemine les commandes vers PowerShell sur l’ordinateur distant via ce WinRM.3 La communication utilise par défaut les ports HTTP 5985 et HTTPS 5986.35
On s’inquiète souvent d’un « HTTP donc en clair », mais une fois l’authentification initiale terminée, WinRM chiffre la communication. En HTTPS, c’est TLS ; en HTTP, c’est un chiffrement au niveau du message négocié par le protocole d’authentification (AES-256 dans un environnement moderne avec Kerberos).3 Par ailleurs, par défaut, seuls les membres du groupe Administrators de la machine distante peuvent se connecter, et comme la session s’exécute dans le contexte de l’utilisateur connecté, le contrôle d’accès aux fichiers et au registre s’applique normalement.3
La préparation côté récepteur passe par Enable-PSRemoting. Ce que fait cette applet de commande est officiellement listé. En interne, elle exécute Set-WSManQuickConfig, qui effectue (1) le démarrage du service WinRM, (2) l’automatisation du type de démarrage, (3) la création d’un écouteur recevant sur n’importe quelle adresse IP, (4) l’activation de l’exception de pare-feu pour les communications WS-Management, et (5) la création et l’activation de la configuration de session (le point de terminaison) avec l’autorisation d’accès à distance, puis redémarre le service WinRM.4
# À exécuter une seule fois, du côté qui « reçoit » la connexion, depuis un PowerShell en droits administrateur
# (généralement inutile sous Windows Server où c'est activé par défaut ; nécessaire sous les éditions clientes)
Enable-PSRemoting
# Vérification de connectivité depuis le côté qui « se connecte » ── si cela passe, le socle de Remoting est en place
Test-WSMan -ComputerName sv-app01
Deux particularités sont sources de blocage si on ne les connaît pas. La première concerne le pare-feu. Sur les éditions serveur de Windows, Enable-PSRemoting crée aussi, pour le profil réseau public, une règle « autoriser uniquement depuis le même sous-réseau » ; mais sur les éditions clientes, si le profil réseau est public, l’activation elle-même échoue (un problème classique quand une machine de test est connectée au Wi-Fi de l’entreprise). Dans ce cas, ajoutez -SkipNetworkProfileCheck, ou repassez le profil en privé.4
La seconde concerne la relation entre la version de PowerShell et le point de terminaison. Enable-PSRemoting configure un point de terminaison « pour la version de PowerShell utilisée pour l’exécuter ». L’exécuter depuis PowerShell 7 n’affecte pas le point de terminaison de Windows PowerShell 5.1, et inversement.4 De plus, même en se connectant depuis PowerShell 7, c’est par défaut le point de terminaison existant de Windows PowerShell 5.1 (Microsoft.PowerShell) qui est utilisé10, donc « en local c’est du 7, mais ce qui tourne à distance, c’était du 5.1 » arrive tout à fait couramment. Prenez l’habitude d’afficher $PSVersionTable côté distant pour vérifier.
3. Domaine et groupe de travail ── c’est là que se situe le mur de l’authentification
Le principal point de blocage dans l’apprentissage de Remoting n’est pas la syntaxe des commandes, mais l’authentification. La préparation nécessaire change selon l’environnement.
| Élément | Environnement de domaine | Environnement en groupe de travail |
|---|---|---|
| Protocole d’authentification | Kerberos (avec authentification mutuelle)5 | NTLM (pas de vérification d’identité du serveur)5 |
| Configuration supplémentaire | En principe inutile. Connexion directe par nom d’ordinateur | Inscription dans TrustedHosts requise côté connexion5 |
| Identifiants | L’utilisateur actuellement connecté est utilisé tel quel | -Credential explicite, la forme de base |
| Spécification par adresse IP | Inscription dans TrustedHosts ou HTTPS requis11 | Idem |
Dans un environnement de domaine, l’authentification mutuelle Kerberos (le client et le serveur se vérifient l’un l’autre) fonctionne, donc Invoke-Command -ComputerName sv-app01 { ... } passe tel quel. En groupe de travail, Kerberos n’est pas disponible5, donc il faut inscrire la machine cible dans TrustedHosts du côté connexion.
# À exécuter côté « connexion », depuis un PowerShell lancé en administrateur (nécessaire uniquement en groupe de travail)
# Modifier TrustedHosts nécessite aussi les droits administrateur. La valeur existante étant écrasée, vérifiez d'abord la valeur actuelle
Get-Item WSMan:\localhost\Client\TrustedHosts
# N'ajouter que les noms d'hôte strictement nécessaires. Sans -Concatenate, les inscriptions existantes sont effacées. Évitez d'autoriser tout avec '*'
Set-Item WSMan:\localhost\Client\TrustedHosts -Value 'sv-app01,sv-app02' -Concatenate
# Test de connexion avec identifiants explicites
$cred = Get-Credential sv-app01\Administrator
Invoke-Command -ComputerName sv-app01 -Credential $cred -ScriptBlock { hostname }
Le point important ici est le sens réel de TrustedHosts. La documentation officielle précise explicitement qu’« un ordinateur inscrit dans TrustedHosts n’est pas authentifié, et il est possible que le client lui envoie des identifiants ».5 Autrement dit, ce n’est pas tant une « liste d’ordinateurs de confiance » qu’une « liste qui supprime l’avertissement signalant qu’on ne peut pas vérifier l’identité du serveur ».3 Dans un environnement où le DNS ou l’ARP peuvent être manipulés, il y a un risque de transmettre des identifiants administrateur à un faux serveur. C’est pourquoi il faut éviter les inscriptions génériques et ne mettre que des noms d’hôte ou des IP fixes, en nombre minimal. Pour un environnement en groupe de travail utilisé en production, ou une DMZ, la démarche la plus saine consiste à préparer un certificat et à configurer un écouteur HTTPS (5986).3
Notez au passage : si vous commencez à écrire en clair, dans un script, les identifiants récupérés via Get-Credential, c’est un signal d’alerte. Les bonnes pratiques de stockage et de transmission des identifiants sont détaillées dans « Gérer les identifiants en toute sécurité avec PowerShell », publié en même temps que cet article.
Un autre point facilement négligé en groupe de travail est la présence ou non d’un mot de passe. Si le compte de la machine cible n’a pas de mot de passe défini (mot de passe vide), les commandes distantes ne peuvent pas être exécutées.1
3.1. Configurer un écouteur HTTPS (5986)
Pour un usage courant en groupe de travail ou en DMZ, mieux vaut mettre en place un écouteur HTTPS plutôt que de se contenter de TrustedHosts. Voici le squelette de la procédure.12
- Préparer un certificat d’authentification serveur. Les exigences sont : « un certificat d’authentification serveur de l’ordinateur local », « un CN (ou un nom alternatif du sujet) correspondant au nom d’hôte », « dans sa période de validité, non révoqué, et non auto-signé ». Si vous disposez d’une AC interne, vous pouvez en faire la demande via l’inscription web sur
https://<serveur de l'autorité de certification>/certsrv. - Placer le certificat dans le magasin personnel de l’ordinateur local. Vérifiez via le composant logiciel enfichable Certificats (dans MMC, ajoutez « Certificats » et choisissez « Compte d’ordinateur » dans l’assistant), sous Certificats (ordinateur local) > Personnel > Certificats.
-
Créer l’écouteur HTTPS. La méthode la plus rapide tient en une ligne.
winrm quickconfig -transport:httpsSi vous avez plusieurs certificats et voulez préciser lequel utiliser, vous pouvez aussi le créer depuis PowerShell en indiquant l’empreinte numérique (visible avec
Get-ChildItem Cert:\LocalMachine\My).New-Item -Path WSMan:\localhost\Listener -Address * -Transport HTTPS -CertificateThumbPrint 'empreinte du certificat' -Force - Autoriser dans le pare-feu la réception sur TCP 5986. La règle créée par
Enable-PSRemotingvise HTTP (5985) ; HTTPS demande une règle séparée. -
Vérifier que l’écouteur a bien été créé.
winrm enumerate winrm/config/listener
Côté connexion, il suffit d’ajouter -UseSSL.
Invoke-Command -ComputerName sv-app01.example.local -UseSSL -Credential $cred -ScriptBlock { hostname }
Si les conditions du certificat ne sont pas remplies, la création de l’écouteur échoue avec une erreur du type « Cannot create a WinRM listener on HTTPS because this machine does not have an appropriate certificate. (numéro d’erreur -2144108267 / 0x80338115) ». Dans ce cas, vérifiez dans l’ordre la date d’expiration du certificat, si le destinataire correspond au nom d’hôte, si l’usage de clé étendu inclut « Authentification du serveur », et si la chaîne de certification est valide.12
4. Invoke-Command ── la forme de base pour « faire la même chose sur 20 machines »
Le rôle principal de Remoting revient à Invoke-Command. Passez plusieurs machines à -ComputerName, et écrivez dans -ScriptBlock « ce qui doit être fait à distance ».6 Commencer par un inventaire en lecture seule est la règle d’or d’une exploitation sécurisée.
$servers = 'sv-app01', 'sv-app02', 'sv-db01'
# Vérification de l'état après application d'un correctif ── uniquement en lecture, donc sans risque
$result = Invoke-Command -ComputerName $servers -ScriptBlock {
# Le contenu de ce bloc s'exécute « côté distant »
$os = Get-CimInstance Win32_OperatingSystem
[PSCustomObject]@{
LastBoot = $os.LastBootUpTime # Le redémarrage a-t-il bien eu lieu ?
SpoolerRun = (Get-Service -Name Spooler).Status # État d'un service requis pour l'activité
FreeGB = [math]::Round((Get-PSDrive C).Free / 1GB, 1)
}
}
# On sait à quel serveur appartient chaque résultat grâce à PSComputerName
$result | Sort-Object PSComputerName |
Select-Object PSComputerName, LastBoot, SpoolerRun, FreeGB |
Export-Csv -Path .\patch-check.csv -NoTypeInformation -Encoding UTF8
La connexion à chaque serveur est traitée en parallèle, avec un nombre d’exécutions simultanées (ThrottleLimit) par défaut de 32.7 Les résultats reviennent mélangés dans l’ordre d’arrivée, d’où l’intérêt, comme dans l’exemple ci-dessus, de les retrier avec la propriété PSComputerName ajoutée automatiquement.8
4.1. Transmettre des variables ── $using: et -ArgumentList
Le ScriptBlock s’exécutant à distance, les variables locales ne sont pas visibles telles quelles. Il existe deux façons d’y introduire des valeurs.13
$threshold = (Get-Date).AddDays(-30)
# Méthode 1 : $using: ── intègre à distance une « copie de la valeur » de la variable côté appelant
Invoke-Command -ComputerName $servers -ScriptBlock {
(Get-ChildItem 'D:\AppLogs' -Filter *.log |
Where-Object LastWriteTime -lt $using:threshold).Count
}
# Méthode 2 : -ArgumentList ── reçue via un param() côté ScriptBlock (plus lisible avec de nombreux arguments)
Invoke-Command -ComputerName $servers -ScriptBlock {
param($limit)
(Get-ChildItem 'D:\AppLogs' -Filter *.log |
Where-Object LastWriteTime -lt $limit).Count
} -ArgumentList $threshold
La valeur transmise via $using: est une copie indépendante côté distant. La réécrire côté distant ne modifie pas la variable en local.13
4.2. Ce qui revient est un « instantané » ── un objet désérialisé
C’est le premier point qui déroute avec les résultats de Remoting. Un objet .NET vivant ne peut pas traverser le réseau : la sortie distante est donc sérialisée en XML (CLIXML) pour être envoyée, puis reconstruite en local sous forme d’objet désérialisé. C’est un instantané des propriétés au moment de l’exécution, sans méthodes.87
Par exemple, on ne peut pas récupérer localement le résultat de Get-Service et appeler .Stop() dessus. Si vous voulez arrêter un service, exécutez Stop-Service à l’intérieur du ScriptBlock — autrement dit, la bonne répartition des rôles consiste à faire aboutir les opérations côté distant, et ne rapporter en local que les données destinées au reporting. La sélection, la mise en forme et l’export en CSV des propriétés, en local, se font avec les mêmes réflexes que d’habitude avec PowerShell (pour ces opérations de base, voir « Les bases des commandes PowerShell »).
5. Enter-PSSession et New-PSSession ── interaction et réutilisation
Pour examiner une seule machine de manière interactive, utilisez Enter-PSSession. L’invite devient [sv-app01]: PS>, et les commandes saisies s’exécutent à distance. On en sort avec exit.11 Contrairement au Bureau à distance, l’écran n’est pas rapporté, mais pour des tâches comme « consulter un journal » ou « vérifier une configuration », c’est plus rapide ; la connexion exige également d’être membre du groupe Administrators.11
D’un autre côté, chaque appel d’Invoke-Command avec -ComputerName établit puis referme la connexion à chaque fois.14 Pour des travaux d’investigation qui envoient plusieurs fois des commandes au même groupe de serveurs, créer une session persistante avec New-PSSession et la réutiliser est plus rapide, et les variables et l’état côté distant sont conservés d’une commande à l’autre.1415
# Établir la session une seule fois et la réutiliser via la variable $s
$s = New-PSSession -ComputerName $servers
try {
# 1re fois : créer côté distant une variable $hotfix
Invoke-Command -Session $s { $hotfix = Get-HotFix | Sort-Object InstalledOn -Descending }
# 2e fois : la variable créée par la commande précédente est directement utilisable (la session conserve l'état)
Invoke-Command -Session $s { $hotfix | Select-Object -First 5 }
}
finally {
# Toujours libérer la session, même en cas d'erreur ou d'interruption en cours de route (libère les ressources côté distant)
Remove-PSSession $s
}
6. Les pièges ── second hop, et l’option SSH
6.1. Le problème du second hop (double saut)
C’est le mur le plus connu sur le terrain. Depuis le PC local (A), on entre par Remoting sur le serveur B, puis on essaie depuis B de lire \\fs01\share (le serveur C) — l’accès est refusé. Les authentifications Kerberos/NTLM par défaut authentifient sans envoyer les identifiants eux-mêmes à B, d’où une méthode sécurisée dans laquelle B ne peut pas s’authentifier auprès de C en votre nom.39
Il existe plusieurs parades, que la documentation officielle classe par ordre de préférence.9 Voici les principales.
- Transmettre explicitement les identifiants dans le ScriptBlock ── ne nécessite aucune modification de configuration côté serveur, c’est le plus simple. On transmet les identifiants à l’Invoke-Command interne via
$using:cred.9 Cependant, comme l’objet d’identifiants transite par la session du serveur relais (B), si B est compromis, les identifiants transmis peuvent être exploités : cette approche suppose donc de ne l’utiliser que si B est entièrement digne de confiance, et de transmettre un compte dédié disposant, côté C, uniquement des droits strictement nécessaires. - Délégation Kerberos contrainte basée sur les ressources ── aucune sauvegarde d’identifiants ; c’est la ressource cible (C) qui est configurée pour « accepter la délégation depuis B ». Configurable sans droits d’administrateur de domaine, c’est une option offrant un bon équilibre entre sécurité et simplicité de configuration.9
- JEA (Just Enough Administration) ── un mécanisme PowerShell qui met en place un point de terminaison dédié n’autorisant « que les commandes nécessaires à cette tâche », restreignant ainsi les droits. Avec une configuration utilisant des comptes virtuels, l’utilisateur peut se connecter avec des identifiants autres qu’administrateur tout en n’exécutant que les commandes d’administration autorisées.16 Dans le contexte du second hop, cela revient à créer un guichet qui n’exécute que les tâches standard, y compris l’accès à C, au lieu de distribuer des identifiants administrateur au serveur relais (B).9
- CredSSP ── les identifiants sont mis en cache sur le serveur distant, donc si ce serveur est compromis, les identifiants le sont aussi. Désactivé par défaut, son activation devrait être réservée aux environnements les plus dignes de confiance.9
# La parade la plus simple : transmettre les identifiants à l'Invoke-Command interne via $using:cred
# On se connecte au serveur externe (sv-app01) avec ses propres identifiants, et on ne transmet
# à l'appel interne qu'un compte dédié disposant, côté fs01, des droits strictement nécessaires
# (ne pas distribuer d'identifiants administrateur)
#
# [Prérequis] L'appel interne est « une nouvelle connexion Remoting de sv-app01 vers fs01 », donc il faut :
# 1. Que WinRM (5985/5986) soit joignable depuis sv-app01 vers fs01
# 2. En groupe de travail ou avec une adresse IP, que fs01 soit déjà inscrit dans TrustedHosts côté sv-app01
# 3. Que $cred soit un compte valide sur fs01 (compte de domaine, ou compte local à fs01)
# Copier-coller sans vérifier ces points mène souvent à « ça marche en local mais échoue depuis le serveur relais »
$cred = Get-Credential CONTOSO\svc-fileread
Invoke-Command -ComputerName sv-app01 -ScriptBlock {
Invoke-Command -ComputerName fs01 -Credential $using:cred -ScriptBlock { hostname }
}
Avant tout, la solution la moins coûteuse consiste à se demander si l’on ne peut pas, plutôt que de « lire les fichiers de C en passant par B », faire directement un Invoke-Command depuis le poste local vers C.
6.2. Avec PowerShell 7, le Remoting basé sur SSH est aussi disponible
À partir de PowerShell 6.0, un Remoting se connectant via SSH plutôt que WinRM est disponible. Invoke-Command / Enter-PSSession / New-PSSession ont reçu un jeu de paramètres SSH — -HostName, -UserName, -KeyFilePath — permettant une gestion transversale entre Windows et Linux.2 La cible doit disposer d’un serveur SSH et de la configuration du sous-système SSH de PowerShell ; les fonctionnalités propres à la base WinRM, comme la configuration de points de terminaison ou JEA, ne sont actuellement pas prises en charge.2 À retenir comme option pour un environnement mêlant des serveurs Linux, ou si vous voulez unifier l’exploitation autour de l’authentification par clé. Windows PowerShell 5.1 ne dispose pas de cette fonctionnalité, ce qui peut constituer un motif de migration si besoin (pour une vue d’ensemble des différences, voir « Les différences entre Windows PowerShell 5.1 et PowerShell 7 », publié en même temps que cet article).
À titre indicatif, une session de Remoting ne crée pas de session de bureau comme le RDP. La différence entre les deux notions de « fonctionner à distance » est détaillée dans « Comprendre l’isolation des sessions Windows ».
7. Diagnostiquer une absence de connexion
La plupart des raisons pour lesquelles les débutants abandonnent Remoting tiennent à un simple « ça ne se connecte pas ». Et la cause d’un échec peut se trouver n’importe où : service, écouteur, pare-feu, authentification, droits. En les éliminant dans l’ordre, en partant de l’amont, on ne s’y perd pas.
7.1. L’ordre du diagnostic
- Vérifier la connectivité. Commencez par
Test-WSMan -ComputerName sv-app01depuis le côté connexion. Si cela passe, le service WinRM, l’écouteur et le pare-feu sont en état de fonctionner (des problèmes d’authentification ou de droits peuvent subsister). Si cela échoue, passez à l’étape suivante. - Le service WinRM tourne-t-il côté distant ? Sur les éditions serveur, le type de démarrage est automatique, mais sous les éditions clientes de Windows, le service WinRM est désactivé par défaut.1 Vérifiez avec
Get-Service WinRM, et si besoin exécutezEnable-PSRemoting(qui regroupe le démarrage du service, son automatisation, l’écouteur, l’exception de pare-feu et la configuration de session).4 -
L’écouteur est-il à l’écoute ? Exécutez ce qui suit côté distant, et vérifiez que
ListeningOnn’est pas vide. S’il est vide, une erreur de configuration classique se produit dans un environnement où l’écouteur est distribué par stratégie de groupe.1Get-WSManInstance winrm/config/listener -Enumerate - Vérifier le profil réseau. Sur les éditions clientes, si le réseau est public,
Enable-PSRemotingéchoue lui-même avec « Unable to check the status of the firewall ». Repassez le profil en privé, ou ajoutez-SkipNetworkProfileCheck.1 - Vérifier les règles de pare-feu. Même sur une édition serveur, le profil public applique une règle « autoriser uniquement depuis le même sous-réseau ». Pour entrer depuis un autre sous-réseau, il faut revoir la règle (vérifiez le nom de la règle avec
Get-NetFirewallRuleavant de la modifier ; le nom de la règle varie selon la version de Windows).1 - Les conditions du mode d’authentification sont-elles remplies ? En groupe de travail, hors domaine, ou avec une adresse IP explicite, Kerberos n’est pas disponible, donc c’est NTLM ; l’inscription dans TrustedHosts (ou HTTPS) et une spécification explicite de
-Credentialsont obligatoires. Un compte cible avec un mot de passe vide ne fonctionne pas.1 - A-t-on les droits nécessaires pour se connecter ? Seuls les membres du groupe Administrators côté distant peuvent se connecter au point de terminaison par défaut. Un utilisateur d’un autre domaine ou un compte local reçoit par défaut un jeton d’utilisateur standard et ne peut donc pas agir en administrateur (si nécessaire, il existe
LocalAccountTokenFilterPolicy, mais c’est un réglage qui désactive la restriction UAC à distance pour tous les utilisateurs : n’y recourez qu’en en comprenant les implications).1 - Vérifier la version de PowerShell du point de terminaison. Si la connexion réussit mais qu’on vous dit que « cette applet de commande n’existe pas », il est possible, comme au chapitre 2, que vous soyez entré sur le point de terminaison de Windows PowerShell 5.1. Vérifiez avec
Invoke-Command -ComputerName sv-app01 { $PSVersionTable.PSVersion }, et précisez si nécessaire avec-ConfigurationName.10
7.2. Comment lire les messages d’erreur les plus courants
Les messages d’erreur sont quasiment normalisés : mieux vaut donc les associer à un endroit précis à vérifier plutôt que de tenter de les mémoriser un par un.1
| Message d’erreur (extrait) | Cause fréquente | Premier endroit à vérifier |
|---|---|---|
Access is denied. You need to run this cmdlet from an elevated process. |
Le PowerShell local n’est pas en droits administrateur | Le rouvrir en « Exécuter en tant qu’administrateur » |
ACCESS IS DENIED |
Remoting désactivé côté cible / l’utilisateur connecté n’est pas dans Administrators / restriction de jeton pour un autre domaine ou un administrateur local | Exécuter Enable-PSRemoting côté cible, indiquer un administrateur avec -Credential, vérifier si besoin les droits de la configuration de session ou LocalAccountTokenFilterPolicy |
The connection to the remote host was refused. Verify that the WS-Management service is running on the remote host and configured to listen for requests on the correct port and HTTP URL. |
Le service WinRM est arrêté, pas d’écouteur, port incorrect | Get-Service WinRM, énumération des écouteurs, configuration du port |
The client cannot connect to the destination specified in the request. Verify that the service on the destination is running and is accepting requests. |
Le ListeningOn de l’écouteur est vide (erreur de stratégie), influence d’un proxy |
Énumération des écouteurs, configuration du proxy via New-PSSessionOption |
The WinRM client cannot process the request. If the authentication scheme is different from Kerberos, or if the client computer is not joined to a domain, then HTTPS transport must be used or the destination machine must be added to the TrustedHosts configuration setting. |
Groupe de travail, hors domaine, adresse IP explicite | Inscription dans TrustedHosts + -Credential, ou configuration HTTPS du point 3.1 |
Unable to check the status of the firewall (lors de l’exécution d’Enable-PSRemoting) |
Réseau public sur une édition cliente | Repasser le profil en privé, ou -SkipNetworkProfileCheck |
The WS-Management service cannot complete the operation within the time specified in OperationTimeout. |
Traitement long, charge élevée côté distant | Prolonger avec New-PSSessionOption -OperationTimeout |
The total data received from the remote client exceeded allowed maximum. |
Les données renvoyées sont trop volumineuses | Agréger et filtrer dans le ScriptBlock avant de renvoyer. Ajuster le quota si nécessaire |
L’astuce du diagnostic consiste à déterminer, un à un, s’il s’agit d’un problème local, d’un problème de chemin réseau, ou d’un problème côté distant. Le succès ou l’échec de Test-WSMan permet de départager le chemin réseau et le service distant ; une fois cela passé, l’erreur restante se limite à l’authentification et aux droits. Cette approche en deux temps évite de tâtonner indéfiniment sur des réglages sans savoir où se situe le problème.
8. Les règles de l’art en pratique (tableau de décision)
| Point de décision | Options | Critère de jugement |
|---|---|---|
| Examiner une machine de manière interactive | RDP / Enter-PSSession | RDP si l’écran est nécessaire, Enter-PSSession est plus léger si une commande suffit11 |
| Même traitement sur plusieurs machines | Manuellement, une par une / Invoke-Command | Au-delà de 3 machines, Invoke-Command. Jusqu’à 32 en parallèle par défaut67 |
| Envoyer plusieurs commandes successives | Reconnexion à chaque fois via -ComputerName / Réutilisation de New-PSSession | Réutiliser la session pour des allers-retours interactifs lors d’une investigation. Ne pas oublier Remove-PSSession une fois terminé14 |
| Authentification en groupe de travail | TrustedHosts (HTTP) / Écouteur HTTPS | TrustedHosts minimal pour un usage ponctuel. Configuration HTTPS pour un usage courant (procédure au point 3.1)5312 |
| Parade au second hop | Transmission explicite des identifiants / délégation basée sur les ressources / CredSSP | D’abord la transmission explicite, sans modification de configuration. Délégation basée sur les ressources pour un usage permanent. CredSSP en dernier recours9 |
| Première commande à exécuter | Une commande qui modifie / Une commande de lecture | Toujours commencer par un inventaire avec des commandes Get. Pour les commandes de modification, faire un essai avec -WhatIf avant l’exécution réelle |
Ce dernier point mérite d’être souligné. Invoke-Command est à la fois « la commande qui répare 20 machines en un instant » et « la commande qui casse 20 machines en un instant ». Heureusement, la plupart des applets de commande de modification comme Stop-Service ou Set-ItemProperty prennent en charge -WhatIf, et cela fonctionne tel quel à l’intérieur d’un ScriptBlock. Faire de d’abord une machine, puis toutes les machines avec -WhatIf, enfin l’exécution réelle une habitude systématique pour tout nouveau script réduit visiblement le taux d’incidents.
9. Conclusion
- Remoting fonctionne au-dessus de WinRM (WS-Management), avec pour ports par défaut HTTP 5985 / HTTPS 5986. Seuls les membres du groupe Administrators côté distant peuvent se connecter par défaut, et la communication est chiffrée après authentification.
- Enable-PSRemoting démarre le service WinRM, crée l’écouteur, active l’exception de pare-feu et la configuration de session. Attention : le point de terminaison configuré correspond à la version de PowerShell utilisée pour l’exécuter.
- Un domaine fonctionne directement avec Kerberos ; un groupe de travail nécessite TrustedHosts + des identifiants explicites. TrustedHosts étant une liste qui renonce à vérifier l’identité, à limiter au strict minimum.
- L’exécution en masse utilise Invoke-Command (32 en parallèle par défaut), l’interaction Enter-PSSession, et la réutilisation de New-PSSession pour conserver l’état. Les résultats sont des objets désérialisés sans méthodes, donc les opérations doivent aboutir côté distant.
- On n’atteint pas ce qui se trouve au-delà de la machine cible (second hop). Envisagez d’abord la transmission explicite des identifiants, puis, pour un usage permanent, la délégation Kerberos contrainte basée sur les ressources.
- En cas d’échec de connexion, isolez d’abord le chemin réseau et le service distant avec
Test-WSMan, puis concentrez-vous sur l’authentification (TrustedHosts, identifiants) et les droits (Administrators). Les messages d’erreur les plus courants et leurs correspondances sont résumés dans le tableau du chapitre 7. - Côté exploitation, commencez toujours par des commandes de lecture. Pour les commandes de modification, suivez les trois étapes : une machine → -WhatIf → exécution réelle. Pour un exemple concret appliqué à l’inventaire d’un serveur de fichiers, voir « Faire l’inventaire d’un serveur de fichiers avec PowerShell », publié en même temps que cet article.
Articles connexes
- Les bases des commandes PowerShell ── les opérations à connaître en premier et une utilisation sûre
- Recueil de commandes PowerShell pratiques ── enrichir les petites fonctions utiles au quotidien
- Faire l’inventaire d’un serveur de fichiers avec PowerShell ── enquête de capacité et audit des droits d’accès (ACL)
- Gérer les identifiants en toute sécurité avec PowerShell
- Comprendre l’isolation des sessions Windows ── Session 0, RDP et exécution simultanée multi-utilisateurs
- Manipuler correctement les jetons d’emprunt d’identité Windows ── emprunt de droits par thread et restitution sécurisée
Domaines de conseil associés
合同会社小村ソフト (Komura Software LLC) prend en charge la mise en place d’une gestion en masse des serveurs et postes clients avec PowerShell, la conception et la revue de scripts d’exploitation intégrant Remoting, ainsi que l’investigation autour de WinRM et de l’authentification lorsque « ça ne se connecte pas » ou que « l’authentification échoue seulement dans certains environnements ».
- Conseil technique et revue de conception
- Investigation d’anomalies et analyse de cause racine
- Développement d’applications Windows
- Contact
Références
-
Microsoft Learn, about_Remote_Troubleshooting. Sur le fait que Remoting est activé par défaut sur Windows Server 2012 et versions ultérieures, que le service WinRM est désactivé par défaut sous les éditions clientes de Windows, que la modification de la configuration du lecteur WSMan: nécessite les droits administrateur, sur les messages d’erreur courants (accès refusé / connexion refusée / Unable to check the status of the firewall / erreurs du client WinRM relatives à TrustedHosts et HTTPS / délai dépassé / dépassement de quota) et leurs solutions, l’énumération des écouteurs via Get-WSManInstance et l’erreur de stratégie se traduisant par un ListeningOn vide, le comportement des règles de pare-feu en réseau public, l’impossibilité d’utiliser un compte à mot de passe vide en groupe de travail, et la restriction de jeton pour les administrateurs d’un autre domaine ou locaux avec LocalAccountTokenFilterPolicy. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11
-
Microsoft Learn, PowerShell remoting over SSH. Sur le fait qu’un Remoting basé sur SSH est disponible à partir de PowerShell 6, que New-PSSession/Enter-PSSession/Invoke-Command ont reçu les paramètres -HostName/-UserName/-KeyFilePath, le fonctionnement multiplateforme, et le fait que la configuration de point de terminaison ou JEA ne soit actuellement pas pris en charge. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, Security Considerations for PowerShell Remoting using WinRM. Sur le fait que Remoting utilise WinRM (l’implémentation Microsoft de WS-Management), que les ports par défaut sont HTTP 5985/HTTPS 5986, que seuls les membres du groupe Administrators peuvent se connecter par défaut et que la session s’exécute dans le contexte de l’utilisateur, que la communication est chiffrée après authentification, que TrustedHosts n’est qu’une liste supprimant les erreurs de vérification d’identité, et sur le contexte du problème du second hop. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 ↩12
-
Microsoft Learn, Enable-PSRemoting. Sur la liste des opérations effectuées par Enable-PSRemoting (démarrage et automatisation du service WinRM, création de l’écouteur, exception de pare-feu, activation de la configuration de session et modification du descripteur de sécurité), le fait que ce soit activé par défaut sous Windows Server, la restriction sur les éditions clientes en réseau public et SkipNetworkProfileCheck, et le fait que le point de terminaison configuré corresponde à la version utilisée pour l’exécution. ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, Installation and configuration for Windows Remote Management. Sur le fait que les ports d’écoute par défaut de WinRM 2.0 sont 5985/5986, que Kerberos est choisi pour les comptes de domaine et NTLM pour les comptes locaux, que Kerberos n’est pas disponible en groupe de travail et réservé au domaine, et que les ordinateurs de TrustedHosts ne sont pas authentifiés et peuvent recevoir des identifiants, d’où la nécessité de les limiter au minimum. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8
-
Microsoft Learn, Invoke-Command. Sur le fait qu’Invoke-Command permet d’exécuter une commande sur plusieurs ordinateurs en une seule fois, sur la distinction entre une connexion ponctuelle via -ComputerName et l’utilisation d’une PSSession via -Session, et sur des paramètres comme -ArgumentList ou -FilePath. ↩ ↩2 ↩3
-
Microsoft Learn, PowerShell Remoting FAQ. Sur le fait que la valeur par défaut du nombre de connexions simultanées est 32, modifiable via le paramètre ThrottleLimit, que la sortie des commandes distantes est sérialisée en CLIXML et revient comme un objet désérialisé (sans méthodes), et que le résultat d’Invoke-Command reçoit une propriété permettant d’identifier son origine. ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, about_Remote_Output. Sur le fait que la sortie des commandes distantes devient, après sérialisation/désérialisation, un instantané réduit aux propriétés, et que les résultats reviennent dans l’ordre d’arrivée, d’où l’intérêt de les retrier avec PSComputerName. ↩ ↩2 ↩3
-
Microsoft Learn, Making the second hop in PowerShell Remoting. Sur le scénario du problème du second hop, la liste des parades et leur ordre de préférence (CredSSP, délégation Kerberos contrainte basée sur les ressources, JEA, etc.), le fait que CredSSP mette les identifiants en cache à distance avec un risque en cas de compromission et soit désactivé par défaut, et un exemple de transmission des identifiants via $Using:cred dans un ScriptBlock. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8
-
Microsoft Learn, Migrating from Windows PowerShell 5.1 to PowerShell 7. Sur le fait que, dans un environnement où WinRM est activé, PowerShell 7 se connecte par défaut via le point de terminaison existant de Windows PowerShell 5.1 (Microsoft.PowerShell), et que créer le point de terminaison propre à PowerShell 7 nécessite d’exécuter Enable-PSRemoting. ↩ ↩2
-
Microsoft Learn, Enter-PSSession. Sur le fait qu’Enter-PSSession démarre une session interactive avec un seul ordinateur distant, qu’on la termine avec exit/Exit-PSSession, qu’être membre du groupe Administrators côté distant est requis, et que la spécification par adresse IP nécessite une configuration HTTPS ou une inscription dans TrustedHosts. ↩ ↩2 ↩3 ↩4
-
Microsoft Learn, How to configure WINRM for HTTPS (KB 2019527). Sur les exigences de certificat nécessaires à l’écouteur HTTPS (certificat d’authentification serveur de l’ordinateur local, CN correspondant au nom d’hôte, non expiré, non révoqué, non auto-signé), la procédure de vérification via le composant logiciel enfichable Certificats, la configuration via winrm quickconfig -transport:https, la vérification via winrm enumerate winrm/config/listener, les ports HTTP 5985/HTTPS 5986 depuis Windows 7, et l’erreur 0x80338115 en l’absence de certificat approprié ainsi que les attributs de certificat à vérifier. ↩ ↩2 ↩3
-
Microsoft Learn, about_Remote_Variables. Sur le modificateur de portée $using: permettant d’utiliser des variables locales dans une commande exécutée à distance, sur le fait que la valeur est transmise comme une copie indépendante dans une session distante, et sur la perte des méthodes due à la sérialisation. ↩ ↩2
-
Microsoft Learn, New-PSSession. Sur le fait que New-PSSession crée une connexion persistante (PSSession), son usage pour exécuter plusieurs commandes partageant des données, le fait qu’une spécification par -ComputerName crée une connexion ponctuelle refermée après chaque commande, et la prise en charge des connexions basées sur SSH. ↩ ↩2 ↩3
-
Microsoft Learn, Running Remote Commands. Sur l’exécution de fichiers de script via Invoke-Command (-FilePath), et sur le fait qu’une session persistante créée avec New-PSSession conserve l’état, comme les variables, d’une commande à l’autre. ↩
-
Microsoft Learn, Overview of Just Enough Administration (JEA). Sur le fait que JEA soit une technologie de sécurité permettant une administration déléguée sur ce que PowerShell gère, la possibilité de limiter les applets de commande, fonctions et commandes externes exécutables, la réduction du nombre de comptes administrateur via les comptes virtuels ou les comptes de service gérés de groupe, et la traçabilité des actions via les transcriptions et les journaux. ↩
Articles associés
Articles récents partageant les mêmes étiquettes, pour approfondir des sujets proches.
Bien appeler un exe externe depuis PowerShell — les pièges des guillemets d'arguments, du code de sortie et de l'encodage
Appeler robocopy ou un EXE interne depuis PowerShell casse parfois les arguments, empêche de récupérer le code de sortie, ou produit une ...
Gérer les informations d'identification en toute sécurité sous PowerShell — bannir les mots de passe en clair de vos scripts
Un guide pratique pour faire migrer les mots de passe en clair d'un script PowerShell vers un stockage sécurisé : la réalité et les limit...
Politique d'exécution PowerShell et signature de scripts — Guide pratique pour sortir de l'exploitation « on colmate avec Bypass »
La politique d'exécution de PowerShell est « un dispositif de sécurité, pas une frontière de sécurité ». Cet article présente les différe...
Automatiser le déploiement de postes avec winget et PowerShell — Rendre le manuel de procédure exécutable
Ce guide explique comment rendre reproductible la configuration des PC des nouveaux employés : installation d'applications et export/impo...
Renforcer la sécurité de PowerShell — journalisation, AMSI, mode de langage, JEA
Ce guide rassemble la pratique pour utiliser PowerShell en toute sécurité sans l'interdire : activation de la journalisation des blocs de...
Sujets associés
Ces pages replacent le sujet dans un contexte plus large de services et de décisions.
Thèmes techniques Windows
Portail des sujets sur le développement Windows, l'analyse des incidents et la valorisation des actifs existants.
Services liés à ce sujet
Cet article est directement lié aux services suivants.
Développement d'applications Windows
Applications métier, intégration d'équipements et outils de communication, des besoins au développement.
Questions fréquentes
Questions souvent posées lors d’une consultation sur le sujet de cet article.
- Que se passe-t-il quand on exécute Enable-PSRemoting ?
- En interne, Set-WSManQuickConfig est exécuté : le service WinRM est démarré et son démarrage automatisé, un écouteur acceptant les requêtes sur n'importe quelle adresse IP est créé, l'exception de pare-feu pour les communications WS-Management est activée, et la configuration de session (le point de terminaison) est activée avec l'autorisation d'accès à distance qui va avec. C'est activé par défaut sous Windows Server, mais il faut l'exécuter soi-même sous les éditions clientes de Windows. Cela n'est nécessaire que du côté qui reçoit la connexion ; le côté qui se connecte n'en a pas besoin.
- Que faut-il pour utiliser PowerShell Remoting dans un environnement en groupe de travail (sans domaine) ?
- En l'absence de domaine, l'authentification Kerberos n'est pas disponible, ce qui bascule sur NTLM. La forme de base consiste, côté connexion, à inscrire la machine cible dans la liste TrustedHosts de WSMan et à transmettre explicitement les identifiants avec -Credential. Cela dit, une machine inscrite dans TrustedHosts n'est pas authentifiée (aucune vérification d'usurpation) avant l'envoi des identifiants, donc n'inscrivez que les noms d'hôte strictement nécessaires plutôt qu'un joker, et envisagez si possible de configurer un écouteur HTTPS (5986).
- Pourquoi ne peut-on pas appeler de méthodes sur l'objet résultat d'Invoke-Command ?
- Parce que la sortie d'une commande distante est sérialisée en XML (CLIXML) pour être envoyée sur le réseau, puis reconstruite en local comme un objet désérialisé. C'est un instantané des propriétés au moment de l'exécution, pas un objet vivant, et il n'a donc pas de méthodes. Une opération comme arrêter un service ne doit pas appeler de méthode côté local : elle doit s'exécuter à l'intérieur du ScriptBlock, donc côté distant.
- Qu'est-ce que le problème du second hop (double saut) ?
- C'est le problème où, depuis le PC A, on entre par Remoting sur le serveur B, puis on essaie depuis B d'accéder à un autre serveur C (un serveur de fichiers, par exemple) — et c'est refusé. Les authentifications Kerberos/NTLM par défaut n'envoient pas les identifiants eux-mêmes à B, donc B ne peut pas s'authentifier auprès de C en votre nom. Les parades incluent la transmission explicite des identifiants dans le ScriptBlock, la délégation Kerberos contrainte basée sur les ressources, ou CredSSP (risque accru, car les identifiants sont transmis au serveur distant) ; le choix dépend des exigences.
- N'importe qui peut-il se connecter à PowerShell Remoting ?
- Non. Par défaut, seuls les membres du groupe Administrators de l'ordinateur distant peuvent se connecter. De plus, la session établie après connexion s'exécute dans le contexte de l'utilisateur connecté, donc le contrôle d'accès du système d'exploitation s'applique normalement. Cela reste toutefois une porte d'entrée puissante pour un administrateur : combinez-la avec une défense en profondeur — revue des règles de pare-feu, écouteur HTTPS, restriction aux seuls administrateurs nécessaires.
Profil de l’auteur
Page de présentation de l’auteur de l’article.
Go Komura
Représentant de KomuraSoft LLC
Spécialisé dans le développement de logiciels Windows, le conseil technique et l’analyse de pannes, notamment pour les systèmes existants et les incidents difficiles à reproduire.