servers.txt со списком серверов, доступ по WinRM (порт 5985/5986), редактор CSV, тестовая виртуальная машина с целевой ОС
powershell.exe (Windows PowerShell 5.1). В PowerShell 7 (pwsh.exe) модуль ServerManager не загружается — команды вида Get-WindowsFeature там не работают.inventory.csv — файл с одной строкой на сервер.Пример: файл C:\migration\servers.txt, по одному имени на строку:
SRV-FILE01
SRV-SQL01
SRV-APP01

Что сделать: собрать по каждому серверу название продукта, версию, номер сборки, редакцию и дату установки. Затем выгрузить всё в один CSV.
Зачем: план миграции строится не по «парку серверов вообще», а по конкретным машинам с конкретными сборками. Без этого невозможно понять, сколько серверов в зоне риска.
Как проверить: на одном сервере выполните:
Get-ComputerInfo -Property WindowsProductName, WindowsVersion, OsBuildNumber, WindowsEditionId, CsName | Format-List
Ожидаемый вывод (пример; у вас будут свои значения):
WindowsProductName : Windows Server 2016 Standard
WindowsVersion : 1607
OsBuildNumber : 14393
WindowsEditionId : ServerStandard
CsName : SRV-FILE01
Дата установки берётся отдельно:
(Get-CimInstance Win32_OperatingSystem).InstallDate
Теперь массовый сбор по списку:
$servers = Get-Content C:\migration\servers.txt
Invoke-Command -ComputerName $servers -ScriptBlock {
$os = Get-CimInstance Win32_OperatingSystem
[pscustomobject]@{
Server = $env:COMPUTERNAME
OS = $os.Caption
Version = $os.Version
Build = $os.BuildNumber
Installed = $os.InstallDate
}
} | Select-Object Server, OS, Version, Build, Installed |
Export-Csv C:\migration\inventory.csv -NoTypeInformation -Encoding UTF8
Почему это работает: Invoke-Command выполняет блок кода на каждом сервере через WinRM, а Export-Csv складывает результат в таблицу, которую можно открыть в Excel.
Пример: в inventory.csv появится строка вида SRV-SQL01,Microsoft Windows Server 2016 Standard,10.0.14393,14393,12.03.2018 9:14:02.
Сводная таблица полей для проверки:
| Что проверяем | Команда | Ожидаемый результат |
|---|---|---|
| Версия и сборка | `Get-ComputerInfo` | `WindowsVersion 1607`, `OsBuildNumber 14393` |
| Дата установки | `(Get-CimInstance Win32_OperatingSystem).InstallDate` | дата вида `12.03.2018` |
| Редакция | `(Get-ComputerInfo).WindowsEditionId` | `ServerStandard` / `ServerDatacenter` |
| Количество серверов | `(Import-Csv C:\migration\inventory.csv).Count` | число, совпадающее со строками `servers.txt` |
Что сделать: на каждом сервере выгрузить установленные роли, программы, общие папки и нештатные задачи планировщика. Свести в таблицу «что переносим и куда».
Зачем: сервер — это не только ОС. Основная причина, по которой миграция затягивается, — забытая роль или служба, работающая под локальной учётной записью, которая на новой машине не существует.
Как проверить: роли (в Windows PowerShell 5.1):
Get-WindowsFeature | Where-Object { $_.Installed } | Select-Object Name, DisplayName | Sort-Object Name
Пример вывода:
Name DisplayName
---- -----------
File-Services File and iSCSI Services
Web-Server IIS
Установленные программы — из двух веток реестра, 64- и 32-битной:
Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*',
'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*' |
Where-Object DisplayName |
Select-Object DisplayName, DisplayVersion |
Sort-Object DisplayName
Общие папки и задачи:
Get-SmbShare | Select-Object Name, Path, Description
Get-ScheduledTask | Where-Object { $_.TaskPath -notlike '\Microsoft\*' } |
Select-Object TaskPath, TaskName, State
Результат сводите в такую таблицу (заполняйте руками — это и есть план):
| Роль / приложение | Что проверить | Куда переносим |
|---|---|---|
| File-Services | имена шар, права NTFS, размер | SRV-FILE02 (новая ОС) |
| IIS | сайты, привязки, сертификаты | SRV-WEB02 |
| Стороннее ПО | версия, лицензия, совместимость | **сверьтесь с документацией** вендора |
Если к серверу обращаются клиенты с Windows, миграцию клиентской части планируйте отдельно — пошаговый сценарий установки есть в гайде Как установить Windows 11 26H2: пошаговая инструкция с официального ISO.

