Настройка Windows Server на VPS: первые шаги
Чек-лист после развёртывания в правильном порядке: проверить лицензию, задать пароль, часовой пояс, обновления, файрвол, защита RDP, диски и роли. Включая места, где всё идёт не так.
Только что развёрнутый Windows Server выглядит готовым: RDP отвечает, появляется рабочий стол, запускается диспетчер серверов. Именно в этом и состоит ловушка. Между «RDP отвечает» и «сервер пригоден для продуктивной работы» лежит примерно двадцать минут работы, и порядок этих шагов решает, сможете ли вы после них ещё войти на сервер.
Ниже собраны шаги в том порядке, в котором их нужно выполнять, к каждому есть команда для проверки и дословный текст сообщений об ошибках.
Лицензию выясняем первым делом, а не последним
Windows Server не входит в стоимость сервера. KernelHost не является партнёром Microsoft SPLA и не сдаёт лицензии Windows в аренду. Windows работает здесь по модели Bring Your Own License: лицензия приобретается у сертифицированного партнёра Microsoft или напрямую у Microsoft, а клиент приносит её с собой.
Для тестов, оценки и репетиций миграции у Microsoft есть бесплатная ознакомительная версия со сроком действия 180 дней. Она полнофункциональна, ограничена только по времени и для продуктивной эксплуатации не предназначена.
Самое первое, что стоит проверить: что на сервере работает на самом деле.
slmgr /dlv
slmgr /xpr
slmgr /dlv показывает название редакции. Если там стоит ServerStandardEval или ServerDatacenterEval, запущена ознакомительная версия. slmgr /xpr называет дату окончания срока в явном виде. Обе команды открывают всплывающее окно, что мешает на Server Core. Там вместо них используйте cscript C:\Windows\System32\slmgr.vbs /dlv.
Что произойдёт, когда 180 дней закончатся
Сервер продолжает работать, но служба Windows License Monitoring Service выключает его примерно через час после старта, и так раз за разом. В правом нижнем углу появляется водяной знак с сообщением о том, что срок действия лицензии Windows истёк. Тот, кто видит это впервые, обычно часами ищет неисправность железа или драйвера, потому что картина выглядит как срабатывание watchdog.
Чистый выход из положения: переход на настоящую лицензию. Переустановка для этого не нужна:
DISM /Online /Set-Edition:ServerStandard /ProductKey:XXXXX-XXXXX-XXXXX-XXXXX-XXXXX /AcceptEula
Три момента, на которых это регулярно срывается:
- Переход возможен только с Eval на одноимённую полную редакцию или на более старшую. Обратный путь с Datacenter Evaluation на Standard DISM не выполнит.
- Ключ должен быть Retail, MAK или KMS. Если он не подходит, DISM сообщает Error: 1168, а служба лицензирования выдаёт 0xC004F050 с указанием на недействительный ключ продукта. Почти никогда это не означает «поддельный ключ», а означает «неподходящий тип ключа для этого способа».
- Контроллер домена перевести с Evaluation на Retail нельзя. Тот, кто уже выполнил
Install-ADDSForestна ознакомительной версии, должен сначала снять эту роль. Это самая дорогая ошибка во всей статье, поэтому вопрос лицензии стоит здесь в самом начале, а не в конце.
Замечание об источнике установки: собственные образы ISO загрузить в KernelHost нельзя, Windows берётся из каталога образов в личном кабинете. Лицензию вы приносите свою, образ уже на месте.
Меняем пароль администратора, не заперев себя снаружи
Выданный пароль указан в письме о развёртывании и подлежит немедленной замене. Привычный путь через net user Administrator * работает, но у него есть недостаток: при нарушении политики он выдаёт лишь скупое сообщение. Лучше так:
$pw = Read-Host -AsSecureString -Prompt "Новый пароль"
Set-LocalUser -Name "Administrator" -Password $pw
Если появляется Пароль не удовлетворяет требованиям сложности пароля, значит сработала локальная политика: минимум восемь символов и три класса символов из четырёх. Действующие значения можно посмотреть командой net accounts.
Разумнее, чем переименовывать учётную запись, завести вторую именованную учётную запись администратора. Тогда у вас останется обходной путь, если первую заблокируют:
$pw = Read-Host -AsSecureString -Prompt "Пароль для svcadmin"
New-LocalUser -Name "svcadmin" -Password $pw -PasswordNeverExpires
Add-LocalGroupMember -SID "S-1-5-32-544" -Member "svcadmin"
Почему SID, а не имя группы? Потому что на русской системе группа администраторов называется Администраторы, а на английской Administrators. Скрипты с жёстко прописанным именем ломаются при первой же смене языка с ошибкой Указанная локальная группа не существует. S-1-5-32-544 одинаков на любой Windows.
Ловушка блокировки, которая в Windows Server 2025 действительно есть
Вплоть до Windows Server 2019 включительно встроенную учётную запись администратора нельзя было заблокировать через сетевые входы. После одного из накопительных обновлений для Server 2022, а в Windows Server 2025 уже по умолчанию, всё иначе: блокировка учётной записи срабатывает после пяти неудачных попыток и затрагивает в том числе встроенного администратора.
На VPS с открытым портом 3389 это означает буквально следующее: попытки входа автоматических сканеров блокируют вашу учётную запись раньше, чем вы сами успеваете войти. Вы вводите правильный пароль и всё равно получаете Учётная запись пользователя заблокирована и не может быть использована для входа в систему.
Как выбраться, если это уже случилось:
- Войдите через консоль в личном кабинете, а не по RDP.
- Снимите блокировку: либо дождитесь окончания её срока (
net accountsпоказывает его, по умолчанию десять минут), либо напрямую:
$u = [ADSI]"WinNT://$env:COMPUTERNAME/Administrator,user"
$u.IsAccountLocked = $false
$u.SetInfo()
Постоянное решение состоит не в том, чтобы поднять порог блокировки, а в том, чтобы ограничить доступность RDP. Об этом ниже. Только после этого порог можно снова ослабить, потому что чужие попытки до сервера уже не доходят.
Часовой пояс и время задаём до того, как что-то попадёт в журналы
Образы Windows почти всегда стоят на UTC или на американском часовом поясе. Этого никто не замечает, пока первый сертификат TLS не будет отклонён как «ещё не действительный» или пока журналы событий не перестанут сопоставляться с журналами других систем.
Get-TimeZone
Get-TimeZone -ListAvailable | Where-Object { $_.Id -like "*Europe*" }
Set-TimeZone -Id "W. Europe Standard Time"
«W. Europe Standard Time» покрывает Вену, Берлин и Цюрих вместе с переходом на летнее время. Само время приходит от службы времени, и здесь проходит настоящая граница между железным сервером и виртуальным:
w32tm /query /source
w32tm /query /status
Если в качестве источника указан Local CMOS Clock, сервер вообще не берёт время из сети. На виртуализированной системе часы после этого заметно уходят, иногда на несколько секунд в сутки. Задайте настоящий источник:
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
Доказательство того, что настройка села: w32tm /query /source теперь называет один из внесённых серверов, а w32tm /query /status показывает значение Stratum меньше 10 и правдоподобное время последней синхронизации. Если w32tm /resync вместо этого сообщает Компьютер не выполнил синхронизацию, поскольку отсутствовали доступные данные о времени, то чаще всего файрвол блокирует исходящий UDP-порт 123 или служба ещё не была запущена.
Если сервер позже войдёт в домен: тогда раздачу времени берёт на себя контроллер домена, а ручной список пиров нужно снова убрать, иначе получатся два конкурирующих источника времени.
Обновления Windows и что делать, если они зависли
Ставьте обновления до установки ролей, а не после. Иначе вы установите роли из старого состояния и прогоните их потом через цикл обновлений второй раз.
На Server Core этим занимается sconfig, пункт меню 6. С графической оболочкой это делается через параметры. Скриптуемым процесс становится с модулем PSWindowsUpdate:
Install-PackageProvider -Name NuGet -Force
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
Install-Module PSWindowsUpdate -Force
Import-Module PSWindowsUpdate
Get-WindowsUpdate
Если загрузка из PowerShell Gallery срывается с сообщением Не найдено совпадений для указанных условий поиска или обрывом соединения, то на более старых версиях (Server 2016 и 2019) виновником почти всегда оказывается TLS. Выполните заранее, в той же сессии:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Для первого прогона имеет смысл оставить перезагрузку под собственным контролем:
Install-WindowsUpdate -AcceptAll -IgnoreReboot
Get-WURebootStatus -Silent
Первый цикл обновлений на свежем образе занимает от 30 до 60 минут, в зависимости от возраста образа, и требует двух-трёх перезагрузок. Это нормально. Ненормально сообщение Не удалось настроить обновления Windows. Отмена изменений при загрузке. Две самые частые причины на VPS: слишком мало свободного места на C: (ниже примерно 10 ГБ становится тесно) или жёсткая перезагрузка посреди фазы настройки. Проверьте место командой Get-Volume и сбросьте хранилище обновлений: остановить службы wuauserv и bits, переименовать C:\Windows\SoftwareDistribution, запустить службы обратно.
Мимоходом: для Windows Server 2025 есть hotpatching, то есть обновления безопасности без перезагрузки. С мая 2026 года они бесплатны, но требуют подключения к Azure Arc. Для одного отдельного VPS это чаще всего больше хлопот, чем пользы.
Файрвол: профиль важнее правила
Файрвол Windows остаётся включённым. Всегда. Привычный совет «выключи на минутку для теста» на публично доступном сервере регулярно заканчивается тем, что он так и остаётся выключенным.
Get-NetFirewallProfile | Select-Object Name, Enabled
Get-NetConnectionProfile
Самое частое заблуждение о файрволе Windows: правило существует, оно включено, а доступ всё равно блокируется. Причина почти всегда в том, что правило действует для профиля Частный или Доменный, а сетевая карта стоит в профиле Общедоступный. VPS с прямым публичным IP после развёртывания часто попадает именно туда. Проверьте привязку правила явно:
Get-NetFirewallRule -Name "RemoteDesktop-UserMode-In-TCP" | Select-Object Name, Enabled, Profile, Action
И посмотрите один раз, что вообще разрешено на входящих:
Get-NetFirewallRule -Enabled True -Direction Inbound -Action Allow | Select-Object DisplayName, Profile | Sort-Object DisplayName
Чему на VPS в интернете точно не место, так это общему доступу к файлам и принтерам на TCP 445. Если SMB нужен, то через туннель, а не в открытую. Туннель WireGuard для этого самый прямой путь, настройка удалённой стороны описана в статье Настройка VPN-сервера WireGuard.
А вот эхо-запрос ICMP разрешить стоит, иначе мониторинг сочтёт сервер мёртвым:
New-NetFirewallRule -DisplayName "ICMPv4 Echo входящий" -Protocol ICMPv4 -IcmpType 8 -Direction Inbound -Action Allow
Защитить RDP не значит перенести порт
Другой порт снижает шум в журналах, и только. Если вы всё же хотите его сменить, это делается без перезагрузки, как описано в статье Смена порта RDP без перезагрузки. Настоящая защита состоит из трёх других вещей.
Первое: принудительно включить проверку подлинности на уровне сети. Без NLA Windows поднимает сеанс ещё до того, как кто-либо предъявил учётные данные. Это ровно та поверхность атаки, которая никому не нужна.
$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 означает, что NLA включена, SecurityLayer = 2 требует TLS при установлении соединения.
Второе: ограничить IP-адрес источника. Это мера с самым большим эффектом, и она умещается в одну строку. Она полностью обрубает подбор паролей, а вместе с ним и описанную выше проблему с блокировкой учётной записи.
Set-NetFirewallRule -Name "RemoteDesktop-UserMode-In-TCP" -RemoteAddress "203.0.113.10"
Set-NetFirewallRule -Name "RemoteDesktop-UserMode-In-UDP" -RemoteAddress "203.0.113.10"
Имя правила намеренно взято внутреннее, через -Name, а не отображаемая группа, потому что она в зависимости от языка называется «Удалённый рабочий стол» или «Remote Desktop». Несколько адресов или целая сеть тоже работают, например -RemoteAddress @("203.0.113.10","198.51.100.0/24").
И важная мера предосторожности: выполняйте это из уже открытого сеанса RDP и держите параллельно второй сеанс. Если вы ошибётесь в собственном IP, соединение пропадёт мгновенно. Обратный путь тогда только через консоль в личном кабинете. Тем, у кого дома меняющийся IP, этот шаг лучше пропустить и вместо него сделать RDP доступным только через VPN.
Третье: выставить подходящий порог блокировки, уже после того как файрвол закрыт:
net accounts /lockoutthreshold:10 /lockoutduration:15 /lockoutwindow:15
Три ошибки RDP, которые ищут чаще всего
- Произошла ошибка при проверке подлинности. Указанная функция не поддерживается. Это случай CredSSP из CVE-2018-0886: клиент пропатчен, сервер нет. Правильное решение состоит в уровне обновлений на сервере. Гуляющий по форумам обход через реестр с
AllowEncryptionOracle = 2на клиенте снова открывает ровно эту брешь, и применять его допустимо разве что до завершения установки обновлений, а потом удалять. - Удалённый компьютер требует проверки подлинности на уровне сети, которая не поддерживается данным компьютером. Встречается у очень старых клиентов. Сервер здесь настроен правильно, обновите клиент вместо того, чтобы отключать NLA.
- Не удаётся подключиться к удалённому компьютеру. Возможные причины: ... Это сообщение сборное. Сузьте область поиска на сервере: слушает ли вообще кто-нибудь.
Get-Service TermService
Get-NetTCPConnection -LocalPort 3389 -State Listen
Если возвращается строка с 0.0.0.0:3389, служба в порядке и ошибка кроется в файрволе или на пути к нему. Если не возвращается ничего, дело в службе или в изменённом порте. Если сервер под нагрузкой вообще перестаёт отвечать и ICMP тоже молчит, стоит посмотреть в сторону атаки, к этому подходит статья Защита сервера от DDoS-атак.
Подключение дополнительных накопителей
Второй накопитель после назначения не появляется в проводнике сам собой. Он сырой, и его нужно инициализировать.
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 "Данные" -Confirm:$false
Get-Volume
GPT вместо MBR, всегда. У MBR предел на 2 ТБ, а переход задним числом никому не в радость. Четыре подводных камня:
- Накопитель отключён или защищён от записи.
Initialize-Diskсообщает тогда Диск находится в автономном состоянии или Диск защищён от записи. Решение:Set-Disk -Number 1 -IsOffline $falseиSet-Disk -Number 1 -IsReadOnly $false. - Буква D: занята. Во многих образах на ней висит виртуальный дисковод с источником установки.
New-Partitionпрерывается с сообщением Указанная буква диска недоступна. Проверьте черезGet-Volumeи уйдите на E: или заранее переставьте виртуальный дисковод. - Перепутан номер.
-DiskNumber 1не гарантированно указывает на новый накопитель. Сравните вGet-Diskразмер иPartitionStyle, прежде чем форматировать. Форматирование номера 0 означает системный накопитель. - После расширения дискового пространства C: не растёт вместе с ним. Дополнительное место лежит позади него нераспределённым:
Update-HostStorageCache
$max = (Get-PartitionSupportedSize -DriveLetter C).SizeMax
Resize-Partition -DriveLetter C -Size $max
Если Resize-Partition сообщает здесь Указанный размер не поддерживается или Size Not Supported, значит между C: и свободным местом находится раздел восстановления. Его сначала нужно удалить или сдвинуть в конец, одной командой это не делается и без резервной копии затевать не стоит.
Установка ролей и компонентов
Только теперь, после уровня обновлений и файрвола, добавляются роли. Взгляд на текущее состояние:
Get-WindowsFeature | Where-Object Installed | Select-Object Name, DisplayName
Веб-сервер укладывается в одну строку:
Install-WindowsFeature -Name Web-Server -IncludeManagementTools
Get-Service W3SVC
Invoke-WebRequest http://localhost -UseBasicParsing | Select-Object StatusCode
Если возвращается StatusCode 200, IIS работает локально. Что он доступен и снаружи, отсюда ещё не следует, для этого нужны подходящее правило файрвола и проверка со второй системы.
Классика среди неудач: .NET Framework 3.5. Его нет в работающей системе, он подгружается из источника установки. Без подключённого образа приходит:
Ошибка: 0x800f081f
Не удалось найти исходные файлы.
На VPS без собственного ISO у вас два пути: задать политику так, чтобы Windows разрешалось брать файлы прямо из Windows Update, или скопировать на сервер папку sources\sxs из образа с тем же номером сборки и указать на неё через -Source. Другой номер сборки не подойдёт, даже если он относится к той же версии Windows.
Ещё два момента про роли: Uninstall-WindowsFeature -Name Web-Server -Remove удаляет не только роль, но и её файлы с накопителя. Это экономит место, но делает последующую переустановку зависимой от источника, с тем же самым 0x800f081f. А тем, кто ставит Active Directory, стоит ещё раз пролистать наверх: на ознакомительной лицензии это тупик.
По каким признакам видно, что всё село
Напоследок серия проверочных команд. У каждой есть ожидаемый ответ, и если хотя бы один не совпадает, сервер ещё не готов.
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
Ожидается следующее: дата окончания срока или «активация выполнена бессрочно», европейский часовой пояс, настоящий источник времени вместо локальных часов, обновления от сегодня или вчера, все три профиля файрвола в состоянии True, ограничение RemoteAddress вместо Any, свежая дата пароля у администратора и все тома с буквами.
После этого стоит сделать последний, часто забываемый шаг: не разрывайте сеанс простым закрытием окна, а выходите из системы по-настоящему. Отключённые сеансы остаются висеть вместе со своим потреблением памяти, и на небольшом VPS это за недели накапливается до точки, когда новый вход становится невозможен.
Если параллельно поднимается сервер на Linux, то статья Настройка нового root-сервера: чек-лист закрывает те же темы для другой стороны, а Защита SSH и вход по ключу соответствует там разделу про RDP.
Частые вопросы
Входит ли лицензия Windows Server в стоимость сервера?
Что произойдёт, когда закончатся 180 дней ознакомительной версии?
Почему я постоянно оказываюсь заблокирован на собственном сервере?
Как подключить второй накопитель в Windows Server?
Что означает сообщение о том, что указанная функция не поддерживается?
Почему файрвол Windows блокирует доступ, хотя правило существует?
2026 KernelHost GmbH. Все права защищены. Эта инструкция охраняется авторским правом. Публикация на других сайтах, в том числе частично или в изменённом виде, без нашего письменного согласия не разрешается. Цитирование с указанием источника и активной ссылкой мы приветствуем.

