Catégories

Configurer Remote PowerShell (WinRM) dans un WORKGROUP

Introduction

On va voir dans ce billet comment, dans un contexte privé (WORKGROUP, pas de nom de domaine ni de serveur AD) mettre en oeuvre PowerShell en mode remote. On mettra en oeuvre 2 méthodes différentes.

L'objectif est de pouvoir gérer les machines de la tribu à partir d'un seul terminal.

Le set-up

  • Machine locale de l'administrateur = 5PRO-PHILIPPE = 192.168.1.49 = Win 11 Pro 22H2
  • Machine distante utilisateur = PC-MARTINE = 192.168.1.30 = Win10 Pro 22H2
  • Machine distante utilisateur = VIRT11-PHILIPPE = 192.168.1.15 = Win 11 Pro 22H2

Afin de fixer le vocabulaire

  • La machine locale est un client.
  • La machine distante est un serveur, un hôte

Note

Il faut disposer sur chaque machine distante d'un compte administrateur de type local. La méthode ci-dessous ne fonctionne PAS, par exemple, si la machine distante est un PC qui utilise HELLO et la reconnaissance faciale pour connecter l'utilisateur administrateur. Elle ne fonctionne pas non plus si l'administrateur de la machine distante se logue avec son compte Microsoft.

Sur de telles machines il faut donc créer un compte administrateur local. Ne passez pas à la suite tant que vous n'avez pas de compte admin local. N'hésitez pas à lire la fin de cette section du billet si besoin.

Sur la machine distante (user)

Ouvrir une console en mode administrateur

  • WIN + X, i
    • Cela veut dire qu'il faut presser les touches Windows et 'x' simultanément puis appuyer sur la touche 'i'

Vérifier que le réseau est privé

Get-NetConnectionProfile

Name                     : Livebox-AAE0
InterfaceAlias           : Wi-Fi
InterfaceIndex           : 10
NetworkCategory          : Private
DomainAuthenticationKind : None
IPv4Connectivity         : Internet
IPv6Connectivity         : Internet

Ci-dessus il n'y a rien à faire (NetworkCategory est égal à Private)

Si ce n'est pas lisible, cliquez sur les images pour les agrandir. 👓

Si besoin, c'est le cas ci-dessus, configurer le réseau en mode privé. Il faut utiliser l'InterfaceIndex de la sortie précédente. On vérifie ensuite que le réseau est bien privé.

Set-NetConnectionProfile -InterfaceIndex 6 -NetworkCategory Private
Get-NetConnectionProfile

Activer le service WinRM

Vérifier l'état du service :

Get-Service -Name '*WinRM*' 
WinRM fonctionne. On est bon de ce côté-là.
WinRM ne tourne PAS sur cette machine distante

Si WinRM ne tourne PAS (cas ci-dessus) il faut l'activer :

Enable-PSRemoting

Vérifier l'état du firewall

Get-NetFirewallRule -DisplayName "Gestion à distance de Windows (HTTP-Entrée)"

Vérifier dans la description que le port est bien 5985. Ci-dessous on voit que tout est OK. Voir la valeur de l'attribut 'Enabled' (6eme attribut).

Par contre, sur cette machine distante, la règle n'est pas encore active :

Si la règle n'est pas active alors il faut la mettre en route puis vérifier que ça s'est bien passé.

Enable-NetFirewallRule -DisplayName "Gestion à distance de Windows (HTTP-Entrée)"
Get-NetFirewallRule -DisplayName "Gestion à distance de Windows (HTTP-Entrée)"

On en a terminé avec la ou les machines distantes

Sur la machine locale (Administrateur)

Ouvrir une console en mode administrateur

  • WIN + X, i

Vérifier la communication avec la machine distante

Sur le port 5985

Test-NetConnection 192.168.1.30 –Port 5985

ComputerName     : 192.168.1.30                   
RemoteAddress    : 192.168.1.30                                                                                         
RemotePort       : 5985
InterfaceAlias   : Wi-Fi                                                                                                
SourceAddress    : 192.168.1.49                                                                                         
TcpTestSucceeded : True

Vérifier que WinRM fonctionne sur la machine distante

Test-WSMan 192.168.1.30

wsmid           : http://schemas.dmtf.org/wbem/wsman/identity/1/wsmanidentity.xsd
ProtocolVersion : http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd
ProductVendor   : Microsoft Corporation
ProductVersion  : OS: 0.0.0 SP: 0.0 Stack: 3.0

Tester l'ouverture d'une session distante PowerShell

Avec la commande Enter-PSSession et l'adresse IP de la machine distante

