Windows Server op een VPS instellen: de eerste stappen
De checklist na de oplevering, in de juiste volgorde: licentie controleren, wachtwoord instellen, tijdzone, updates, firewall, RDP beveiligen, schijven en rollen. Inclusief de plekken waar het misgaat.
Een net opgeleverde Windows Server ziet eruit alsof hij klaar is: RDP antwoordt, het bureaublad verschijnt, Serverbeheer start op. Precies daar zit de valkuil. Tussen "RDP antwoordt" en "geschikt voor productie" zit ongeveer twintig minuten werk, en de volgorde daarvan bepaalt of u er daarna nog in komt.
Hieronder staan de stappen in de volgorde waarin ze uitgevoerd moeten worden, telkens met het controlecommando en met de foutmeldingen letterlijk.
Eerst de licentie regelen, niet als laatste
Windows Server zit niet in de serverprijs. KernelHost is geen Microsoft-SPLA-partner en verhuurt geen Windows-licenties. Windows draait hier volgens het model Bring Your Own License: de licentie koopt u bij een gecertificeerde Microsoft-partner of rechtstreeks bij Microsoft, en u brengt hem zelf in.
Voor testen, evalueren en migratieproeven bestaat de gratis evaluatieversie van Microsoft met een looptijd van 180 dagen. Die is volwaardig, alleen in tijd beperkt en niet voor productie bedoeld.
Controleer allereerst wat er op de server daadwerkelijk draait:
slmgr /dlv
slmgr /xpr
slmgr /dlv toont de naam van de editie. Staat daar ServerStandardEval of ServerDatacenterEval, dan draait er een evaluatieversie. slmgr /xpr noemt de vervaldatum in gewone taal. Beide commando's openen een pop-upvenster, wat op Server Core in de weg zit. Gebruik daar in plaats daarvan cscript C:\Windows\System32\slmgr.vbs /dlv.
Wat er gebeurt als de 180 dagen verstreken zijn
De server blijft draaien, maar de Windows License Monitoring Service sluit hem na ongeveer een uur draaien af, telkens opnieuw. Rechtsonder verschijnt een watermerk met de mededeling dat de Windows-licentie is verlopen. Wie dat voor het eerst ziet, zoekt meestal urenlang naar een hardware- of stuurprogrammafout, omdat het patroon op een watchdog lijkt.
De nette uitweg is de overstap naar een echte licentie. Dat kan zonder herinstallatie:
DISM /Online /Set-Edition:ServerStandard /ProductKey:XXXXX-XXXXX-XXXXX-XXXXX-XXXXX /AcceptEula
Drie punten waarop dit regelmatig strandt:
- Het werkt alleen van Eval naar de volledige versie met dezelfde naam of hoger. Van Datacenter Evaluation terug naar Standard voert DISM niet uit.
- De sleutel moet een retail-, MAK- of KMS-sleutel zijn. Past hij niet, dan meldt DISM Error: 1168 of de licentieservice 0xC004F050 met de mededeling dat de productcode ongeldig is. Dat betekent bijna nooit "vervalste sleutel", maar "verkeerd sleuteltype voor deze weg".
- Een domeincontroller laat zich niet van Evaluation naar Retail omzetten. Wie op de evaluatieversie al
Install-ADDSForestheeft uitgevoerd, moet die rol eerst weer afbouwen. Dat is de duurste fout uit dit artikel, en daarom staat de licentievraag hier bovenaan en niet aan het eind.
Nog een opmerking over de installatiebron: eigen ISO-images kunt u bij KernelHost niet uploaden, Windows komt uit de imagecatalogus in het klantenpaneel. De licentie brengt u zelf mee, het image staat er al.
Het administratorwachtwoord wijzigen zonder uzelf buiten te sluiten
Het meegeleverde wachtwoord staat in de opleveringsmail en hoort meteen vervangen te worden. De gebruikelijke weg via net user Administrator * werkt, maar heeft als nadeel dat hij bij een overtreding van het beleid slechts een summiere melding geeft. Beter:
$pw = Read-Host -AsSecureString -Prompt "Nieuw wachtwoord"
Set-LocalUser -Name "Administrator" -Password $pw
Komt er Het wachtwoord voldoet niet aan de vereisten voor de wachtwoordcomplexiteit, dan grijpt het lokale beleid in: minstens acht tekens en drie van de vier tekenklassen. De geldende waarden controleert u met net accounts.
Zinvoller dan het account hernoemen is een tweede, apart benoemd beheerdersaccount. Daarmee houdt u een weg terug als het ene account vergrendeld raakt:
$pw = Read-Host -AsSecureString -Prompt "Wachtwoord voor svcadmin"
New-LocalUser -Name "svcadmin" -Password $pw -PasswordNeverExpires
Add-LocalGroupMember -SID "S-1-5-32-544" -Member "svcadmin"
Waarom de SID en niet de groepsnaam? Omdat de beheerdersgroep op een Duits systeem Administratoren heet en op een Engels systeem Administrators. Scripts die de naam hard vastleggen, breken bij de eerste taalwissel af met De opgegeven lokale groep bestaat niet. S-1-5-32-544 is op elke Windows dezelfde.
De vergrendelingsval die er onder Windows Server 2025 echt is
Tot en met Windows Server 2019 kon het ingebouwde Administrator-account via het netwerk niet vergrendeld raken. Sinds een cumulatieve update voor Server 2022, en standaard onder Windows Server 2025, is dat anders: de accountvergrendeling treedt in werking vanaf vijf mislukte pogingen, en ze treft ook de ingebouwde Administrator.
Op een VPS met een open poort 3389 betekent dat concreet: de inlogpogingen van geautomatiseerde scanners vergrendelen uw account nog voordat u zelf aan de beurt bent. U typt een juist wachtwoord in en krijgt toch Het gebruikersaccount dat wordt gebruikt, is vergrendeld en kan niet worden gebruikt om u aan te melden.
De weg eruit als het eenmaal gebeurd is:
- Log in via de console in het klantenpaneel in plaats van via RDP.
- Hef de vergrendeling op, ofwel door de vergrendelingsduur af te wachten (
net accountstoont die, standaard tien minuten) ofwel direct:
$u = [ADSI]"WinNT://$env:COMPUTERNAME/Administrator,user"
$u.IsAccountLocked = $false
$u.SetInfo()
De blijvende oplossing is niet de drempelwaarde omhoogdraaien, maar de bereikbaarheid van RDP beperken. Dat komt verderop aan bod. Pas daarna kunt u de drempel weer versoepelen, want dan komen er geen vreemde pogingen meer binnen.
Tijdzone en klok instellen voordat er iets wordt vastgelegd
Windows-images staan bijna altijd op UTC of op een Amerikaanse zone. Dat valt niemand op, totdat het eerste TLS-certificaat wordt geweigerd als "nog niet geldig" of gebeurtenislogboeken niet meer te rijmen zijn met die van andere systemen.
Get-TimeZone
Get-TimeZone -ListAvailable | Where-Object { $_.Id -like "*Europe*" }
Set-TimeZone -Id "W. Europe Standard Time"
"W. Europe Standard Time" dekt Amsterdam, Berlijn en Wenen af, inclusief de overgang naar zomertijd. De tijd zelf komt van de tijdservice, en daar zit het eigenlijke verschil tussen fysieke hardware en een virtuele server:
w32tm /query /source
w32tm /query /status
Staat er als bron Local CMOS Clock, dan haalt de server zijn tijd helemaal niet uit het netwerk. Op een gevirtualiseerd systeem loopt de klok dan zichtbaar weg, soms meerdere seconden per dag. Stel een echte bron in:
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
Het bewijs dat het goed zit: w32tm /query /source noemt nu een van de ingevoerde servers, en w32tm /query /status toont een Stratum-waarde kleiner dan 10 plus een plausibel tijdstip van de laatste synchronisatie. Meldt w32tm /resync daarentegen De computer is niet gesynchroniseerd omdat er geen tijdgegevens beschikbaar waren, dan blokkeert meestal de firewall de uitgaande UDP-poort 123, of de service draaide nog niet.
Sluit de server zich later bij een domein aan, dan neemt de domeincontroller de tijdverdeling over en moet de handmatige peerlijst er weer uit, anders hebt u twee concurrerende tijdbronnen.
Windows-updates, en wat te doen als ze blijven hangen
Patch vóór de installatie van rollen, niet erna. Anders installeert u rollen vanuit een oude stand en haalt u ze daarna een tweede keer door de updatelus.
Op Server Core doet sconfig dat, menupunt 6. Met bureaubladomgeving gaat het via de instellingen. Scriptbaar wordt het met de module PSWindowsUpdate:
Install-PackageProvider -Name NuGet -Force
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
Install-Module PSWindowsUpdate -Force
Import-Module PSWindowsUpdate
Get-WindowsUpdate
Mislukt het downloaden uit de PowerShell Gallery met Er is geen overeenkomst gevonden voor de opgegeven zoekcriteria of met een verbroken verbinding, dan ligt dat op oudere versies (Server 2016 en 2019) bijna altijd aan TLS. Voer in dezelfde sessie eerst dit uit:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Voor de eerste ronde is het verstandig de herstart zelf in de hand te houden:
Install-WindowsUpdate -AcceptAll -IgnoreReboot
Get-WURebootStatus -Silent
De eerste patchronde op een vers image duurt, afhankelijk van de ouderdom van dat image, 30 tot 60 minuten en vergt twee tot drie herstarts. Dat is normaal. Niet normaal is de melding Kan Windows-updates niet configureren. Wijzigingen worden ongedaan gemaakt tijdens het opstarten. De twee meest voorkomende oorzaken op een VPS: te weinig vrije ruimte op C: (onder ongeveer 10 GB wordt het krap) of een harde herstart midden in de configuratiefase. Controleer de ruimte met Get-Volume en zet de updateopslag terug: stop de services wuauserv en bits, hernoem C:\Windows\SoftwareDistribution en start de services weer.
Terzijde: voor Windows Server 2025 bestaat hotpatching, oftewel beveiligingsupdates zonder herstart. Sinds mei 2026 kost het niets meer, maar het vereist wel een koppeling met Azure Arc. Voor één enkele VPS is dat meestal meer moeite dan het oplevert.
Firewall: het profiel is belangrijker dan de regel
De Windows-firewall blijft aan. Altijd. Het gebruikelijke advies "even uitzetten om te testen" eindigt er op een publiek bereikbare server regelmatig mee dat hij uit blijft.
Get-NetFirewallProfile | Select-Object Name, Enabled
Get-NetConnectionProfile
De verreweg meest voorkomende firewallvergissing onder Windows: de regel bestaat, is ingeschakeld, en de toegang wordt toch geblokkeerd. De oorzaak is bijna altijd dat de regel geldt voor het profiel Privé of Domein, terwijl de netwerkkaart in het profiel Openbaar staat. Een VPS met een direct openbaar IP-adres belandt na de oplevering vaak precies daar. Controleer de koppeling van een regel expliciet:
Get-NetFirewallRule -Name "RemoteDesktop-UserMode-In-TCP" | Select-Object Name, Enabled, Profile, Action
En kijk ook eens na wat er inkomend eigenlijk allemaal is toegestaan:
Get-NetFirewallRule -Enabled True -Direction Inbound -Action Allow | Select-Object DisplayName, Profile | Sort-Object DisplayName
Wat op een VPS aan het open internet niets te zoeken heeft, is bestands- en printerdeling op TCP 445. Hebt u SMB nodig, dan door een tunnel en niet open. Een WireGuard-tunnel is daarvoor de meest rechttoe rechtaan oplossing, het opzetten van de tegenkant staat beschreven in WireGuard-VPN-server instellen.
Een ICMP-echo kunt u daarentegen beter wel toestaan, anders meldt uw monitoring de server als dood:
New-NetFirewallRule -DisplayName "ICMPv4 Echo inkomend" -Protocol ICMPv4 -IcmpType 8 -Direction Inbound -Action Allow
RDP beveiligen betekent niet de poort verplaatsen
Een andere poort vermindert de ruis in de logboeken en verder niets. Wilt u hem toch wijzigen, dan kan dat zonder herstart, dat staat beschreven in RDP-poort wijzigen zonder herstart. De eigenlijke beveiliging bestaat uit drie andere dingen.
Ten eerste: verificatie op netwerkniveau afdwingen. Zonder NLA bouwt Windows de sessie op voordat iemand zich heeft geïdentificeerd. Dat is precies het aanvalsoppervlak dat u niet wilt.
$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 betekent dat NLA actief is, SecurityLayer = 2 dwingt TLS af voor het opzetten van de verbinding.
Ten tweede: het bron-IP beperken. Dat is de maatregel met het grootste effect, en het is één regel. Hij snijdt wachtwoordaanvallen volledig af, en daarmee ook het vergrendelingsprobleem van hierboven.
Set-NetFirewallRule -Name "RemoteDesktop-UserMode-In-TCP" -RemoteAddress "203.0.113.10"
Set-NetFirewallRule -Name "RemoteDesktop-UserMode-In-UDP" -RemoteAddress "203.0.113.10"
De regelnaam is bewust de interne -Name en niet de weergavegroep, want die heet afhankelijk van de taal "Extern bureaublad" of "Remote Desktop". Meerdere adressen of een heel netwerk kan ook, bijvoorbeeld -RemoteAddress @("203.0.113.10","198.51.100.0/24").
En dan de belangrijke voorzorgsmaatregel: voer dit uit vanuit een bestaande RDP-sessie en laat daarnaast een tweede sessie openstaan. Typt u uw eigen IP-adres verkeerd, dan is de verbinding meteen weg. De weg terug is dan de console in het klantenpaneel. Wie thuis een wisselend IP-adres heeft, slaat deze stap beter over en maakt RDP in plaats daarvan alleen via VPN bereikbaar.
Ten derde: de vergrendelingsdrempel passend instellen, nadat de firewall dicht is:
net accounts /lockoutthreshold:10 /lockoutduration:15 /lockoutwindow:15
De drie RDP-fouten waar echt naar gezocht wordt
- Er is een verificatiefout opgetreden. De gevraagde functie wordt niet ondersteund. Dat is het CredSSP-geval uit CVE-2018-0886: de client is gepatcht, de server niet. De juiste oplossing is de patchstand op de server. De veelbesproken omweg via het register met
AllowEncryptionOracle = 2op de client zet precies dat lek weer open en mag, als het al gebeurt, alleen tot het einde van de patchronde blijven staan en hoort daarna weer weg. - De externe computer vereist verificatie op netwerkniveau, die door uw computer niet wordt ondersteund. Komt voor bij zeer oude clients. De server is hier juist ingesteld, werk de client bij in plaats van NLA uit te schakelen.
- Extern bureaublad kan geen verbinding maken met de externe computer. Mogelijke oorzaken hiervoor zijn: ... Deze melding is een verzamelbak. Ga op de server eerst na of er wel iets luistert:
Get-Service TermService
Get-NetTCPConnection -LocalPort 3389 -State Listen
Komt er een regel met 0.0.0.0:3389 terug, dan is de service in orde en zit de fout in de firewall of onderweg daarnaartoe. Komt er niets terug, dan is het de service of een gewijzigde poort. Antwoordt de server onder belasting helemaal niet meer en blijft ook ICMP uit, dan loont een blik in de richting van een aanval, daarbij past Server tegen DDoS-aanvallen beschermen.
Extra schijven in gebruik nemen
Een tweede schijf verschijnt na de toewijzing niet vanzelf in Verkenner. Hij staat nog op RAW en moet eerst geïnitialiseerd worden.
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 "Gegevens" -Confirm:$false
Get-Volume
GPT in plaats van MBR, altijd. MBR houdt bij 2 TB op, en die overstap doet later niemand graag. Vier struikelblokken:
- Schijf offline of schrijfbeveiligd.
Initialize-Diskmeldt dan De schijf bevindt zich in de offlinetoestand of De schijf is schrijfbeveiligd. Oplossing:Set-Disk -Number 1 -IsOffline $falseenSet-Disk -Number 1 -IsReadOnly $false. - Letter D: is bezet. Bij veel images hangt daar het virtuele station van de installatiebron.
New-Partitionbreekt af met De opgegeven stationsletter is niet beschikbaar. Controleer metGet-Volumeen wijk uit naar E:, of verplaats eerst het virtuele station. - Nummer verwisseld.
-DiskNumber 1is niet gegarandeerd de nieuwe schijf. Vergelijk inGet-Diskde grootte enPartitionStylevoordat u formatteert. Een formattering van nummer 0 treft de systeemschijf. - Na een uitbreiding van de opslag groeit C: niet mee. De extra ruimte ligt er ongepartitioneerd achter:
Update-HostStorageCache
$max = (Get-PartitionSupportedSize -DriveLetter C).SizeMax
Resize-Partition -DriveLetter C -Size $max
Meldt Resize-Partition hier De opgegeven grootte wordt niet ondersteund of Size Not Supported, dan ligt er tussen C: en de vrije ruimte een herstelpartitie. Die moet eerst verwijderd of naar het einde verplaatst worden, dat lukt niet met één commando en hoort niet zonder back-up te gebeuren.
Rollen en onderdelen installeren
Pas nu, na patchstand en firewall, komen de rollen erbij. Een blik op de huidige toestand:
Get-WindowsFeature | Where-Object Installed | Select-Object Name, DisplayName
Een webserver is één regel:
Install-WindowsFeature -Name Web-Server -IncludeManagementTools
Get-Service W3SVC
Invoke-WebRequest http://localhost -UseBasicParsing | Select-Object StatusCode
Komt StatusCode 200 terug, dan draait IIS lokaal. Dat hij ook van buitenaf bereikbaar is, staat daarmee nog niet vast, daarvoor zijn de bijbehorende firewallregel en een controle vanaf een tweede systeem nodig.
De klassieker onder de mislukkingen is .NET Framework 3.5. Dat zit niet in het draaiende systeem, maar moet alsnog uit de installatiebron worden bijgeladen. Zonder gekoppeld image komt er:
Fout: 0x800f081f
De bronbestanden zijn niet gevonden.
Op een VPS zonder eigen ISO hebt u twee wegen: het beleid zo instellen dat Windows de bestanden rechtstreeks bij Windows Update mag ophalen, of de map sources\sxs uit een image met hetzelfde buildnummer naar de server kopiëren en er met -Source naar verwijzen. Een ander buildnummer werkt niet, ook niet als het bij dezelfde Windows-versie hoort.
Nog twee punten over rollen: Uninstall-WindowsFeature -Name Web-Server -Remove verwijdert niet alleen de rol, maar ook de bijbehorende bestanden van de schijf. Dat scheelt ruimte, maar maakt een latere herinstallatie afhankelijk van een bron, met dezelfde 0x800f081f. En wie Active Directory installeert, kan beter eerst nog even naar boven scrollen: op een evaluatielicentie is dat een doodlopende weg.
Waaraan u ziet dat alles goed staat
Tot slot een ronde controlecommando's. Elk daarvan heeft een verwacht antwoord, en klopt er één niet, dan is de server nog niet klaar.
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
Verwacht wordt: een vervaldatum of "permanent geactiveerd", de Europese tijdzone, een echte tijdbron in plaats van de lokale klok, updates van vandaag of gisteren, alle drie de firewallprofielen op True, een RemoteAddress-beperking in plaats van Any, een recente wachtwoorddatum bij de Administrator en alle stations met een letter.
Daarna loont een laatste, vaak vergeten stap: verbreek de sessie niet zomaar door het venster te sluiten, maar meld u netjes af. Verbroken sessies blijven met hun geheugengebruik staan, en op een kleine VPS telt dat over weken op tot het punt waarop inloggen helemaal niet meer lukt.
Wordt er parallel een Linux-server opgezet, dan behandelt Nieuwe rootserver inrichten: de checklist dezelfde onderwerpen voor de andere kant, en SSH beveiligen en sleutel-login instellen is daar de tegenhanger van het hoofdstuk over RDP.
Veelgestelde vragen
Zit er een Windows Server-licentie bij de serverprijs in?
Wat gebeurt er als de 180 dagen van de evaluatieversie voorbij zijn?
Waarom word ik voortdurend uit mijn eigen server gesloten?
Hoe neem ik een tweede schijf onder Windows Server in gebruik?
Wat betekent de melding dat de gevraagde functie niet wordt ondersteund?
Waarom blokkeert de Windows-firewall terwijl de regel bestaat?
2026 KernelHost GmbH. Alle rechten voorbehouden. Deze handleiding is auteursrechtelijk beschermd. Publicatie op andere websites, geheel, gedeeltelijk of in bewerkte vorm, is zonder onze schriftelijke toestemming niet toegestaan. Citeren met bronvermelding en link is uitdrukkelijk welkom.

