Configurar o Windows Server num VPS: os primeiros passos

Publicado a 16 min de leitura

A checklist a seguir ao aprovisionamento, pela ordem certa: verificar a licença, definir a palavra-passe, fuso horário, atualizações, firewall, proteger o RDP, discos e funções. Incluindo os pontos em que a coisa costuma correr mal.

Um Windows Server acabado de aprovisionar parece pronto: o RDP responde, o ambiente de trabalho aparece, o Gestor de Servidor arranca. É exatamente aí que está a armadilha. Entre "o RDP responde" e "pronto para produção" vão cerca de vinte minutos de trabalho, e a ordem desses passos decide se depois ainda consegue entrar.

Aqui ficam os passos pela ordem em que têm de ser feitos, cada um com o comando de verificação e com as mensagens de erro na íntegra.

Esclarecer primeiro a licença, não no fim

O Windows Server não faz parte do preço do servidor. A KernelHost não é parceira Microsoft SPLA e não aluga licenças Windows. Aqui o Windows funciona no modelo Bring Your Own License: a licença é obtida junto de um parceiro Microsoft certificado ou diretamente da Microsoft, e é o cliente que a traz.

Para testar, avaliar e para ensaios de migração existe a versão de avaliação gratuita da Microsoft, com 180 dias de validade. É completa, apenas está limitada no tempo e não se destina a produção.

Antes de tudo o resto, verifique o que está realmente a correr no servidor:

slmgr /dlv
slmgr /xpr

O slmgr /dlv mostra o nome da edição. Se aí estiver ServerStandardEval ou ServerDatacenterEval, está a correr uma avaliação. O slmgr /xpr indica a data de expiração em texto claro. Ambos os comandos abrem uma janela de pop-up, o que incomoda no Server Core. Aí utilize antes cscript C:\Windows\System32\slmgr.vbs /dlv.

O que acontece quando os 180 dias terminam

O servidor continua a funcionar, mas o Windows License Monitoring Service encerra-o ao fim de cerca de uma hora de atividade, e volta a fazê-lo sempre. No canto inferior direito aparece uma marca de água a avisar que a licença do Windows expirou. Quem vê isto pela primeira vez costuma passar horas à procura de uma falha de hardware ou de controladores, porque o padrão parece o de um watchdog.

A saída limpa é passar para uma licença real. Isso faz-se sem reinstalar:

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

Três pontos em que isto falha com regularidade:

  • Só funciona de Eval para a versão completa com o mesmo nome, ou para cima. De Datacenter Evaluation de volta para Standard, o DISM não faz.
  • A chave tem de ser Retail, MAK ou KMS. Se não encaixar, o DISM comunica Error: 1168, ou o serviço de licenciamento devolve 0xC004F050 com a indicação de que a chave de produto é inválida. Isso quase nunca significa "chave falsificada", mas sim "tipo de chave errado para este caminho".
  • Um controlador de domínio não se pode converter de Evaluation para Retail. Quem já executou o Install-ADDSForest sobre a avaliação tem primeiro de voltar a desmontar a função. É o erro mais caro deste artigo, e é por isso que a questão da licença está aqui logo no início e não no fim.

Uma nota sobre a origem de instalação: na KernelHost não é possível carregar imagens ISO próprias, o Windows vem do catálogo de imagens na área de cliente. A licença tem de a trazer consigo, a imagem já lá está.

Alterar a palavra-passe de administrador sem se bloquear a si próprio

A palavra-passe entregue vem no e-mail de aprovisionamento e tem de ser substituída de imediato. O caminho habitual através de net user Administrator * funciona, mas tem a desvantagem de devolver uma mensagem muito magra quando alguma política é violada. Melhor assim:

$pw = Read-Host -AsSecureString -Prompt "Nova palavra-passe"
Set-LocalUser -Name "Administrator" -Password $pw

Se aparecer A palavra-passe não cumpre os requisitos de complexidade de palavras-passe, está a atuar a política local: pelo menos oito carateres e três das quatro classes de carateres. Os valores em vigor pode consultá-los com net accounts.

