Installer Windows Server sur un VPS : les premières étapes

Publié le 16 min de lecture

La checklist après la mise à disposition, dans le bon ordre : vérifier la licence, définir le mot de passe, fuseau horaire, mises à jour, pare-feu, sécurisation de RDP, disques et rôles. Y compris les endroits où cela dérape.

Un serveur Windows fraîchement livré a tout l'air d'être prêt : RDP répond, le bureau s'affiche, le Gestionnaire de serveur démarre. C'est précisément le piège. Entre « RDP répond » et « prêt pour la production », il y a environ vingt minutes de travail, et l'ordre dans lequel ces étapes sont faites décide si vous pourrez encore entrer ensuite.

Voici les étapes dans l'ordre où elles doivent être faites, chacune avec sa commande de contrôle et le libellé exact des messages d'erreur.

Clarifier la licence en premier, pas en dernier

Windows Server n'est pas compris dans le prix du serveur. KernelHost n'est pas partenaire Microsoft SPLA et ne loue pas de licences Windows. Windows fonctionne ici selon le modèle Bring Your Own License : la licence est obtenue auprès d'un partenaire Microsoft certifié ou directement chez Microsoft, puis apportée par le client.

Pour les tests, les évaluations et les répétitions de migration, il existe la version d'évaluation gratuite de Microsoft, valable 180 jours. Elle est complète, elle est seulement limitée dans le temps et n'est pas prévue pour la production.

Vérifiez tout d'abord ce qui tourne réellement sur le serveur :

slmgr /dlv
slmgr /xpr

slmgr /dlv affiche le nom de l'édition. Si vous y lisez ServerStandardEval ou ServerDatacenterEval, une évaluation est en cours. slmgr /xpr indique la date d'expiration en clair. Les deux commandes ouvrent une fenêtre pop-up, ce qui gêne sur Server Core. Utilisez-y plutôt cscript C:\Windows\System32\slmgr.vbs /dlv.

Ce qui se passe à l'expiration des 180 jours

Le serveur continue de fonctionner, mais le Windows License Monitoring Service l'arrête après environ une heure de fonctionnement, encore et encore. En bas à droite apparaît un filigrane indiquant que la licence Windows a expiré. Quand on voit cela pour la première fois, on cherche en général pendant des heures une panne matérielle ou un problème de pilote, parce que le schéma ressemble à celui d'un watchdog.

La sortie propre consiste à passer sur une vraie licence. Cela se fait sans réinstallation :

DISM /Online /Set-Edition:ServerStandard /ProductKey:XXXXX-XXXXX-XXXXX-XXXXX-XXXXX /AcceptEula

Trois points sur lesquels cela échoue régulièrement :

  • Le passage ne fonctionne que d'une version Eval vers la version complète du même nom, ou vers une édition supérieure. DISM ne redescend pas de Datacenter Evaluation vers Standard.
  • La clé doit être une clé Retail, MAK ou KMS. Si elle ne convient pas, DISM signale Erreur : 1168, ou le service de licence renvoie 0xC004F050 en indiquant que la clé de produit n'est pas valide. Cela ne veut presque jamais dire « clé contrefaite », mais « mauvais type de clé pour ce chemin ».
  • Un contrôleur de domaine ne peut pas être basculé d'Evaluation vers Retail. Si vous avez déjà exécuté Install-ADDSForest sur l'évaluation, vous devez d'abord retirer le rôle. C'est l'erreur la plus coûteuse de cet article, et c'est pour cela que la question de la licence figure tout en haut et non à la fin.

Une remarque sur la source d'installation : chez KernelHost, il n'est pas possible de téléverser ses propres images ISO, Windows provient du catalogue d'images de l'espace client. Vous apportez la licence, l'image est déjà là.

Changer le mot de passe administrateur sans se bloquer l'accès

Le mot de passe livré figure dans le mail de mise à disposition et doit être remplacé immédiatement. La voie habituelle par net user Administrator * fonctionne, mais elle a le défaut de ne renvoyer qu'un message très maigre en cas de violation des stratégies. Mieux vaut :

$pw = Read-Host -AsSecureString -Prompt "Nouveau mot de passe"
Set-LocalUser -Name "Administrator" -Password $pw

