Configurare Windows Server su un VPS: i primi passi
La checklist dopo l'attivazione, nell'ordine giusto: licenza, password, fuso orario, aggiornamenti, firewall, RDP sicuro, dischi e ruoli. Compresi i punti in cui le cose vanno storte.
Un Windows Server appena fornito sembra già pronto: RDP risponde, il desktop compare, Server Manager si avvia. È esattamente qui che sta la trappola. Tra "RDP risponde" e "pronto per la produzione" ci sono circa venti minuti di lavoro, e l'ordine in cui li fai decide se dopo riuscirai ancora a entrare.
Qui trovi i passaggi nell'ordine in cui vanno eseguiti, ognuno con il comando di verifica e con i messaggi di errore riportati alla lettera.
La licenza si chiarisce all'inizio, non alla fine
Windows Server non è compreso nel prezzo del server. KernelHost non è un partner Microsoft SPLA e non affitta licenze Windows. Qui Windows funziona secondo il modello Bring Your Own License: la licenza si acquista da un partner Microsoft certificato oppure direttamente da Microsoft, e viene portata dal cliente.
Per test, valutazioni e prove di migrazione esiste la versione di valutazione gratuita di Microsoft, con 180 giorni di durata. È completa in tutte le sue funzioni, ha solo un limite di tempo e non è pensata per la produzione.
Come prima cosa in assoluto, controlla che cosa gira davvero sul server:
slmgr /dlv
slmgr /xpr
slmgr /dlv mostra il nome dell'edizione. Se compare ServerStandardEval oppure ServerDatacenterEval, è in esecuzione una versione di valutazione. slmgr /xpr indica la data di scadenza in chiaro. Entrambi i comandi aprono una finestra popup, cosa scomoda su Server Core: lì usa invece cscript C:\Windows\System32\slmgr.vbs /dlv.
Che cosa succede quando scadono i 180 giorni
Il server continua a funzionare, ma il Windows License Monitoring Service lo spegne dopo circa un'ora di attività, e lo fa ripetutamente. In basso a destra compare una filigrana che segnala la licenza di Windows scaduta. Chi lo vede per la prima volta passa di solito ore a cercare un guasto hardware o un problema di driver, perché lo schema assomiglia a quello di un watchdog.
La via d'uscita pulita è il passaggio a una licenza vera, e non serve reinstallare:
DISM /Online /Set-Edition:ServerStandard /ProductKey:XXXXX-XXXXX-XXXXX-XXXXX-XXXXX /AcceptEula
Tre punti in cui la cosa fallisce regolarmente:
- Il passaggio funziona solo da Eval alla versione completa omonima oppure verso un'edizione superiore. Da Datacenter Evaluation all'indietro verso Standard, DISM non lo esegue.
- La chiave deve essere di tipo Retail, MAK o KMS. Se non è quella giusta, DISM segnala Error: 1168 oppure il servizio di licenza restituisce 0xC004F050 con l'indicazione che il product key non è valido. Quasi mai significa "chiave contraffatta", significa "tipo di chiave sbagliato per questa strada".
- Un domain controller non si può convertire da Evaluation a Retail. Chi ha già eseguito
Install-ADDSForestsulla versione di valutazione deve prima rimuovere il ruolo. È l'errore più costoso di tutto l'articolo, ed è il motivo per cui la questione della licenza sta qui in cima e non alla fine.
Una nota sulla fonte di installazione: su KernelHost non è possibile caricare immagini ISO proprie, Windows arriva dal catalogo di immagini nell'area clienti. La licenza la porti tu, l'immagine c'è già.
Cambiare la password di amministratore senza restare fuori
La password consegnata si trova nella mail di attivazione e va sostituita subito. La strada solita con net user Administrator * funziona, ma ha lo svantaggio di restituire un messaggio molto scarno quando si violano i criteri. Meglio così:
$pw = Read-Host -AsSecureString -Prompt "Nuova password"
Set-LocalUser -Name "Administrator" -Password $pw
Se compare La password non soddisfa i requisiti di complessità delle password, sta agendo il criterio locale: almeno otto caratteri e tre classi di caratteri su quattro. I valori in vigore li verifichi con net accounts.
Più utile che rinominare l'account è creare un secondo account amministrativo con un nome proprio. Così hai una via di ritorno se il primo account viene bloccato:
$pw = Read-Host -AsSecureString -Prompt "Password per svcadmin"
New-LocalUser -Name "svcadmin" -Password $pw -PasswordNeverExpires
Add-LocalGroupMember -SID "S-1-5-32-544" -Member "svcadmin"
Perché il SID e non il nome del gruppo? Perché su un sistema italiano il gruppo degli amministratori si chiama Amministratori e su uno inglese Administrators. Gli script che cablano il nome fisso si interrompono al primo cambio di lingua con Il gruppo locale specificato non esiste. S-1-5-32-544 invece è identico su qualsiasi Windows.
La trappola del blocco account che su Windows Server 2025 esiste davvero
Fino a Windows Server 2019 compreso, l'account amministratore integrato non poteva essere bloccato tramite gli accessi di rete. Da un aggiornamento cumulativo per Server 2022, e per impostazione predefinita su Windows Server 2025, le cose stanno diversamente: il blocco account scatta dopo cinque tentativi falliti e colpisce anche l'amministratore integrato.
Su un VPS con la porta 3389 aperta questo significa una cosa molto concreta: i tentativi di accesso degli scanner automatici ti bloccano l'account prima ancora che tu riesca a collegarti. Digiti una password corretta e ricevi comunque L'account utente utilizzato è bloccato e non può essere usato per l'accesso.
La via d'uscita, se è già successo:
- Accedi tramite la console nell'area clienti invece che via RDP.
- Sblocca l'account, aspettando che scada il tempo di blocco (
net accountslo mostra, il valore predefinito è dieci minuti) oppure direttamente:
$u = [ADSI]"WinNT://$env:COMPUTERNAME/Administrator,user"
$u.IsAccountLocked = $false
$u.SetInfo()
La soluzione definitiva non è alzare la soglia di blocco, ma limitare la raggiungibilità di RDP. Ne parliamo più avanti. Solo dopo si può allentare di nuovo la soglia, perché a quel punto i tentativi estranei non arrivano più.
Imposta fuso orario e ora prima che venga registrato qualsiasi log
Le immagini Windows sono quasi sempre impostate su UTC o su un fuso americano. Nessuno se ne accorge finché il primo certificato TLS non viene rifiutato come "non ancora valido" oppure i registri eventi non si lasciano più correlare con quelli di altri sistemi.
Get-TimeZone
Get-TimeZone -ListAvailable | Where-Object { $_.Id -like "*Europe*" }
Set-TimeZone -Id "W. Europe Standard Time"
"W. Europe Standard Time" copre Roma, Vienna e Berlino, cambio dell'ora legale incluso. L'ora vera e propria arriva dal servizio orario, ed è qui che sta la differenza reale tra una macchina fisica e un server virtuale:
w32tm /query /source
w32tm /query /status
Se come sorgente compare Local CMOS Clock, il server non prende affatto l'ora dalla rete. Su un sistema virtualizzato l'orologio va allora visibilmente alla deriva, a volte di diversi secondi al giorno. Imposta una sorgente vera:
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 prova che ha funzionato: w32tm /query /source ora indica uno dei server configurati e w32tm /query /status mostra un valore Stratum inferiore a 10 più un orario plausibile dell'ultima sincronizzazione. Se invece w32tm /resync segnala Il computer non è stato sincronizzato perché non erano disponibili dati sull'ora, di solito è il firewall a bloccare la porta UDP 123 in uscita, oppure il servizio non era ancora avviato.
Se il server entrerà più tardi in un dominio: a quel punto è il domain controller a distribuire l'ora e la lista manuale dei peer va tolta di nuovo, altrimenti ti ritrovi con due sorgenti orarie in concorrenza.
Aggiornamenti di Windows, e che fare quando si bloccano
Applica le patch prima di installare i ruoli, non dopo. Altrimenti installi ruoli partendo da uno stato vecchio e poi li fai passare una seconda volta per il ciclo degli aggiornamenti.
Su Server Core se ne occupa sconfig, voce di menu 6. Con l'interfaccia desktop si passa dalle impostazioni. Diventa scriptabile con il modulo PSWindowsUpdate:
Install-PackageProvider -Name NuGet -Force
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
Install-Module PSWindowsUpdate -Force
Import-Module PSWindowsUpdate
Get-WindowsUpdate
Se il download dalla PowerShell Gallery fallisce con Non è stata trovata alcuna corrispondenza per i criteri di ricerca specificati oppure con una connessione interrotta, sulle versioni più vecchie (Server 2016 e 2019) la causa è quasi sempre TLS. Nella stessa sessione, esegui prima questo:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Per la prima esecuzione conviene tenere il riavvio sotto il proprio controllo:
Install-WindowsUpdate -AcceptAll -IgnoreReboot
Get-WURebootStatus -Silent
Il primo giro di patch su un'immagine appena installata dura, a seconda dell'età dell'immagine, dai 30 ai 60 minuti e richiede due o tre riavvii. È normale. Non è normale il messaggio Errore durante la configurazione degli aggiornamenti di Windows. Ripristino delle modifiche in corso all'avvio. Le due cause più frequenti su un VPS: troppo poco spazio libero su C: (sotto i 10 GB circa la situazione si fa stretta) oppure un riavvio forzato nel bel mezzo della fase di configurazione. Controlla lo spazio con Get-Volume e azzera l'archivio degli aggiornamenti: ferma i servizi wuauserv e bits, rinomina C:\Windows\SoftwareDistribution, riavvia i servizi.
Un inciso: per Windows Server 2025 esiste l'hotpatching, cioè aggiornamenti di sicurezza senza riavvio. Da maggio 2026 non costa più nulla, ma presuppone un collegamento ad Azure Arc. Per un singolo VPS di solito è più lavoro che beneficio.
Firewall: il profilo conta più della regola
Il firewall di Windows resta acceso. Sempre. Il consiglio classico "spegnilo un attimo per provare" su un server raggiungibile pubblicamente finisce regolarmente con il firewall che resta spento.
Get-NetFirewallProfile | Select-Object Name, Enabled
Get-NetConnectionProfile
L'equivoco di gran lunga più diffuso sul firewall di Windows: la regola esiste, è attiva, e l'accesso viene bloccato lo stesso. La causa è quasi sempre che la regola vale per il profilo Privato o Dominio, mentre la scheda di rete si trova nel profilo Pubblico. Un VPS con IP pubblico diretto finisce spesso proprio lì dopo l'attivazione. Verifica in modo esplicito a quale profilo è associata una regola:
Get-NetFirewallRule -Name "RemoteDesktop-UserMode-In-TCP" | Select-Object Name, Enabled, Profile, Action
E dai un'occhiata a che cosa è effettivamente permesso in ingresso:
Get-NetFirewallRule -Enabled True -Direction Inbound -Action Allow | Select-Object DisplayName, Profile | Sort-Object DisplayName
Su un VPS esposto a internet la condivisione di file e stampanti su TCP 445 non ha proprio motivo di esistere. Se ti serve SMB, fallo passare in un tunnel, non lasciarlo aperto. Un tunnel WireGuard è la strada più lineare, la configurazione della controparte è descritta in Configurare un server VPN WireGuard.
Un echo ICMP invece conviene permetterlo, altrimenti il tuo monitoraggio segnala il server come morto:
New-NetFirewallRule -DisplayName "ICMPv4 Echo in ingresso" -Protocol ICMPv4 -IcmpType 8 -Direction Inbound -Action Allow
Mettere in sicurezza RDP non significa spostare la porta
Una porta diversa riduce il rumore nei log e nient'altro. Se vuoi comunque cambiarla, si può fare senza riavvio, come descritto in Cambiare la porta RDP senza riavvio. La messa in sicurezza vera è fatta di altre tre cose.
Primo: imponi l'autenticazione a livello di rete. Senza NLA Windows costruisce la sessione prima che qualcuno si sia identificato. È esattamente la superficie di attacco che non si vuole avere.
$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 significa NLA attivo, SecurityLayer = 2 impone il TLS per l'instaurazione della connessione.
Secondo: limita l'IP di origine. È la misura con l'effetto maggiore, ed è una riga sola. Taglia completamente gli attacchi alle password, e con essi anche il problema del blocco account visto sopra.
Set-NetFirewallRule -Name "RemoteDesktop-UserMode-In-TCP" -RemoteAddress "203.0.113.10"
Set-NetFirewallRule -Name "RemoteDesktop-UserMode-In-UDP" -RemoteAddress "203.0.113.10"
Il nome della regola è volutamente il -Name interno e non il gruppo visualizzato, perché quello si chiama "Desktop remoto" o "Remote Desktop" a seconda della lingua. Funzionano anche più indirizzi o un'intera rete, per esempio -RemoteAddress @("203.0.113.10","198.51.100.0/24").
E qui la precauzione importante: esegui il comando da una sessione RDP già aperta e tieni in parallelo una seconda sessione. Se sbagli a digitare il tuo IP, la connessione salta all'istante. La via di ritorno è allora la console nell'area clienti. Chi a casa ha un IP che cambia dovrebbe saltare questo passaggio e rendere invece RDP raggiungibile solo tramite VPN.
Terzo: imposta la soglia di blocco su un valore sensato, dopo che il firewall è chiuso:
net accounts /lockoutthreshold:10 /lockoutduration:15 /lockoutwindow:15
I tre errori RDP che vengono cercati davvero
- Si è verificato un errore di autenticazione. La funzione richiesta non è supportata. È il caso CredSSP di CVE-2018-0886: il client è aggiornato, il server no. La soluzione corretta è il livello di patch sul server. L'aggiramento tramite registro di sistema che circola in rete, con
AllowEncryptionOracle = 2sul client, riapre esattamente quella falla e va impostato, semmai, solo fino al termine del ciclo di patch e poi rimosso. - Il computer remoto richiede l'autenticazione a livello di rete, non supportata dal computer in uso. Capita con client molto vecchi. Qui il server è configurato correttamente: aggiorna il client invece di disattivare NLA.
- Impossibile connettersi al computer remoto tramite Desktop remoto. Le possibili cause sono: ... Questo messaggio è un contenitore buono per tutto. Restringi il campo sul server e controlla se qualcuno è davvero in ascolto:
Get-Service TermService
Get-NetTCPConnection -LocalPort 3389 -State Listen
Se torna una riga con 0.0.0.0:3389, il servizio è a posto e il problema sta nel firewall o sul percorso fino a lì. Se non torna nulla, è il servizio oppure una porta modificata. Se il server sotto carico non risponde più affatto e manca anche l'ICMP, vale la pena guardare in direzione di un attacco: a questo si collega Proteggere il server dagli attacchi DDoS.
Aggiungere dischi supplementari
Un secondo disco, dopo l'assegnazione, non compare da solo in Esplora file. È grezzo e va inizializzato.
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 "Dati" -Confirm:$false
Get-Volume
GPT invece di MBR, sempre. MBR finisce la corsa a 2 TB, e il passaggio successivo non lo fa volentieri nessuno. Quattro punti critici:
- Disco offline o protetto da scrittura.
Initialize-Disksegnala allora Il disco si trova in stato offline oppure Il disco è protetto da scrittura. Soluzione:Set-Disk -Number 1 -IsOffline $falseeSet-Disk -Number 1 -IsReadOnly $false. - La lettera D: è occupata. In molte immagini è lì che si trova l'unità virtuale della fonte di installazione.
New-Partitionsi interrompe con La lettera di unità specificata non è disponibile. Controlla conGet-Volumee ripiega su E:, oppure sposta prima l'unità virtuale. - Numero sbagliato.
-DiskNumber 1non è per forza il disco nuovo. Confronta inGet-Diskla dimensione e ilPartitionStyleprima di formattare. Una formattazione sul numero 0 colpisce il disco di sistema. - Dopo un ampliamento dello storage, C: non cresce insieme. Lo spazio in più resta subito dietro, non partizionato:
Update-HostStorageCache
$max = (Get-PartitionSupportedSize -DriveLetter C).SizeMax
Resize-Partition -DriveLetter C -Size $max
Se qui Resize-Partition segnala La dimensione specificata non è supportata oppure Size Not Supported, tra C: e lo spazio libero c'è una partizione di ripristino. Va prima rimossa o spostata alla fine, cosa che non si risolve con un solo comando e non andrebbe fatta senza un backup.
Installare ruoli e funzionalità
Solo adesso, dopo il livello di patch e il firewall, arrivano i ruoli. Uno sguardo alla situazione attuale:
Get-WindowsFeature | Where-Object Installed | Select-Object Name, DisplayName
Un server web è una riga sola:
Install-WindowsFeature -Name Web-Server -IncludeManagementTools
Get-Service W3SVC
Invoke-WebRequest http://localhost -UseBasicParsing | Select-Object StatusCode
Se torna StatusCode 200, IIS funziona in locale. Questo non dice ancora che sia raggiungibile anche dall'esterno: per quello servono la regola firewall giusta e una verifica fatta da un secondo sistema.
Il classico tra i fallimenti è .NET Framework 3.5. Non si trova nel sistema in esecuzione, va caricato dalla fonte di installazione. Senza immagine montata arriva questo:
Errore: 0x800f081f
Impossibile trovare i file di origine.
Su un VPS senza ISO proprio hai due strade: impostare il criterio in modo che Windows possa scaricare i file direttamente da Windows Update, oppure copiare sul server la cartella sources\sxs presa da un'immagine con lo stesso numero di build e puntarci con -Source. Un numero di build diverso non funziona, nemmeno se appartiene alla stessa versione di Windows.
Altri due punti sui ruoli: Uninstall-WindowsFeature -Name Web-Server -Remove non rimuove soltanto il ruolo, ma anche i suoi file dal disco. Questo fa risparmiare spazio, però rende la reinstallazione successiva dipendente dalla fonte, con lo stesso 0x800f081f. E chi installa Active Directory dovrebbe risalire ancora una volta all'inizio dell'articolo: con una licenza di valutazione è un vicolo cieco.
Come capire che è tutto a posto
Alla fine un giro di comandi di verifica. Ognuno ha una risposta attesa, e se una di queste non torna, il server non è ancora pronto.
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
Ci si aspetta: una data di scadenza oppure "attivato in modo permanente", il fuso orario europeo, una sorgente oraria vera al posto dell'orologio locale, aggiornamenti di oggi o di ieri, tutti e tre i profili firewall su True, una limitazione RemoteAddress al posto di Any, una data password recente per l'amministratore e tutte le unità con la loro lettera.
Dopo di che vale la pena fare un ultimo passaggio, spesso dimenticato: non chiudere semplicemente la finestra per terminare la sessione, ma disconnettiti in modo corretto. Le sessioni interrotte restano aperte con il loro consumo di RAM, e su un VPS piccolo la cosa si somma nell'arco di settimane fino al punto in cui non è più possibile alcun nuovo accesso.
Se in parallelo stai configurando un server Linux, Configurare un nuovo server root: la checklist copre gli stessi temi sull'altro fronte, e Mettere in sicurezza SSH e configurare il login con chiave è lì la controparte del capitolo su RDP.
Domande frequenti
La licenza di Windows Server è compresa nel prezzo del server?
Che cosa succede quando i 180 giorni della versione di valutazione sono scaduti?
Perché vengo continuamente escluso dal mio stesso server?
Come aggiungo un secondo disco su Windows Server?
Che cosa significa il messaggio secondo cui la funzione richiesta non è supportata?
Perché il firewall di Windows blocca anche se la regola esiste?
2026 KernelHost GmbH. Tutti i diritti riservati. Questa guida è protetta dal diritto d'autore. La ripubblicazione su altri siti web, anche parziale o in forma modificata, non è consentita senza il nostro consenso scritto. Le citazioni con indicazione della fonte e un link sono le benvenute.