Mais sensato do que mudar o nome da conta é uma segunda conta de administrador, com nome próprio. Assim tem um caminho de volta caso uma das contas seja bloqueada:

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

Porquê o SID em vez do nome do grupo? Porque o grupo de administradores se chama Administradores num sistema em português e Administrators num sistema em inglês. Os scripts que fixam o nome no código quebram na primeira mudança de idioma com O grupo local especificado não existe. O S-1-5-32-544 é o mesmo em qualquer Windows.

A armadilha do bloqueio que existe mesmo no Windows Server 2025

Até ao Windows Server 2019 inclusive, a conta de administrador integrada não podia ser bloqueada através de inícios de sessão em rede. Desde uma atualização cumulativa para o Server 2022, e por predefinição no Windows Server 2025, isso mudou: o bloqueio de conta atua a partir de cinco tentativas falhadas e apanha também o administrador integrado.

Num VPS com a porta 3389 aberta isso significa algo muito concreto: as tentativas de início de sessão dos scanners automatizados bloqueiam-lhe a conta antes de chegar a sua vez. Escreve uma palavra-passe correta e mesmo assim recebe A conta referenciada está atualmente bloqueada e não pode ser utilizada para iniciar sessão.

A forma de sair, quando já aconteceu:

  1. Iniciar sessão pela consola na área de cliente em vez de usar o RDP.
  2. Levantar o bloqueio, esperando que a duração do bloqueio passe (o net accounts mostra-a, a predefinição são dez minutos) ou diretamente:
$u = [ADSI]"WinNT://$env:COMPUTERNAME/Administrator,user"
$u.IsAccountLocked = $false
$u.SetInfo()

A solução duradoura não é subir o limiar de bloqueio, mas sim limitar de onde o RDP é alcançável. Isso vem mais abaixo. Só depois se pode voltar a relaxar o limiar, porque a partir daí já não chegam tentativas alheias.

Definir o fuso horário e a hora antes de haver registos

As imagens Windows estão quase sempre em UTC ou num fuso americano. Ninguém repara nisso, até o primeiro certificado TLS ser recusado como "ainda não válido" ou até os registos de eventos deixarem de poder ser cruzados com os de outros sistemas.

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

O "W. Europe Standard Time" cobre Viena, Berlim e Zurique, incluindo a mudança para a hora de verão. A hora em si vem do serviço de tempo, e é aí que está a verdadeira diferença entre uma máquina bare metal e um servidor virtual:

w32tm /query /source
w32tm /query /status

Se como origem aparecer Local CMOS Clock, o servidor não vai buscar a hora à rede de todo. Num sistema virtualizado o relógio deriva então de forma visível, por vezes vários segundos por dia. Defina uma origem a sério:

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

A prova de que ficou bem: o w32tm /query /source nomeia agora um dos servidores configurados, e o w32tm /query /status mostra um valor de Stratum inferior a 10, além de uma hora plausível da última sincronização. Se, em vez disso, o w32tm /resync devolver O computador não foi sincronizado porque não estavam disponíveis dados de hora, normalmente é a firewall a bloquear a porta UDP 123 de saída, ou o serviço ainda não estava a correr.

Se o servidor aderir mais tarde a um domínio: nessa altura é o controlador de domínio que assume a distribuição da hora e a lista manual de pares tem de sair, caso contrário fica com duas origens de tempo em concorrência.

Atualizações do Windows, e o que fazer quando ficam presas

Aplique os patches antes de instalar funções, não depois. Caso contrário instala funções a partir de um estado antigo e volta a passá-las uma segunda vez pelo ciclo de atualizações.

No Server Core trata disso o sconfig, opção 6 do menu. Com interface gráfica faz-se pelas definições. E torna-se automatizável com o módulo PSWindowsUpdate:

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

Se a transferência a partir da PowerShell Gallery falhar com Não foi encontrada nenhuma correspondência para os critérios de pesquisa especificados ou com uma quebra de ligação, nas versões mais antigas (Server 2016 e 2019) é quase sempre por causa do TLS. Execute isto antes, na mesma sessão:

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