Si vous obtenez Le mot de passe ne respecte pas les exigences de complexité des mots de passe, c'est la stratégie locale qui s'applique : au moins huit caractères et trois classes de caractères sur quatre. Vous pouvez consulter les valeurs en vigueur avec net accounts.

Plus judicieux que de renommer le compte : créer un second compte administrateur nommé. Vous gardez ainsi une porte de retour si l'un des comptes est verrouillé :

$pw = Read-Host -AsSecureString -Prompt "Mot de passe pour svcadmin"
New-LocalUser -Name "svcadmin" -Password $pw -PasswordNeverExpires
Add-LocalGroupMember -SID "S-1-5-32-544" -Member "svcadmin"

Pourquoi le SID plutôt que le nom du groupe ? Parce que le groupe des administrateurs s'appelle Administrateurs sur un système français et Administrators sur un système anglais. Les scripts qui codent le nom en dur s'arrêtent au premier changement de langue avec Le groupe local spécifié n'existe pas. S-1-5-32-544 est identique sur tous les Windows.

Le piège du verrouillage, bien réel sous Windows Server 2025

Jusqu'à Windows Server 2019 inclus, le compte administrateur intégré ne pouvait pas être verrouillé par des connexions réseau. Depuis une mise à jour cumulative pour Server 2022, et par défaut sous Windows Server 2025, il en va autrement : le verrouillage de compte se déclenche au bout de cinq tentatives échouées, et il touche aussi l'administrateur intégré.

Sur un VPS dont le port 3389 est ouvert, cela signifie concrètement que les tentatives de connexion des scanners automatisés verrouillent votre compte avant même que vous n'ayez la main. Vous saisissez un mot de passe correct et vous obtenez malgré tout Le compte d'utilisateur référencé est verrouillé et ne peut pas être utilisé pour ouvrir une session.