Il est possible (voir ci-dessus) que cela ne fonctionne pas car, par défaut, l'authentification supportée est Kerberos.

  • Retrouver les types d'authentification supportées avec la commande Get-ChildItem invoquée sur WSMAN.
Get-ChildItem -Path WSMan:\localhost\Service\Auth\

   WSManConfig : Microsoft.WSMan.Management\WSMan::localhost\Service\Auth

Type            Name                           SourceOfValue   Value
----            ----                           -------------   -----
System.String   Basic                                          false
System.String   Kerberos                                       true
System.String   Negotiate                                      true
System.String   Certificate                                    false
System.String   CredSSP                                        false
System.String   CbtHardeningLevel                              Relaxed

Se connecter avec la méthode trusted hosts

Je considère que les étapes précédentes, tant sur la machine distante que sur la machine locale, ont été franchies avec succès.

  • Lister les hôtes de confiance disponibles sur la machine locale.
get-Item WSMan:\localhost\Client\TrustedHosts

   WSManConfig : Microsoft.WSMan.Management\WSMan::localhost\Client

Type            Name                           SourceOfValue   Value
----            ----                           -------------   -----
System.String   TrustedHosts
  • Ajouter les 2 machines distantes avec Set-Item
  • Vérifier la liste des hôtes de confiance
Set-Item WSMan:\localhost\Client\TrustedHosts -Value 192.168.1.15 -Concatenate
Configuration de la sécurité WinRM.
Cette commande modifie la liste TrustedHosts pour le client WinRM. Les ordinateurs figurant dans la liste TrustedHosts
ne sont pas nécessairement authentifiés. Or, le client risque d'envoyer des informations d'identification à destination
 de ces ordinateurs. Êtes-vous sûr de vouloir modifier cette liste ?
[O] Oui  [N] Non  [S] Suspendre  [?] Aide (la valeur par défaut est « O ») : O


Set-Item WSMan:\localhost\Client\TrustedHosts -Value 192.168.1.30 -Concatenate
Configuration de la sécurité WinRM.
Cette commande modifie la liste TrustedHosts pour le client WinRM. Les ordinateurs figurant dans la liste TrustedHosts
ne sont pas nécessairement authentifiés. Or, le client risque d'envoyer des informations d'identification à destination
 de ces ordinateurs. Êtes-vous sûr de vouloir modifier cette liste ?
[O] Oui  [N] Non  [S] Suspendre  [?] Aide (la valeur par défaut est « O ») : O


get-Item WSMan:\localhost\Client\TrustedHosts
   WSManConfig : Microsoft.WSMan.Management\WSMan::localhost\Client
Type            Name                           SourceOfValue   Value
----            ----                           -------------   -----
System.String   TrustedHosts                                   192.168.1.15,192.168.1.30
  • Se connecter à la machine distante
Enter-PSSession -ComputerName 192.168.1.15 -Credential admin

Où 'admin' est l'identifiant d'un administrateur qui a un compte local. J'insiste car j'ai perdu pas mal de temps là-dessus 😀. S'il faut créer un compte local admin, il ne faut pas oublier de l'activer en ouvrant au moins une fois sa session (je suis pas sûr de mon coup à 100% mais je préfère mettre ceinture et bretelles)

Lorsqu'on ouvre la session sur la machine distante avec Enter-PSSession il faut saisir le mot de passe de l'utilisateur 'admin'

Si tout se passe bien on se retrouve sur la machine distante.

Il faut noter l'adresse IP en début de prompt qui permet de savoir qu'on est en remote.

Tout se passe alors comme si on était en local et on peut utiliser tout ce que l'on sait de PowerShell (en ce qui me concerne ça va être vite fait... 😁)

On peut aussi utiliser Invoke-Command mais à ce stade c'est assez lourd car il faut indiquer les credentials à chaque invocation.

Par contre, coup de pot (ou pas) comme l'admin a le même mot de passe sur les 2 machines distantes on peut lancer la même commande sur les 2 machines en parallèle (voir les 2 adresses IP passées dans la commande) puis récupérer les résultats sur la machine locale. Ça c'est top. Je suis bluffé.

Voir les 2 adresses IP différentes dans la dernière colonne.

Malheureusement

  • Je n'arrive pas à me connecter en utilisant le nom des machines plutôt que les adresses IP
  • Je dois toujours utiliser le paramètre -Credential. Faut que je trouve un truc.

Il est temps d'utiliser un autre mode d'identification.

Se connecter avec un certificat

Je considère que les étapes qui précèdent la section "Se connecter avec la méthode trusted hosts" ont été franchies avec succès tant sur la machine distante (user) que sur la machine locale (admin).