Para a primeira passagem convém manter o reinício nas suas mãos:

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

A primeira ronda de patches numa imagem nova demora entre 30 e 60 minutos, consoante a idade da imagem, e precisa de dois a três reinícios. Isso é normal. O que não é normal é a mensagem Falha ao configurar as atualizações do Windows. A reverter as alterações durante o arranque. As duas causas mais frequentes num VPS: pouco espaço livre em C: (abaixo de cerca de 10 GB a coisa aperta) ou um reinício brusco a meio da fase de configuração. Verifique o espaço com Get-Volume e reponha o repositório de atualizações: pare os serviços wuauserv e bits, mude o nome de C:\Windows\SoftwareDistribution e volte a iniciar os serviços.

À margem: para o Windows Server 2025 existe o hotpatching, ou seja, atualizações de segurança sem reinício. Desde maio de 2026 deixou de ter custo, mas pressupõe uma ligação ao Azure Arc. Para um VPS isolado costuma dar mais trabalho do que benefício.

Firewall: o perfil é mais importante do que a regra

A firewall do Windows fica ligada. Sempre. O conselho habitual de "desligar um bocado para testar" acaba com regularidade, num servidor acessível publicamente, com ela desligada para sempre.

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

O equívoco de firewall mais frequente no Windows, de longe: a regra existe, está ativada, e mesmo assim o acesso é bloqueado. A causa é quase sempre que a regra vale para o perfil Privado ou Domínio, ao passo que a placa de rede está no perfil Público. Um VPS com endereço IP público direto vai muitas vezes parar exatamente aí depois do aprovisionamento. Verifique de forma explícita a que perfil pertence uma regra:

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

E veja uma vez o que está sequer permitido à entrada:

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

O que não tem nada que fazer num VPS ligado à Internet é a partilha de ficheiros e impressoras no TCP 445. Se precisar de SMB, faça-o passar por um túnel em vez de o deixar aberto. Um túnel WireGuard é o caminho mais direto para isso, e a configuração do outro extremo está descrita em configurar um servidor VPN WireGuard.

Um eco ICMP, esse, deve permitir, caso contrário a sua monitorização dá o servidor por morto:

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

Proteger o RDP não significa mudar a porta

Outra porta reduz o ruído nos registos e mais nada. Se ainda assim a quiser mudar, isso faz-se sem reiniciar, e está descrito em mudar a porta RDP sem reiniciar. A proteção a sério consiste noutras três coisas.

Primeiro: impor a autenticação ao nível da rede. Sem NLA, o Windows monta a sessão antes de alguém se ter identificado. É exatamente essa a superfície de ataque que não se quer.

$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 ativo, SecurityLayer = 2 impõe TLS para o estabelecimento da ligação.

Segundo: restringir o IP de origem. É a medida com maior efeito e cabe numa linha. Corta por completo os ataques a palavras-passe e, com eles, o problema do bloqueio de conta descrito acima.

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

O nome da regra é de propósito o -Name interno e não o grupo de apresentação, porque esse chama-se "Ambiente de Trabalho Remoto" ou "Remote Desktop" conforme o idioma. Vários endereços ou uma rede inteira também funcionam, por exemplo -RemoteAddress @("203.0.113.10","198.51.100.0/24").

E aqui fica a precaução importante: execute isto a partir de uma sessão RDP existente e deixe em paralelo uma segunda sessão aberta. Se se enganar a escrever o seu próprio endereço IP, a ligação desaparece de imediato. O caminho de volta é então a consola na área de cliente. Quem tem em casa um IP que muda deve saltar este passo e, em vez disso, tornar o RDP acessível apenas por VPN.

Terceiro: definir o limiar de bloqueio num valor adequado, depois de a firewall estar fechada:

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