La marche à suivre quand c'est arrivé :

  1. Se connecter par la console de l'espace client plutôt que par RDP.
  2. Lever le verrouillage, soit en attendant la fin de la durée de verrouillage (net accounts l'affiche, la valeur par défaut est de dix minutes), soit directement :
$u = [ADSI]"WinNT://$env:COMPUTERNAME/Administrator,user"
$u.IsAccountLocked = $false
$u.SetInfo()

La solution durable ne consiste pas à relever le seuil de verrouillage, mais à restreindre l'accessibilité de RDP. C'est le sujet plus bas. Ce n'est qu'ensuite que l'on peut de nouveau détendre le seuil, puisque plus aucune tentative extérieure n'arrive.

Régler le fuseau horaire et l'heure avant que quoi que ce soit ne soit journalisé

Les images Windows sont presque toujours réglées sur UTC ou sur un fuseau américain. Personne ne le remarque, jusqu'à ce que le premier certificat TLS soit rejeté comme « pas encore valide » ou que les journaux d'événements ne puissent plus être recoupés avec ceux des autres systèmes.

Get-TimeZone
Get-TimeZone -ListAvailable | Where-Object { $_.Id -like "*Europe*" }
Set-TimeZone -Id "W. Europe Standard Time"

« W. Europe Standard Time » couvre Vienne, Berlin et Zurich, changement d'heure d'été compris. L'heure elle-même vient du service de temps, et c'est là que se situe la vraie différence entre une machine physique et un serveur virtuel :

w32tm /query /source
w32tm /query /status

Si la source indiquée est Local CMOS Clock, le serveur ne va pas du tout chercher son heure sur le réseau. Sur un système virtualisé, l'horloge dérive alors de façon visible, parfois de plusieurs secondes par jour. Définissez une vraie source :

w32tm /config /manualpeerlist:"time.windows.com,0x9 at.pool.ntp.org,0x9" /syncfromflags:manual /update
Set-Service w32time -StartupType Automatic
Restart-Service w32time
w32tm /resync /force

La preuve que c'est en place : w32tm /query /source nomme désormais l'un des serveurs configurés, et w32tm /query /status affiche une valeur Stratum inférieure à 10 ainsi qu'une heure de dernière synchronisation plausible. Si w32tm /resync renvoie à la place L'ordinateur n'a pas resynchronisé car aucune donnée d'heure n'était disponible, c'est en général le pare-feu qui bloque le port UDP 123 sortant, ou le service qui ne tournait pas encore.

Si le serveur rejoint plus tard un domaine : le contrôleur de domaine prend alors en charge la distribution de l'heure et la liste de pairs manuelle doit être retirée, sinon vous avez deux sources de temps concurrentes.

Les mises à jour Windows, et que faire quand elles bloquent

Appliquez les correctifs avant d'installer des rôles, pas après. Sinon, vous installez des rôles à partir d'un état ancien et vous les faites ensuite passer une deuxième fois dans la boucle des mises à jour.

Sur Server Core, sconfig s'en charge, entrée de menu 6. Avec l'interface graphique, cela passe par les paramètres. Le module PSWindowsUpdate permet de scripter l'opération :

Install-PackageProvider -Name NuGet -Force
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
Install-Module PSWindowsUpdate -Force
Import-Module PSWindowsUpdate
Get-WindowsUpdate

Si le téléchargement depuis la PowerShell Gallery échoue avec Aucune correspondance n'a été trouvée pour les critères de recherche spécifiés ou avec une coupure de connexion, la cause est presque toujours TLS sur les versions plus anciennes (Server 2016 et 2019). À exécuter au préalable dans la même session :

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

Pour la première exécution, il vaut mieux garder le redémarrage sous contrôle :

Install-WindowsUpdate -AcceptAll -IgnoreReboot
Get-WURebootStatus -Silent

La première passe de correctifs sur une image fraîche dure de 30 à 60 minutes selon l'âge de l'image et demande deux à trois redémarrages. C'est normal. Ce qui ne l'est pas, c'est le message Échec de la configuration des mises à jour Windows. Annulation des modifications au démarrage. Les deux causes les plus fréquentes sur un VPS : trop peu d'espace libre sur C: (en dessous d'environ 10 GB, cela devient juste) ou un redémarrage brutal en pleine phase de configuration. Vérifiez l'espace avec Get-Volume et réinitialisez le magasin des mises à jour : arrêtez les services wuauserv et bits, renommez C:\Windows\SoftwareDistribution, redémarrez les services.

En marge : pour Windows Server 2025, il existe le hotpatching, c'est-à-dire des mises à jour de sécurité sans redémarrage. Depuis mai 2026, cela ne coûte plus rien, mais suppose un rattachement à Azure Arc. Pour un VPS isolé, c'est le plus souvent plus de travail que de bénéfice.

Pare-feu : le profil compte plus que la règle

Le pare-feu Windows reste activé. Toujours. Le conseil habituel qui consiste à « le désactiver un instant pour tester » se termine régulièrement, sur un serveur accessible publiquement, par un pare-feu qui reste désactivé.

Get-NetFirewallProfile | Select-Object Name, Enabled
Get-NetConnectionProfile

L'erreur de pare-feu de loin la plus fréquente sous Windows : la règle existe, elle est activée, et l'accès est malgré tout bloqué. La cause est presque toujours que la règle vaut pour le profil Privé ou Domaine, alors que la carte réseau se trouve dans le profil Public. Un VPS avec IP publique directe atterrit souvent exactement là après la mise à disposition. Vérifiez explicitement l'affectation d'une règle :

Get-NetFirewallRule -Name "RemoteDesktop-UserMode-In-TCP" | Select-Object Name, Enabled, Profile, Action

Et regardez une fois ce qui est réellement autorisé en entrée :

Get-NetFirewallRule -Enabled True -Direction Inbound -Action Allow | Select-Object DisplayName, Profile | Sort-Object DisplayName

Ce qui n'a rien à faire sur un VPS exposé à Internet, c'est le partage de fichiers et d'imprimantes sur le port TCP 445. Si vous avez besoin de SMB, faites-le passer par un tunnel plutôt qu'en clair. Un tunnel WireGuard est la voie la plus directe, la configuration du côté opposé est décrite dans Installer un serveur VPN WireGuard.

En revanche, vous devriez autoriser l'écho ICMP, sinon votre monitoring signalera le serveur comme mort :

New-NetFirewallRule -DisplayName "ICMPv4 Echo entrant" -Protocol ICMPv4 -IcmpType 8 -Direction Inbound -Action Allow

Sécuriser RDP ne veut pas dire déplacer le port

Un autre port réduit le bruit dans les journaux, rien de plus. Si vous voulez malgré tout le changer, cela se fait sans redémarrage, c'est décrit dans Changer le port RDP sans redémarrage. La véritable sécurisation repose sur trois autres points.

Premièrement : imposer l'authentification au niveau du réseau. Sans NLA, Windows ouvre la session avant que quiconque se soit authentifié. C'est exactement la surface d'attaque dont on ne veut pas.

$rdp = "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp"
Get-ItemProperty -Path $rdp -Name UserAuthentication, SecurityLayer
Set-ItemProperty -Path $rdp -Name UserAuthentication -Value 1
Set-ItemProperty -Path $rdp -Name SecurityLayer -Value 2

UserAuthentication = 1 signifie NLA actif, SecurityLayer = 2 impose TLS pour l'établissement de la connexion.

Deuxièmement : restreindre l'IP source. C'est la mesure qui a le plus d'effet, et elle tient en une ligne. Elle coupe entièrement les attaques par mot de passe, et donc aussi le problème de verrouillage de compte évoqué plus haut.

Set-NetFirewallRule -Name "RemoteDesktop-UserMode-In-TCP" -RemoteAddress "203.0.113.10"
Set-NetFirewallRule -Name "RemoteDesktop-UserMode-In-UDP" -RemoteAddress "203.0.113.10"

Le nom de règle employé est volontairement le -Name interne et non le groupe d'affichage, car celui-ci s'appelle « Bureau à distance » ou « Remote Desktop » selon la langue. Plusieurs adresses ou un réseau entier fonctionnent tout aussi bien, par exemple -RemoteAddress @("203.0.113.10","198.51.100.0/24").

Et voici la précaution importante : exécutez cela depuis une session RDP existante et laissez en parallèle une seconde session ouverte. Si vous faites une faute de frappe dans votre propre IP, la connexion est perdue sur-le-champ. Le chemin de retour est alors la console de l'espace client. Si votre IP change à la maison, sautez cette étape et rendez plutôt RDP accessible uniquement par VPN.

Troisièmement : régler le seuil de verrouillage comme il faut, une fois le pare-feu refermé :

net accounts /lockoutthreshold:10 /lockoutduration:15 /lockoutwindow:15

Les trois erreurs RDP que l'on cherche vraiment

  • Une erreur d'authentification s'est produite. La fonction demandée n'est pas prise en charge. C'est le cas CredSSP issu de CVE-2018-0886 : le client est corrigé, le serveur ne l'est pas. La bonne solution est le niveau de correctifs sur le serveur. Le contournement par le registre qui circule, avec AllowEncryptionOracle = 2 sur le client, rouvre exactement la faille et ne doit, si tant est qu'on l'emploie, être défini que jusqu'à la fin de la passe de correctifs, puis supprimé.
  • L'ordinateur distant nécessite une authentification au niveau du réseau, que votre ordinateur ne prend pas en charge. Se produit avec des clients très anciens. Le serveur est ici correctement configuré : mettez le client à jour au lieu de désactiver NLA.
  • Le Bureau à distance ne peut pas se connecter à l'ordinateur distant pour l'une des raisons suivantes : ... Ce message est un fourre-tout. Délimitez le problème sur le serveur en vérifiant si un service écoute seulement :
Get-Service TermService
Get-NetTCPConnection -LocalPort 3389 -State Listen

Si une ligne avec 0.0.0.0:3389 revient, le service est en ordre et l'erreur se situe dans le pare-feu ou sur le chemin qui y mène. Si rien ne revient, c'est le service ou un port modifié. Si le serveur ne répond plus du tout sous charge et que l'ICMP reste lui aussi sans réponse, un coup d'œil du côté d'une attaque en cours vaut la peine, et Protéger un serveur contre les attaques DDoS traite ce sujet.

Intégrer des disques supplémentaires

Un second disque n'apparaît pas de lui-même dans l'Explorateur après son affectation. Il est brut et doit être initialisé.

Get-Disk
Get-Disk | Where-Object PartitionStyle -eq 'RAW' | Initialize-Disk -PartitionStyle GPT
New-Partition -DiskNumber 1 -UseMaximumSize -DriveLetter D | Format-Volume -FileSystem NTFS -NewFileSystemLabel "Données" -Confirm:$false
Get-Volume

GPT plutôt que MBR, toujours. MBR arrive en bout de course à 2 TB, et personne n'aime faire la bascule après coup. Quatre pièges :

  • Disque hors connexion ou protégé en écriture. Initialize-Disk signale alors Le disque est à l'état hors connexion ou Le disque est protégé en écriture. Solution : Set-Disk -Number 1 -IsOffline $false et Set-Disk -Number 1 -IsReadOnly $false.
  • La lettre D: est occupée. Sur beaucoup d'images, c'est là qu'est monté le lecteur virtuel de la source d'installation. New-Partition s'interrompt avec La lettre de lecteur spécifiée n'est pas disponible. Vérifiez avec Get-Volume et basculez sur E:, ou déplacez d'abord le lecteur virtuel.
  • Numéro confondu. -DiskNumber 1 n'est pas forcément le nouveau disque. Comparez la taille et PartitionStyle dans Get-Disk avant de formater. Un formatage sur le numéro 0 vise le disque système.
  • Après une extension de stockage, C: ne grandit pas tout seul. L'espace supplémentaire reste non partitionné derrière :
Update-HostStorageCache
$max = (Get-PartitionSupportedSize -DriveLetter C).SizeMax
Resize-Partition -DriveLetter C -Size $max

Si Resize-Partition renvoie ici La taille spécifiée n'est pas prise en charge ou Size Not Supported, c'est qu'une partition de récupération se trouve entre C: et l'espace libre. Elle doit d'abord être supprimée ou déplacée en fin de disque, cela ne se fait pas en une seule commande et ne devrait pas se faire sans sauvegarde.

Installer les rôles et les fonctionnalités

C'est seulement maintenant, une fois les correctifs appliqués et le pare-feu en place, que viennent les rôles. Un coup d'œil sur l'état actuel :

Get-WindowsFeature | Where-Object Installed | Select-Object Name, DisplayName

Un serveur web tient en une ligne :

Install-WindowsFeature -Name Web-Server -IncludeManagementTools
Get-Service W3SVC
Invoke-WebRequest http://localhost -UseBasicParsing | Select-Object StatusCode

Si StatusCode 200 revient, IIS tourne en local. Cela ne dit pas encore qu'il est joignable depuis l'extérieur : il faut pour cela la règle de pare-feu correspondante et un test depuis un second système.

Le grand classique des échecs, c'est .NET Framework 3.5. Il ne se trouve pas dans le système en cours d'exécution, il doit être rechargé depuis la source d'installation. Sans image montée, vous obtenez :

Erreur : 0x800f081f
Les fichiers sources sont introuvables.

Sur un VPS sans ISO propre, vous avez deux voies : régler la stratégie de manière que Windows puisse récupérer les fichiers directement depuis Windows Update, ou copier sur le serveur le dossier sources\sxs issu d'une image portant le même numéro de build, puis le désigner avec -Source. Un autre numéro de build ne fonctionne pas, même s'il appartient à la même version de Windows.

Deux points supplémentaires sur les rôles : Uninstall-WindowsFeature -Name Web-Server -Remove ne retire pas seulement le rôle, mais aussi ses fichiers du disque. Cela économise de la place, mais rend la réinstallation ultérieure dépendante d'une source, avec le même 0x800f081f. Et si vous installez Active Directory, remontez d'abord en haut de cet article : sur une licence d'évaluation, c'est une impasse.

Comment reconnaître que tout est en place

Pour finir, une série de commandes de contrôle. Chacune a une réponse attendue, et si l'une d'elles ne correspond pas, le serveur n'est pas encore prêt.

slmgr /xpr
Get-TimeZone
w32tm /query /source
Get-HotFix | Sort-Object InstalledOn -Descending | Select-Object -First 5
Get-NetFirewallProfile | Select-Object Name, Enabled
Get-NetFirewallRule -Name "RemoteDesktop-UserMode-In-TCP" | Get-NetFirewallAddressFilter
Get-LocalUser | Select-Object Name, Enabled, PasswordLastSet
Get-Volume | Where-Object DriveLetter
Get-WindowsFeature | Where-Object Installed | Measure-Object

On attend : une date d'expiration ou « activé de façon permanente », le fuseau horaire européen, une vraie source de temps à la place de l'horloge locale, des mises à jour d'aujourd'hui ou d'hier, les trois profils de pare-feu sur True, une restriction RemoteAddress au lieu de Any, une date de mot de passe récente pour l'administrateur et tous les volumes avec une lettre.

Ensuite, une dernière étape souvent oubliée vaut la peine : ne coupez pas la session en fermant simplement la fenêtre, fermez-la proprement. Les sessions déconnectées restent en place avec leur consommation de mémoire, et sur un petit VPS cela s'additionne au fil des semaines jusqu'au point où plus aucune nouvelle connexion n'est possible.

Si un serveur Linux est mis en place en parallèle, Configurer un nouveau serveur root : la check-list couvre les mêmes sujets de l'autre côté, et Sécuriser SSH et configurer la connexion par clé y est le pendant de la section sur RDP.

Questions fréquentes

La licence Windows Server est-elle comprise dans le prix du serveur ?
Non. KernelHost n'est pas partenaire Microsoft SPLA et ne loue pas de licences Windows. Windows fonctionne en Bring Your Own License : la licence est obtenue auprès d'un partenaire Microsoft certifié ou directement chez Microsoft, puis apportée par le client. Pour les tests, la version d'évaluation gratuite de Microsoft, valable 180 jours, est disponible.
Que se passe-t-il à l'expiration des 180 jours de la version d'évaluation ?
Le serveur démarre encore, mais le Windows License Monitoring Service l'arrête après environ une heure de fonctionnement, et cela se répète. Un filigrane signalant la licence expirée apparaît sur le bureau. Avec une licence régulière, l'installation se bascule sans réinstallation : DISM /Online /Set-Edition:ServerStandard /ProductKey:... /AcceptEula.
Pourquoi suis-je sans cesse bloqué hors de mon propre serveur ?
Sous Windows Server 2025, le verrouillage de compte est actif par défaut à partir de cinq connexions échouées et concerne aussi le compte administrateur intégré. Avec le port 3389 ouvert, les tentatives de connexion automatisées verrouillent le compte en permanence. La solution n'est pas un seuil de verrouillage plus élevé, mais la restriction de la règle RDP à votre propre IP source avec Set-NetFirewallRule -Name RemoteDesktop-UserMode-In-TCP -RemoteAddress.
Comment intégrer un second disque sous Windows Server ?
Get-Disk l'affiche avec PartitionStyle RAW. Ensuite Initialize-Disk -PartitionStyle GPT, puis New-Partition -DiskNumber 1 -UseMaximumSize -DriveLetter D et Format-Volume -FileSystem NTFS. Si Windows signale un état hors connexion ou une protection en écriture, Set-Disk -IsOffline $false et Set-Disk -IsReadOnly $false résolvent le cas. Si D: est déjà occupée, basculez sur une autre lettre.
Que signifie le message indiquant que la fonction demandée n'est pas prise en charge ?
C'est l'erreur CredSSP issue de CVE-2018-0886. Le client a la mise à jour de sécurité, le serveur pas encore. La bonne solution est le niveau de correctifs sur le serveur, et non le contournement répandu par le registre avec AllowEncryptionOracle = 2 sur le client, car celui-ci rouvre la faille.
Pourquoi le pare-feu Windows bloque-t-il alors que la règle existe ?
Parce que les règles de pare-feu s'appliquent par profil réseau. Si la règle vaut pour Privé ou Domaine alors que la carte réseau est sur Public, elle ne s'applique pas. Un VPS avec IP publique atterrit souvent dans le profil Public après la mise à disposition. Get-NetConnectionProfile montre l'affectation, Get-NetFirewallRule avec la colonne Profile montre la portée de la règle.

Windows Server VPS RDP PowerShell Administration serveur Sécurité