Что сделать: перенести одну некритичную роль на тестовую ВМ с целевой ОС, прогнать проверки и только потом тиражировать сценарий на остальные серверы.
Зачем: пилот вскрывает несовместимости, пока они не задели продуктив. Одна ошибка на тестовой ВМ дешевле простоя файлового сервера.
Как проверить: сначала убедитесь, что резервная копия существует:
wbadmin get versions
Если список версий пуст — бэкапа нет, перенос начинать нельзя.
Проверка доступности новой машины и её версии:
Test-NetConnection -ComputerName SRV-NEW01 -Port 5985
Invoke-Command -ComputerName SRV-NEW01 -ScriptBlock {
Get-CimInstance Win32_OperatingSystem | Select-Object Caption, Version, BuildNumber
}
Ожидаемый результат: TcpTestSucceeded : True и строка с Caption, Version, BuildNumber целевой ОС (значения зависят от выбранной вами версии — сверьтесь с документацией).
Чек-лист приёмки пилота:
inventory.csv заполнен, в нём нет серверов без версии и сборкиwbadmin get versions показывает копию не старше сутокGet-WindowsFeature показывает её как InstalledПроблема. Команда ролей не находится.
Get-WindowsFeature : The term 'Get-WindowsFeature' is not recognized as the name of a cmdlet, function, script file, or operable program.pwsh.exe), где модуль ServerManager не поддерживается, либо открыта клиентская ОС без роли.powershell.exe -NoExit -Command "Import-Module ServerManager; Get-WindowsFeature | Where-Object Installed"
Проблема. Массовый сбор обрывается на первом же сервере.
Invoke-Command : Connecting to remote server SRV-FILE01 failed with the following error message : WinRM cannot complete the operation.Enable-PSRemoting -Force
Test-WSMan SRV-FILE01
Test-WSMan должен вернуть блок с ProductVersion и StackVersion. Если связи нет — откройте порт 5985 в правилах файрвола.
Проблема. Не читаются установленные программы.
Get-ItemProperty : Cannot find path 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall' because it does not exist.'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*',
'SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*' |
ForEach-Object { Get-ItemProperty "HKLM:\$_" -ErrorAction SilentlyContinue } |
Where-Object DisplayName | Select-Object DisplayName, DisplayVersion
Вы получили inventory.csv со всеми серверами Windows Server 2016 и таблицу зависимостей «роль → целевой сервер». Дальше — согласовать даты отключения исходных машин и перенести следующий по списку сервер по отработанному на пилоте сценарию.
Когда именно заканчивается поддержка Windows Server 2016?
Точные даты в постах канала не приводились — откройте страницу жизненного цикла продукта в документации Microsoft и сверьте колонки основной и расширенной поддержки; версию своего сервера возьмите из Get-ComputerInfo.
Что произойдёт после окончания поддержки?
Сервер продолжит работать, но перестанет получать обновления безопасности. Условия продления обновлений (если они для вас доступны) — сверьтесь с документацией Microsoft.
Можно ли обновить Windows Server 2016 на месте, без нового сервера?
Поддерживаемые пути обновления зависят от редакции и целевой версии — сверьтесь с матрицей обновлений в документации. Для серверов с большим набором ролей безопаснее схема «новый сервер + перенос роли», как в шаге 3.
Как быстро понять масштаб работ, если серверов много?
Запустите сбор из шага 1 по файлу servers.txt и посчитайте строки: (Import-Csv C:\migration\inventory.csv).Count. Это число серверов, для которых нужен план миграции.