Os três erros de RDP que as pessoas procuram mesmo

  • Ocorreu um erro de autenticação. A função pedida não é suportada. É o caso CredSSP da CVE-2018-0886: o cliente está corrigido, o servidor não. A solução correta é o nível de patches no servidor. O contorno de registo que circula por aí, com AllowEncryptionOracle = 2 no cliente, volta a abrir precisamente essa falha e, quando muito, só deve ficar definido até a ronda de patches estar concluída e ser removido a seguir.
  • O computador remoto requer autenticação ao nível da rede, que o seu computador não suporta. Aparece em clientes muito antigos. Aqui o servidor está bem configurado: atualize o cliente em vez de desligar o NLA.
  • O Ambiente de Trabalho Remoto não consegue estabelecer ligação ao computador remoto por um dos seguintes motivos: ... Esta mensagem é um caixote onde cabe tudo. Delimite no servidor se sequer alguém está à escuta:
Get-Service TermService
Get-NetTCPConnection -LocalPort 3389 -State Listen

Se voltar uma linha com 0.0.0.0:3389, o serviço está em ordem e o erro está na firewall ou no caminho até lá. Se não voltar nada, é o serviço ou uma porta alterada. Se o servidor deixar de responder por completo sob carga e o ICMP também ficar mudo, vale a pena olhar na direção de um ataque, e para isso encaixa proteger servidores contra ataques DDoS.

Integrar discos adicionais

Um segundo disco não aparece sozinho no Explorador depois de ser atribuído. Está em bruto e tem de ser inicializado.

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 "Dados" -Confirm:$false
Get-Volume

GPT em vez de MBR, sempre. O MBR fica pelo caminho aos 2 TB, e a mudança posterior não apetece a ninguém. Quatro pontos onde se tropeça:

  • Disco offline ou protegido contra escrita. O Initialize-Disk comunica então O disco está offline ou O disco está protegido contra escrita. Solução: Set-Disk -Number 1 -IsOffline $false e Set-Disk -Number 1 -IsReadOnly $false.
  • A letra D: está ocupada. Em muitas imagens está aí montada a unidade virtual com a origem de instalação. O New-Partition interrompe com A letra de unidade especificada não está disponível. Verifique com Get-Volume e passe para E:, ou mova antes a unidade virtual.
  • Número trocado. O -DiskNumber 1 não é garantidamente o disco novo. Compare o tamanho e o PartitionStyle no Get-Disk antes de formatar. Uma formatação no número 0 vai contra o disco do sistema.
  • Depois de uma ampliação de armazenamento, o C: não cresce sozinho. O espaço adicional fica sem partição, atrás:
Update-HostStorageCache
$max = (Get-PartitionSupportedSize -DriveLetter C).SizeMax
Resize-Partition -DriveLetter C -Size $max

Se o Resize-Partition devolver aqui O tamanho especificado não é suportado ou Size Not Supported, é porque entre o C: e o espaço livre existe uma partição de recuperação. Essa tem primeiro de ser removida ou movida para o fim, o que não se faz num único comando e não deve acontecer sem um backup.

Instalar funções e funcionalidades

Só agora, com o nível de patches e a firewall no sítio, chegam as funções. Um olhar ao estado atual:

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

Um servidor web cabe numa linha:

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

Se voltar StatusCode 200, o IIS está a correr localmente. Isso ainda não diz que também esteja acessível a partir do exterior, para isso é precisa a regra de firewall adequada e um olhar a partir de um segundo sistema.

O clássico entre os falhanços é o .NET Framework 3.5. Não está no sistema em execução, tem de ser carregado a partir da origem de instalação. Sem uma imagem montada aparece:

Erro: 0x800f081f
Não foi possível localizar os ficheiros de origem.

Num VPS sem ISO próprio tem dois caminhos: definir a política de modo que o Windows possa ir buscar os ficheiros diretamente ao Windows Update, ou copiar para o servidor a pasta sources\sxs de uma imagem com o mesmo número de compilação e apontar para ela com -Source. Outro número de compilação não funciona, mesmo que pertença à mesma versão do Windows.

Mais dois pontos sobre funções: o Uninstall-WindowsFeature -Name Web-Server -Remove não remove apenas a função, remove também os respetivos ficheiros do disco. Isso poupa espaço, mas torna a reinstalação posterior dependente de uma origem, com o mesmo 0x800f081f. E quem instala o Active Directory deve voltar a subir até ao início: numa licença de avaliação isso é um beco sem saída.