On va générer sur la machine distante un certificat SSL de type self-signed certificate qu'on transfèrera à la machine locale et qui sera utilisé lors des connexions pour encrypter le trafic WinRM. En anglais dans le texte on va faire du WinRM over HTTPS.

Générer un certificat sur la machine distante

Saisir les commandes suivantes

$hostname = $env:COMPUTERNAME
$hostIP=(Get-NetAdapter | Get-NetIPAddress).IPv4Address | Out-String
$RemoteCert = New-SelfSignedCertificate -DnsName $hostName, $hostIP -CertStoreLocation Cert:\LocalMachine\My
$RemoteCert | Format-List -Property *

On peut vérifier le certificat sur la machine cible en suivant les étapes ci-dessous

  • WIN, 'mmc'
  • CTRL + M
  • Certificats (liste de gauche)
  • Bouton 'Ajouter >'
  • Un compte d'ordinateur
  • Ordinateur local
  • Terminer
  • OK
  • On retrouve le certificat
  • Double clic sur le certificat. Il faut noter qu'il est valide 1 an

Sécuriser la communication

  • Sur la machine cible
  • Ajouter un listener HTTPS et le lier au précédent certificat $RemoteCert
New-Item -Path WSMan:\localhost\Listener\ -Transport HTTPS -Address * -CertificateThumbPrint $RemoteCert.Thumbprint -Force
  • Lister les écouteurs afin de confirmer que tout est OK
    • Il doit y en avoir 2. Un sur HTTP (utilisé précédemment dans la méthode trusted hosts) et celui sur HTTPS qu'on vient de créer.
  • Ouvrir le port 5986 dans le firewall
    • Les communications HTTP et HTTPS passent respectivement via les ports 5985 et 5986
New-NetFirewallRule -Displayname 'Gestion à distance de Windows (HTTPS-Entrée)' -Name 'WINRM-HTTPS-In-TCP-NoScope' -Profile Private -LocalPort 5986 -Protocol TCP
Vaut mieux mettre -Profile Private que -Profile Any comme ci-dessus
  • Redémarrer WinRM
Restart-Service WinRM
  • Exporter le certificat
    • La machine dispose d'un répertoire Public auquel on pourra accéder depuis la machine locale de l'administrateur. Le certificat peut très bien être sauvegardé sur le bureau ou ailleur.
Export-Certificate -Cert $RemoteCert -FilePath "c:\Users\Public\Documents\$env:COMPUTERNAME.cer"
  • Importer le certificat sur la machine locale (Admin) d'une façon ou d'une autre
  • Quand le certificat est sur le disque dur, on peut faire un clic droit sur le nom du certificat dans File Explorer et 'Installer le certificat'
  • Sinon, si par exemple on a copié le certificat sur le bureau on peut utiliser la commande suivante
Import-Certificate -FilePath C:\Users\phili\OneDrive\Bureau\VIRT11-PHILIPPE.cer -CertStoreLocation Cert:\LocalMachine\root\
  • Comme précédemment, on peut utiliser la console de management (MMC) pour vérifier que le certificat est bien importé.
  • On peut alors ouvrir une session sur la machine distante en utilisant son nom et une liaison cryptée. Youpi !
Enter-PSSession -Computername VIRT11-PHILIPPE -UseSSL -Credential admin
  • Idem pour invoquer une commande
Invoke-Command -ComputerName VIRT11-PHILIPPE -UseSSL -Credential admin {get-eventlog -LogName System -new 3} 

On peut s'amuser (ou anticiper un script) avec les lignes suivantes

$UserName = 'admin'
$Password = 'MyTopSecretPasswd'
$SecPassword = ConvertTo-SecureString $Password -AsPlainText -Force
$CredObject = New-Object System.Management.Automation.PSCredential ($UserName, $SecPassword)
Invoke-Command -ComputerName VIRT11-PHILIPPE -UseSSL -Credential $credObject {get-eventlog -LogName System -new 3}

Remarques

Firewall - Port 5985

Quand je vais voir dans le firewall de la machine distante VIRT11-PHILIPPE, voilà ce que je vois. Les règles sont classées par N° de port.

Je pense

  1. Qu'il faut désactiver la première règle dont le profil est public
  2. Modifier le profil de la seconde pour ne garder qu'un profil privé

Dans le premier cas il suffit de double cliquer sur la règle et de décocher la case Activé

Dans le second cas, double cli sur la règle, onglet Avancé, ne laissé coché que la case Privé.

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

  

  

  

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.