Como reconhece que está tudo no sítio

No fim, uma ronda de comandos de verificação. Cada um tem uma resposta esperada e, se alguma não bater certo, o servidor ainda não está 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

O que se espera: uma data de expiração ou "ativado permanentemente", o fuso horário europeu, uma origem de tempo a sério em vez do relógio local, atualizações de hoje ou de ontem, os três perfis de firewall em True, uma restrição de RemoteAddress em vez de Any, uma data de palavra-passe recente no administrador e todas as unidades com letra.

Depois disso vale a pena um último passo, muitas vezes esquecido: não corte a sessão fechando simplesmente a janela, termine sessão como deve ser. As sessões desligadas ficam de pé com o seu consumo de memória e, num VPS pequeno, isso vai somando ao longo de semanas até ao ponto em que já não é possível nenhum início de sessão novo.

Se estiver a montar em paralelo um servidor Linux, configurar um servidor root novo: a checklist cobre os mesmos temas do outro lado, e proteger o SSH e configurar o início de sessão por chave é aí o equivalente à secção sobre o RDP.

Perguntas frequentes

A licença do Windows Server está incluída no preço do servidor?
Não. A KernelHost não é parceira Microsoft SPLA e não aluga licenças Windows. O Windows é operado no modelo Bring Your Own License: a licença é obtida junto de um parceiro Microsoft certificado ou diretamente da Microsoft e é o cliente que a traz. Para testar existe a versão de avaliação gratuita da Microsoft, com 180 dias de validade.
O que acontece quando os 180 dias da versão de avaliação terminam?
O servidor continua a arrancar, mas o Windows License Monitoring Service encerra-o ao fim de cerca de uma hora de atividade, e volta a fazê-lo sempre. No ambiente de trabalho aparece uma marca de água a assinalar a licença expirada. Com uma licença regular, a instalação pode ser convertida sem reinstalar: DISM /Online /Set-Edition:ServerStandard /ProductKey:... /AcceptEula.
Porque é que fico constantemente bloqueado fora do meu próprio servidor?
No Windows Server 2025, o bloqueio de conta está ativo por predefinição a partir de cinco inícios de sessão falhados e abrange também a conta de administrador integrada. Com a porta 3389 aberta, as tentativas de início de sessão automatizadas bloqueiam a conta em permanência. A solução não é um limiar de bloqueio mais alto, mas sim a restrição da regra de RDP ao seu próprio IP de origem com Set-NetFirewallRule -Name RemoteDesktop-UserMode-In-TCP -RemoteAddress.
Como integro um segundo disco no Windows Server?
O Get-Disk mostra-o com PartitionStyle RAW. Depois Initialize-Disk -PartitionStyle GPT, a seguir New-Partition -DiskNumber 1 -UseMaximumSize -DriveLetter D e Format-Volume -FileSystem NTFS. Se o Windows comunicar estado offline ou proteção contra escrita, ajudam o Set-Disk -IsOffline $false e o Set-Disk -IsReadOnly $false. Se o D: já estiver ocupado, passe para outra letra.
O que significa a mensagem de que a função pedida não é suportada?
É o erro CredSSP da CVE-2018-0886. O cliente tem a atualização de segurança, o servidor ainda não. A solução correta é o nível de patches no servidor, não o contorno de registo muito divulgado com AllowEncryptionOracle = 2 no cliente, porque esse volta a abrir a falha.
Porque é que a firewall do Windows bloqueia, apesar de a regra existir?
Porque as regras de firewall valem por perfil de rede. Se a regra estiver em Privado ou Domínio e a placa de rede em Público, a regra não pega. Um VPS com endereço IP público vai muitas vezes parar ao perfil Público depois do aprovisionamento. O Get-NetConnectionProfile mostra a atribuição e o Get-NetFirewallRule, com a coluna Profile na saída, mostra o alcance da regra.

Windows Server VPS RDP PowerShell Administração de servidores Segurança