Windows Server для самых маленьких. Часть 19: Заменяем и выводим контроллеры домена
Все части серии «Windows Server для самых маленьких»Контроллер домена живёт столько, сколько живёт версия Windows Server на нём, — пять-десять лет, — и за это время его хотя бы раз переносят на новое железо, новый гипервизор или новую версию ОС. У Active Directory для этого есть удобное свойство: контроллер — не уникальная сущность, а одна из копий каталога, и заменить его можно, добавив новую копию и убрав старую. Так меняют железо, так переходят на новую версию ОС, так избавляются от контроллера, который умер, откатился в прошлое или пропустил полгода репликации (часть 18). Эта часть — про то, что при этом должно переехать вместе с контроллером, и про то, что от него остаётся в каталоге, если убрать его неправильно.
Команды выполняются с рабочей станции ws1 в PowerShell 7 (часть 15), всё, что должно работать на самом контроллере, — через Invoke-Command (часть 14). Домен тот же, что в части 18: corp.example.com, dc1 (192.168.1.10) и dc2 (192.168.1.11) в сайте Office, dc3 (192.168.2.10) и dc4 (192.168.2.11) в сайте Branch, все роли FSMO на dc1. dc3 — единственный контроллер на Windows Server 2019, и его мы заменяем: рядом встаёт dc5 (192.168.2.12) на Windows Server 2025, а dc3 понижается и уходит.
Новая версия — новый контроллер
Переход контроллеров с Windows Server 2019 на 2025 делается не обновлением, а заменой: рядом ставится контроллер на 2025, на него переезжает всё, старый понижается и выключается. Это называют swing migration, и Microsoft рекомендует именно его: чистая установка нового сервера, повышение до контроллера и понижение старого предпочтительнее обновления ОС на месте. Обновление на месте оставляет в системе всё, что накопилось за годы: драйверы, агенты, ключи реестра от продуктов, которых уже нет; при ошибке посреди обновления контроллер оказывается в состоянии, из которого нет пути ни вперёд, ни назад; и на время обновления контроллер недоступен, а при замене — никогда.
У Windows Server 2025 к этому добавился довод, которого раньше не было. Контроллер, поставленный заново, — новым или повышенным с репликацией по сети, — получает базу в формате со страницами 32 КБ (пока лес не перешёл на них, она работает в режиме совместимости с 8 КБ). Контроллер, обновлённый на месте, остаётся со своей базой на 8 КБ, а перейти на страницы 32 КБ лес может только тогда, когда такая база у каждого контроллера, — об этом ниже, в функциональных уровнях.
Обновление на месте для контроллеров поддерживается (с 2019 и 2022 до 2025), и у него есть честная область применения: единственный контроллер в маленьком домене на физическом сервере, рядом с которым некуда поставить второй. Но тогда схему и домен готовят вручную, до обновления первого контроллера.
Первый контроллер новой версии в лесу требует расширения схемы и подготовки домена. Утилита adprep с установочного носителя делает это в два шага: adprep /forestprep — один раз на лес, с правами Schema Admins, Enterprise Admins и Domain Admins и связью с владельцем Schema Master; adprep /domainprep — в каждом домене, с правами Domain Admins и связью с Infrastructure Master. При повышении нового сервера Install-ADDSDomainController выполняет обе подготовки сам, если у учётной записи хватает прав, или с отдельными учётными данными из параметра -ADPrepCredential. Версия схемы — атрибут objectVersion раздела схемы:
PS C:\> (Get-ADObject (Get-ADRootDSE).schemaNamingContext -Properties objectVersion).objectVersion
91
87 — Windows Server 2016, 88 — 2019 и 2022 (у 2022 своих изменений схемы нет), 91 — 2025: подготовка к 2025 применяет файлы sch89.ldf, sch90.ldf и sch91.ldf, и каждый заканчивается записью своего номера в objectVersion. 91 в нашем лесу означает, что схему к 2025 уже расширили — при вводе первого контроллера этой версии. Кто и когда, видно по метаданным репликации атрибута:
PS C:\> repadmin /showobjmeta dc1 "CN=Schema,CN=Configuration,DC=corp,DC=example,DC=com" | Select-String objectVersion
24616288 Office\DC2 28910296 2025-01-12 12:30:31 45 objectVersion
Изменение родилось на dc2: схему пишет только владелец роли Schema Master, в январе 2025 года роль была у dc2, а на dc1 её перенесли позже (перенос ролей и его следы в каталоге — в части 17). Версия атрибута 45 — столько раз его записывали за жизнь леса: по разу на каждый файл schNN.ldf, применённый с момента его создания. Изменение схемы необратимо (часть 5), поэтому его делают в окно обслуживания: не потому, что оно что-то ломает, а потому что отменить его нельзя.
Когда схема и домен уже подготовлены, повышение ничего не расширяет: мастер только проверяет отметки подготовки. Так это выглядит в журнале повышения dc4, %SystemRoot%\debug\dcpromoui.log:
PS C:\> Invoke-Command dc4 { Select-String -Path C:\Windows\debug\dcpromoui.log -Pattern 'ForestPrepIsDone|DomainPrepIsDone' | Select-Object -Last 2 | ForEach-Object Line }
dcpromoui 10D0.EDC 1404 09:29:56.362 testForestPrepIsDone <- "yes"
dcpromoui 10D0.EDC 1415 09:29:56.364 testDomainPrepIsDone <- "yes"
Поэтому для dc5 права Schema Admins не нужны: дополнительный контроллер в существующем домене ставит член Domain Admins.
Что проверить перед выводом
Выводим dc3. Сначала общая картина:
PS C:\> Get-ADDomainController -Filter * | Sort-Object Name | Format-Table Name, IPv4Address, Site, OperatingSystem, IsGlobalCatalog
Name IPv4Address Site OperatingSystem IsGlobalCatalog
---- ----------- ---- --------------- ---------------
DC1 192.168.1.10 Office Windows Server 2025 Standard True
DC2 192.168.1.11 Office Windows Server 2025 Standard True
DC3 192.168.2.10 Branch Windows Server 2019 Standard True
DC4 192.168.2.11 Branch Windows Server 2025 Standard True
И список того, что на уходящем контроллере есть и куда это переезжает.
Роли FSMO. netdom query fsmo — на dc3 ролей нет, все пять на dc1. Если они на уходящем контроллере, их переносят заранее, переносом, а не захватом (часть 17), а после переноса PDC — источник времени (часть 12). netdom не показывает двойников роли Infrastructure в разделах DNS, их владельцев смотрим отдельно:
PS C:\> 'DomainDnsZones', 'ForestDnsZones' | ForEach-Object { Get-ADObject "CN=Infrastructure,DC=$_,DC=corp,DC=example,DC=com" -Properties fSMORoleOwner } | Format-List DistinguishedName, fSMORoleOwner
DistinguishedName : CN=Infrastructure,DC=DomainDnsZones,DC=corp,DC=example,DC=com
fSMORoleOwner : CN=NTDS Settings,CN=DC2,CN=Servers,CN=Office,CN=Sites,CN=Configuration,DC=corp,DC=example,DC=com
DistinguishedName : CN=Infrastructure,DC=ForestDnsZones,DC=corp,DC=example,DC=com
fSMORoleOwner : CN=NTDS Settings,CN=DC2,CN=Servers,CN=Office,CN=Sites,CN=Configuration,DC=corp,DC=example,DC=com
У нас они на dc2. Если бы выводили dc2, их следовало бы перенести до понижения: иначе в атрибуте останется ссылка на удалённый объект, и следующее понижение или adprep /rodcprep споткнутся о неё (часть 17).
Глобальный каталог. В сайте должен остаться хотя бы один GC — иначе клиенты сайта пойдут за ним через канал между сайтами. dc4 — GC, dc5 станет GC по умолчанию.
DNS. Четыре вещи. Зоны в каталоге переедут сами, но пересылка (forwarders) — настройка сервера: при повышении мастер прописывает в неё тот DNS-сервер, которым пользовался новый сервер (у нас после повышения dc4 там оказался dc3), и её заменяют на настоящую. Очистка устаревших записей (scavenging), если она включена на уходящем сервере, включается на другом. DNS-клиенты соседних контроллеров указывают на партнёра по сайту первым (часть 10) — у dc4 первым стоит как раз dc3:
PS C:\> Get-DnsClientServerAddress -CimSession dc4 -AddressFamily IPv4 | Where-Object ServerAddresses | Format-Table InterfaceAlias, ServerAddresses
InterfaceAlias ServerAddresses
-------------- ---------------
Ethernet {192.168.2.10, 127.0.0.1}
И все, кто спрашивает dc3 напрямую: опция 6 DHCP, статические настройки серверов, /etc/resolv.conf на Linux, роутеры, принтеры. Опцию 6 в области сайта видно сразу:
PS C:\> Invoke-Command dc4 { Get-DhcpServerv4OptionValue -ScopeId 192.168.2.0 -OptionId 6 } | Format-Table OptionId, Name, Value
OptionId Name Value
-------- ---- -----
6 DNS Servers {192.168.2.10, 192.168.2.11}
Остальных — ниже.
DHCP. Область сайта обслуживают dc3 и dc4 в паре failover (часть 8):
PS C:\> Invoke-Command dc4 { Get-DhcpServerv4Failover } | Format-List Name, PartnerServer, Mode, LoadBalancePercent, ScopeId, State
Name : dc3-dc4
PartnerServer : dc3.corp.example.com
Mode : LoadBalance
LoadBalancePercent : 50
ScopeId : {192.168.2.0}
State : Normal
Связь failover не переносится на другой сервер, её разбирают и создают заново с dc5. Учётная запись для обновлений DNS от имени клиентов — настройка сервера, на dc5 её задают заново.
Время. Если уходит PDC — он источник времени домена. Если на уходящий контроллер указывали устройства не из домена (опция 42, NTP на коммутаторах и камерах) — их перенастраивают на другой.
Всё остальное, чего на контроллере быть не должно, но оно есть. NPS, Entra Connect, агенты резервного копирования, сертификаты, выданные на имя dc3, и приложения, в которых dc3.corp.example.com вписан как LDAP-сервер: системы заявок, VPN-шлюзы, Linux-машины с sssd, сканеры с «LDAP-аутентификацией». Они не найдут другой контроллер через DC Locator, потому что никогда им не пользовались.
Последний пункт — самый трудоёмкий, и закрыть его можно только одним способом: посмотреть, кто обращается к dc3. Первое — журнал Security, события выдачи билетов Kerberos 4768 (TGT) и 4769 (сервисный билет) по адресам клиентов. Адрес клиента у них в разных полях: у 4768 — Properties[9], у 4769 — Properties[6], и записан он как IPv4, отображённый в IPv6 (::ffff:192.168.2.42):
PS C:\> Invoke-Command dc3 {
$ids = 4768, 4769
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=$ids; StartTime=(Get-Date).AddDays(-7)} |
ForEach-Object { $ip = if ($_.Id -eq 4768) { $_.Properties[9].Value } else { $_.Properties[6].Value }; $ip -replace '^::ffff:' } |
Group-Object -NoElement | Sort-Object Count -Descending | Select-Object Count, Name -First 5
} | Format-Table Count, Name
Count Name
----- ----
962 192.168.2.42
958 192.168.2.43
944 192.168.2.41
810 192.168.2.21
738 192.168.2.23
Массив Id положен в переменную не случайно: в удалённом сеансе Windows PowerShell 5.1 литеральный массив в -FilterHashtable при выводе прямо в конвейер отвечает «No events were found…». Журнал Security на контроллере перезаписывается быстро — у нас он хранит чуть больше недели, — поэтому собирать адреса стоит несколько раз в разные дни.
Это те, кто аутентифицируется на dc3. Для членов домена это нормально: они выбрали его через Locator, и Locator же переведёт их на другой контроллер. Опаснее те, кто обращается к dc3 по LDAP без Kerberos, и те, кто спрашивает у него DNS. Для DNS у сервера есть отладочный журнал пакетов: по документации для записи входящих запросов нужно включить по одному параметру из каждой пары — направление, транспорт, содержимое и тип пакета:
PS C:\> Set-DnsServerDiagnostics -ComputerName dc3 -ReceivePackets $true -UdpPackets $true -TcpPackets $true -Queries $true -QuestionTransactions $true -EnableLoggingToFile $true
# через сутки
PS C:\> Set-DnsServerDiagnostics -ComputerName dc3 -ReceivePackets $false -UdpPackets $false -TcpPackets $false -Queries $false -QuestionTransactions $false
PS C:\> Invoke-Command dc3 {
Select-String -Path C:\Windows\System32\dns\dns.log -Pattern ' Rcv (\S+)' | ForEach-Object { $_.Matches[0].Groups[1].Value } |
Group-Object -NoElement | Sort-Object Count -Descending | Select-Object Count, Name -First 20
}
Журнал по умолчанию пишется в %SystemRoot%\System32\dns\dns.log. Выключают его теми же параметрами, а не -All $false: по документации -All касается всех настроек, кроме пути, размера файла, уровня событий, фильтра адресов и ротации, — то есть и EnableLoggingToFile, который у сервера по умолчанию включён. Каждый адрес в этом списке, который не рабочая станция с DHCP, — устройство или сервер с dc3 в настройках DNS. С LDAP так же: событие 2889 из части 18 перечисляет клиентов с небезопасными привязками (при включённой диагностике), а pktmon с фильтром на порты 389 и 636 за час покажет остальных.
Новый контроллер
dc5 на Windows Server 2025, подготовленный как в части 1 и введённый в домен, повышается как в части 10 — в сайт Branch, с источником репликации dc4:
PS C:\> Install-ADDSDomainController -DomainName corp.example.com -Credential (Get-Credential CORP\alice.admin) -SiteName Branch -ReplicationSourceDC dc4.corp.example.com -InstallDns -SafeModeAdministratorPassword (Read-Host -AsSecureString 'DSRM password') -Force
Команда выполняется на самом dc5: в консоли или через Invoke-Command с явным -Credential, иначе повышение упрётся во второй прыжок (часть 14) — ему нужно ходить на другие контроллеры. Если бы это был первый контроллер 2025 в лесу, учётной записи понадобилось бы членство в Schema Admins и Enterprise Admins или параметр -ADPrepCredential с такой учётной записью; членство в Schema Admins после этого снимают.
После перезагрузки — проверка из части 18: dcdiag /s:dc5 (тесты журналов с рабочей станции пропускаем /skip:), repadmin /showrepl dc5, состояние SYSVOL (DfsrReplicatedFolderInfo, State = 4) и событие DFS Replication 4604 — SYSVOL инициализирован.
Дальше всё, что переезжает, переезжает на dc5, пока dc3 жив. DNS-сервер и DNS-клиенты:
PS C:\> Set-DnsServerForwarder -ComputerName dc5 -IPAddress (Get-DnsServerForwarder -ComputerName dc4).IPAddress
PS C:\> Set-DnsClientServerAddress -CimSession dc4 -InterfaceAlias Ethernet -ServerAddresses 192.168.2.12, 127.0.0.1
PS C:\> Set-DnsClientServerAddress -CimSession dc5 -InterfaceAlias Ethernet -ServerAddresses 192.168.2.11, 127.0.0.1
Если бы уходил PDC, здесь же переезжали бы роли и источник времени — сначала роли, потом время: новый PDC берёт время снаружи, а старый возвращается в иерархию домена (часть 12):
PS C:\> Move-ADDirectoryServerOperationMasterRole -Identity dc5 -OperationMasterRole SchemaMaster, DomainNamingMaster, PDCEmulator, RIDMaster, InfrastructureMaster -Confirm:$false
PS C:\> Invoke-Command dc5 { w32tm /config /manualpeerlist:"0.pool.ntp.org,0x8 1.pool.ntp.org,0x8" /syncfromflags:manual /reliable:yes /update }
PS C:\> Invoke-Command dc1 { w32tm /config /syncfromflags:domhier /reliable:no /update }
DHCP — отдельной последовательностью, потому что failover не переносится, а пересоздаётся. Роль на dc5 ставится и авторизуется, как в части 8, затем область выводится из старой связи и входит в новую:
PS C:\> Install-WindowsFeature -ComputerName dc5 -Name DHCP -IncludeManagementTools
PS C:\> Invoke-Command dc5 { Add-DhcpServerSecurityGroup; Restart-Service DHCPServer }
PS C:\> Add-DhcpServerInDC -DnsName dc5.corp.example.com -IPAddress 192.168.2.12
PS C:\> Set-DhcpServerDnsCredential -ComputerName dc5 -Credential (Get-Credential CORP\svc-dhcp-dns)
PS C:\> Remove-DhcpServerv4FailoverScope -ComputerName dc4 -Name dc3-dc4 -ScopeId 192.168.2.0 -Force
PS C:\> Remove-DhcpServerv4Failover -ComputerName dc4 -Name dc3-dc4 -Force
PS C:\> Remove-DhcpServerInDC -DnsName dc3.corp.example.com -IPAddress 192.168.2.10
PS C:\> Add-DhcpServerv4Failover -ComputerName dc4 -PartnerServer dc5.corp.example.com -Name dc4-dc5 -ScopeId 192.168.2.0 -LoadBalancePercent 50 -SharedSecret (Read-Host 'Shared secret') -Force
PS C:\> Set-DhcpServerv4OptionValue -ComputerName dc4 -ScopeId 192.168.2.0 -DnsServer 192.168.2.11, 192.168.2.12
PS C:\> Invoke-DhcpServerv4FailoverReplication -ComputerName dc4 -Name dc4-dc5 -Force
Remove-DhcpServerv4FailoverScope, выполненный на dc4, по документации удаляет область у партнёра, dc3, и оставляет её с арендами на dc4; пустая связь удаляется следом. После снятия авторизации dc3 больше не выдаёт адреса. Add-DhcpServerv4Failover копирует область с арендами, резервированиями и опциями на dc5, а опцию 6 после неё меняем на одном сервере и реплицируем партнёру. Модуль DhcpServer в PowerShell 7 работает через слой совместимости (часть 15), с -ComputerName это не мешает. Область DHCPv6 (часть 9), если она была на dc3, создаётся на dc5 заново. И после всего — адреса из списка «кто спрашивает dc3», каждый руками.
Неделя между этим моментом и понижением — правильная пауза: за неё всплывёт то, что в список не попало.
Понижение
Понижение — обратная повышению операция, с той же парой Test- и Uninstall-. У Uninstall-ADDSDomainController два набора параметров — штатное понижение и принудительное:
PS C:\> Invoke-Command dc3 { Get-Command Uninstall-ADDSDomainController -Syntax }
Uninstall-ADDSDomainController [-SkipPreChecks] [-LocalAdministratorPassword <securestring>] [-Credential <pscredential>] [-DemoteOperationMasterRole] [-DnsDelegationRemovalCredential <pscredential>] [-IgnoreLastDCInDomainMismatch] [-IgnoreLastDnsServerForZone] [-LastDomainControllerInDomain] [-NoRebootOnCompletion] [-RemoveApplicationPartitions] [-RemoveDnsDelegation] [-RetainDCMetadata] [-Force] [-WhatIf] [-Confirm] [<CommonParameters>]
Uninstall-ADDSDomainController -ForceRemoval [-SkipPreChecks] [-LocalAdministratorPassword <securestring>] [-Credential <pscredential>] [-DemoteOperationMasterRole] [-NoRebootOnCompletion] [-Force] [-WhatIf] [-Confirm] [<CommonParameters>]
Штатное понижение dc3, так же через Invoke-Command с явными учётными данными, — понижению, как и повышению, нужно ходить на другие контроллеры:
PS C:\> $cred = Get-Credential CORP\alice.admin
PS C:\> $pass = Read-Host -AsSecureString 'New local Administrator password'
PS C:\> Invoke-Command dc3 { Test-ADDSDomainControllerUninstallation -Credential $using:cred -LocalAdministratorPassword $using:pass }
PS C:\> Invoke-Command dc3 { Uninstall-ADDSDomainController -Credential $using:cred -LocalAdministratorPassword $using:pass -Force }
Test-ADDSDomainControllerUninstallation выполняет те же предварительные проверки, что и понижение, ничего не меняя. -WhatIf у Uninstall-ADDSDomainController — другое: он только показывает, с какими явными и неявными значениями параметров пошло бы понижение. -LocalAdministratorPassword — пароль встроенного локального администратора, который снова появится на сервере вместе с локальной базой SAM; без параметра командлет спросит его сам. Остальное по документации:
-DemoteOperationMasterRole— продолжать принудительное понижение, даже если на контроллере нашлись роли FSMO; их потом захватывают на другом контроллере. В штатном понижении роли переносим заранее сами — так мы выбираем, кто их получит;-IgnoreLastDnsServerForZone— понижать, даже если контроллер — последний DNS-сервер для какой-то из зон в каталоге;-LastDomainControllerInDomainи-RemoveApplicationPartitions— понижение последнего контроллера, то есть удаление домена (нужны права Enterprise Admins), с удалением разделов приложений;-RemoveDnsDelegation— удалить делегирование на этот DNS-сервер в родительской зоне;-RetainDCMetadata— оставить метаданные контроллера в каталоге после понижения.
Что делает понижение: контроллер отдаёт партнёру несреплицированные изменения, его объект NTDS Settings удаляется, членство в репликации SYSVOL снимается, Netlogon снимает свои записи в DNS, учётная запись DC3$ становится обычной учётной записью сервера: userAccountControl 4096 вместо 532480, основная группа Domain Computers вместо Domain Controllers. Подробности пишутся в %SystemRoot%\debug\dcpromo.log и dcpromoui.log; в конце сервер перезагружается сам. После перезагрузки — удаление ролей:
PS C:\> Uninstall-WindowsFeature -ComputerName dc3 -Name AD-Domain-Services, DNS, DHCP -IncludeManagementTools
Удалить роль AD DS до понижения и перезагрузки нельзя: командлет откажет. Удалять её через DISM не поддерживается: сервер после этого не загрузится нормально. Дальше сервер либо используется как рядовой, либо выводится из домена Remove-Computer (в PowerShell 7 — через слой совместимости, проще выполнить его на самом сервере) и выключается.
Принудительное понижение — когда контроллер не может связаться ни с одним партнёром (сеть, сломанная репликация, USN rollback или пропущенный срок tombstone из части 18) и штатное отказывает:
PS C:\> Uninstall-ADDSDomainController -ForceRemoval -DemoteOperationMasterRole -LocalAdministratorPassword (Read-Host -AsSecureString 'New local Administrator password') -Force
Его выполняют на консоли самого контроллера: связи с другими контроллерами у него и так нет. -ForceRemoval делает всё локально и никому не сообщает: для остальных контроллеров леса этот контроллер продолжает существовать, а все его несреплицированные изменения — новые учётные записи, сменённые пароли — потеряны навсегда. Microsoft предупреждает, что такие брошенные метаданные — причина заметной доли обращений в поддержку по AD DS, Exchange и SQL Server. Так же остаётся в каталоге контроллер, который умер и которого просто нет. В обоих случаях сразу нужна очистка метаданных.
Очистка метаданных
Что от контроллера есть в лесу, видно на живом dc3. Три объекта, которые делают его контроллером: учётная запись компьютера, объект сервера в сайте и под ним NTDS Settings:
PS C:\> Get-ADDomainController dc3 | Format-List ComputerObjectDN, ServerObjectDN, NTDSSettingsObjectDN
ComputerObjectDN : CN=DC3,OU=Domain Controllers,DC=corp,DC=example,DC=com
ServerObjectDN : CN=DC3,CN=Servers,CN=Branch,CN=Sites,CN=Configuration,DC=corp,DC=example,DC=com
NTDSSettingsObjectDN : CN=NTDS Settings,CN=DC3,CN=Servers,CN=Branch,CN=Sites,CN=Configuration,DC=corp,DC=example,DC=com
Объекты соединений, по которым партнёры реплицируют с dc3, — у них в fromServer его NTDS Settings:
PS C:\> $ntds = (Get-ADDomainController dc3).NTDSSettingsObjectDN
PS C:\> Get-ADObject -SearchBase (Get-ADRootDSE).configurationNamingContext -LDAPFilter "(&(objectClass=nTDSConnection)(fromServer=$ntds))" | Select-Object DistinguishedName
DistinguishedName
-----------------
CN=DC3,CN=NTDS Settings,CN=DC1,CN=Servers,CN=Office,CN=Sites,CN=Configuration,DC=corp,DC=example,DC=com
CN=DC3,CN=NTDS Settings,CN=DC2,CN=Servers,CN=Office,CN=Sites,CN=Configuration,DC=corp,DC=example,DC=com
CN=8b9c0d1e-2f3a-4b5c-9d6e-7f8091a2b3c4,CN=NTDS Settings,CN=DC4,CN=Servers,CN=Branch,CN=Sites,CN=Configuration,DC=corp,DC=example,DC=com
Соединение с именем-GUID создал KCC (часть 10), и он же уберёт его, когда dc3 не станет. Два соединения с именем DC3 созданы когда-то вручную, а созданные вручную соединения KCC не изменяет и не удаляет: они живут, пока их не удалит администратор. Всё с именем DC3 в разделах конфигурации и домена:
PS C:\> Get-ADObject -SearchBase (Get-ADRootDSE).configurationNamingContext -LDAPFilter '(cn=DC3)' | Format-Table ObjectClass, DistinguishedName
ObjectClass DistinguishedName
----------- -----------------
server CN=DC3,CN=Servers,CN=Branch,CN=Sites,CN=Configuration,DC=corp,DC=example,DC=com
nTDSConnection CN=DC3,CN=NTDS Settings,CN=DC1,CN=Servers,CN=Office,CN=Sites,CN=Configuration,DC=corp,DC=example,DC=com
nTDSConnection CN=DC3,CN=NTDS Settings,CN=DC2,CN=Servers,CN=Office,CN=Sites,CN=Configuration,DC=corp,DC=example,DC=com
PS C:\> Get-ADObject -SearchBase (Get-ADRootDSE).defaultNamingContext -LDAPFilter '(cn=DC3)' | Format-Table ObjectClass, DistinguishedName
ObjectClass DistinguishedName
----------- -----------------
computer CN=DC3,OU=Domain Controllers,DC=corp,DC=example,DC=com
msDFSR-Member CN=DC3,CN=Topology,CN=Domain System Volume,CN=DFSR-GlobalSettings,CN=System,DC=corp,DC=example,DC=com
msDFSR-Member — участник репликации SYSVOL. Плюс записи в DNS (о них ниже) и, возможно, роли FSMO. Пока NTDS Settings существует, остальные контроллеры считают dc3 партнёром: репликация с ним пытается и падает, repadmin /replsummary и dcdiag показывают ошибки, KCC строит топологию в обход.
Очистка метаданных убирает из каталога то, по чему система репликации узнаёт контроллер, соединения FRS и DFS Replication и пытается перенести или захватить роли FSMO, которые были у удалённого контроллера. Выполняют её на контроллере того же домена, лучше — на прямом партнёре удалённого. Способов два, и оба описаны в документации.
Оснастки. С Windows Server 2008 удаление учётной записи контроллера в Active Directory Users and Computers из OU Domain Controllers выполняет очистку автоматически: оснастка спрашивает, что контроллер окончательно недоступен, предупреждает, если он был GC, и предлагает контроллер, которому уйдут его роли. То же в Active Directory Sites and Services, но там сначала удаляют NTDS Settings, потом объект сервера. Если удаление отвечает «Access is denied», у объекта включена защита от случайного удаления — её снимают.
ntdsutil — тот же процесс из командной строки на контроллере или машине с RSAT:
C:\> ntdsutil
ntdsutil: metadata cleanup
metadata cleanup: connections
server connections: connect to server dc4.corp.example.com
server connections: quit
metadata cleanup: remove selected server CN=DC3,CN=Servers,CN=Branch,CN=Sites,CN=Configuration,DC=corp,DC=example,DC=com
metadata cleanup: quit
ntdsutil: quit
connect to server — к партнёру удалённого контроллера по репликации; remove selected server открывает окно подтверждения, после которого ntdsutil сообщает, что сервер удалён, или — если объекта уже нет — что он не найден. Если под объектом сервера после очистки ничего не осталось, его удаляют; если остались дочерние объекты, сервер не трогают: ими пользуется другое приложение.
Отдельного командлета для очистки в модуле ActiveDirectory нет. После неё повторяем поиск выше: Get-ADObject по (cn=DC3) в обоих разделах и соединения с fromServer не должны вернуть ничего, кроме того, что нужно удалить руками (созданные вручную соединения, пустой объект сервера), а Get-ADDomainController dc3 — отвечать ошибкой.
DNS. Записи контроллера в DNS — отдельная история. При штатном понижении свои SRV- и A-записи должен снять Netlogon, но NS-записи в зонах, где контроллер был сервером имён, и PTR стоит проверить в любом случае; после принудительного понижения или смерти контроллера не снимает никто. Найти всё, что указывает на dc3, по имени или адресу, во всех основных зонах сервера:
PS C:\> $pattern = '^dc3\.corp\.example\.com\.$|^192\.168\.2\.10$'
PS C:\> $records = Get-DnsServerZone -ComputerName dc1 | Where-Object { -not $_.IsAutoCreated -and $_.ZoneType -eq 'Primary' } | ForEach-Object {
$zone = $_.ZoneName
Get-DnsServerResourceRecord -ComputerName dc1 -ZoneName $zone |
Where-Object { $_.RecordData.CimInstanceProperties.Value -match $pattern } |
Select-Object @{n='Zone'; e={$zone}}, HostName, RecordType, @{n='Data'; e={$_.RecordData.CimInstanceProperties.Value -join ' '}}
}
PS C:\> $records | Where-Object Zone -eq '_msdcs.corp.example.com' | Format-Table HostName, RecordType, Data
HostName RecordType Data
-------- ---------- ----
@ NS dc3.corp.example.com.
6e5d4c3b-2a19-4f08-8e7d-6c5b4a392817 CNAME dc3.corp.example.com.
_kerberos._tcp.Branch._sites.dc SRV dc3.corp.example.com. 88 0 100
_ldap._tcp.Branch._sites.dc SRV dc3.corp.example.com. 389 0 100
_kerberos._tcp.dc SRV dc3.corp.example.com. 88 0 100
_ldap._tcp.dc SRV dc3.corp.example.com. 389 0 100
_ldap._tcp.7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f.domains SRV dc3.corp.example.com. 389 0 100
gc A 192.168.2.10
_ldap._tcp.Branch._sites.gc SRV dc3.corp.example.com. 3268 0 100
_ldap._tcp.gc SRV dc3.corp.example.com. 3268 0 100
Данные записи берутся из CimInstanceProperties объекта RecordData: у каждого типа записи свои свойства (IPv4Address у A, DomainName, Port, Priority, Weight у SRV, NameServer у NS), а RecordData.PSObject.Properties заодно вернул бы служебные свойства CIM-объекта. Шаблон привязан к началу и концу значения, чтобы dc3 из чужой зоны (например, сервер имён в stub-зоне доверенного леса) не попал в список. Всего у живого dc3 таких записей несколько десятков: 20 SRV, CNAME <GUID>._msdcs из части 18, пять A-записей (имя домена, dc3, gc._msdcs, DomainDnsZones, ForestDnsZones), PTR и NS в каждой зоне, где он сервер имён. Удаляет их Remove-DnsServerResourceRecord, которому можно передать найденные объекты по конвейеру, — например, все SRV dc3 в зоне домена:
PS C:\> Get-DnsServerResourceRecord -ComputerName dc4 -ZoneName corp.example.com -RRType Srv |
Where-Object { $_.RecordData.DomainName -eq 'dc3.corp.example.com.' } |
Remove-DnsServerResourceRecord -ComputerName dc4 -ZoneName corp.example.com -Force
Последняя проверка — repadmin /replsummary и dcdiag /s:dc4 /e /q без упоминаний dc3.
Старое имя
Приложения с dc3.corp.example.com в настройках — причина, по которой имя хочется сохранить. Три способа.
Повторно использовать имя. После понижения или очистки метаданных и репликации учётную запись DC3 удаляют (Remove-Computer её только отключает), и новый сервер можно назвать dc3 и повысить: учётной записи больше нет, конфликта не будет. Адрес тоже можно взять старый. Это самый чистый вариант, если между выводом старого и вводом нового есть пауза. Если учётная запись контроллера с таким именем ещё есть, Install-ADDSDomainController откажется продолжать без -AllowDomainControllerReinstall.
Дополнительное имя. Контроллер может отзываться на несколько DNS-имён: netdom computername dc5.corp.example.com /add:dc3.corp.example.com записывает второе имя в атрибут msDS-AdditionalDnsHostName учётной записи, добавляет SPN на него и регистрирует для него записи в DNS, так что Kerberos к ldap/dc3.corp.example.com начинает работать на dc5. Старая учётная запись DC3 к этому моменту должна быть удалена: иначе те же SPN окажутся на двух учётных записях. Это штатный механизм, задуманный для переименования контроллеров (/add, затем /makeprimary и после перезагрузки /remove старого имени), и он работает для всего, что ходит по Kerberos. Что у контроллера с именами сейчас, показывают /enumerate и /verify:
PS C:\> Invoke-Command dc3 { netdom computername dc3.corp.example.com /enumerate; netdom computername dc3.corp.example.com /verify }
All of the names for the computer are:
dc3.corp.example.com
The command completed successfully.
All of the computer's names have A records that are properly registered
with DNS.
All of the computer's names have properly registered host Service Principal
Names in the Active Directory Domain Services.
The command completed successfully.
CNAME dc3 → dc5 — только для того, что ходит по LDAP с простой привязкой или по IP: клиент Kerberos попросит билет на имя dc3, SPN с таким именем ни у кого нет, и проверка подлинности откатится на NTLM (часть 6). Худший из трёх.
Функциональные уровни
Функциональный уровень домена и леса определяет две вещи: какие функции каталога включены и контроллеры каких версий могут работать в этом домене и лесу. Какой уровень понимает каждый контроллер, записано в атрибуте msDS-Behavior-Version его NTDS Settings: 7 — Windows Server 2016 (у 2019 и 2022 своего уровня нет, они на том же 2016), 10 — 2025. В сайте Branch до замены:
PS C:\> Get-ADObject -SearchBase "CN=Branch,CN=Sites,$((Get-ADRootDSE).configurationNamingContext)" -LDAPFilter '(objectClass=nTDSDSA)' -Properties 'msDS-Behavior-Version', 'msDS-JetDBPageSize' |
Format-Table @{n='Server'; e={($_.DistinguishedName -split ',')[1] -replace 'CN='}}, 'msDS-Behavior-Version', 'msDS-JetDBPageSize'
Server msDS-Behavior-Version msDS-JetDBPageSize
------ --------------------- ------------------
DC3 7
DC4 10 32768
msDS-JetDBPageSize 32768 у dc4 — та самая база со страницами 32 КБ: dc4 повышен на чистой Windows Server 2025. У контроллера 2025, обновлённого на месте, здесь было бы 8192, у dc3 на 2019 атрибута нет вовсе. Уровень самого домена и леса — тот же атрибут на корне домена и на CN=Partitions:
PS C:\> (Get-ADDomain).DomainMode
Windows2016Domain
PS C:\> (Get-ADForest).ForestMode
Windows2016Forest
PS C:\> (Get-ADObject "CN=Partitions,$((Get-ADRootDSE).configurationNamingContext)" -Properties 'msDS-Behavior-Version').'msDS-Behavior-Version'
7
Контроллер Windows Server 2025 работает на уровнях 2016 и 2025, но не ниже (2012 R2 для него уже не поддерживается); контроллеры 2016, 2019 и 2022 — на уровнях 2012 R2 и 2016. Поэтому, пока в лесу есть dc3, уровень 2025 недоступен, а после его вывода — можно поднимать. Что дают уровни, на которых могут жить сегодняшние контроллеры:
| Уровень | Что даёт |
|---|---|
| 2012 R2 | защита группы Protected Users на стороне контроллера (без NTLM, DES и RC4 в предварительной аутентификации, делегирования и продления TGT дольше четырёх часов), политики аутентификации и силосы политик |
| 2016 | для леса — управление привилегированным доступом (PAM) с Microsoft Identity Manager; для домена — автоматическая смена NTLM-секретов у учётных записей, которым требуется вход по смарт-карте, сетевой NTLM для пользователей, ограниченных определёнными компьютерами, SID свежести ключа при PKInit Freshness |
| 2025 | необязательная функция Database 32k pages — страницы базы 32 КБ вместо 8 |
Делегированных управляемых учётных записей служб (dMSA) из Windows Server 2025 в списке функций уровня нет. Корзина AD, PAM и страницы 32 КБ — необязательные функции леса, и каждая требует своего уровня:
PS C:\> Get-ADOptionalFeature -Filter * | Format-Table Name, RequiredForestMode
Name RequiredForestMode
---- ------------------
Recycle Bin Feature Windows2008R2Forest
Privileged Access Management Feature Windows2016Forest
Database 32k Pages Feature Windows2025Forest
Подъём уровня — две команды; сначала домен, потом лес, потому что уровень домена не может быть ниже уровня леса:
PS C:\> Set-ADDomainMode -Identity corp.example.com -DomainMode Windows2025Domain
PS C:\> Set-ADForestMode -Identity corp.example.com -ForestMode Windows2025Forest
Каждая меняет один атрибут msDS-Behavior-Version — на корне домена и на CN=Partitions — до значения 10, и изменение расходится обычной репликацией. Обратно уровень не опускается (исключения — частные случаи отката на 2008 R2 и 2012 R2), и контроллер более старой версии в такой лес уже не войдёт. Включение страниц 32 КБ — отдельный шаг после этого: все контроллеры леса должны быть на 2025 с базой, поддерживающей 32 КБ, то есть поставленные заново, а не обновлённые на месте; включение необратимо, и резервные копии с базой на 8 КБ после него для восстановления не годятся. Резервное копирование — тема части 20.
Смотрим руками
Как появляется контроллер в конфигурации леса. Объект NTDS Settings нового контроллера создаётся не на нём самом, а на источнике репликации, через который идёт повышение. Метаданные NTDS Settings у dc4, который повышали с dc3:
PS C:\> repadmin /showobjmeta dc1 "CN=NTDS Settings,CN=DC4,CN=Servers,CN=Branch,CN=Sites,CN=Configuration,DC=corp,DC=example,DC=com" | Select-String '^Loc.USN|objectClass|invocationId|1 options|Behavior-Version|JetDBPageSize'
Loc.USN Originating DSA Org.USN Org.Time/Date Ver Attribute
56534580 Branch\DC3 37019648 2026-09-22 19:30:06 1 objectClass
56534580 Branch\DC3 37019648 2026-09-22 19:30:06 1 invocationId
56534580 Branch\DC3 37019648 2026-09-22 19:30:06 1 options
56534580 Branch\DC3 37019648 2026-09-22 19:30:06 1 msDS-Behavior-Version
56534735 Branch\DC4 24586 2026-09-22 19:31:53 1 msDS-JetDBPageSize
objectClass, invocationId, options (бит GC) и уровень контроллера записал dc3 — в момент, когда мастер на dc4 попросил его создать объект. Через две минуты, уже со своей базой, dc4 дописал размер страницы — изменение с маленьким USN самого dc4 (24586), который только начал свою историю. С dc5 будет так же, только источником станет dc4. Понижение проходит этот путь в обратную сторону: NTDS Settings удаляется, а объект сервера остаётся, потому что под ним могут жить объекты других приложений.
Учётные записи контроллеров отличаются от остальных компьютеров основной группой 516 (Domain Controllers) и флагами:
PS C:\> Get-ADComputer -Filter 'primaryGroupID -eq 516' -Properties userAccountControl | Format-Table Name, userAccountControl, DistinguishedName
Name userAccountControl DistinguishedName
---- ------------------ -----------------
DC2 532480 CN=DC2,OU=Domain Controllers,DC=corp,DC=example,DC=com
DC1 532480 CN=DC1,OU=Domain Controllers,DC=corp,DC=example,DC=com
DC3 532480 CN=DC3,OU=Domain Controllers,DC=corp,DC=example,DC=com
DC4 532480 CN=DC4,OU=Domain Controllers,DC=corp,DC=example,DC=com
532480 — это SERVER_TRUST_ACCOUNT (8192, учётная запись контроллера) плюс TRUSTED_FOR_DELEGATION (524288). После штатного понижения у DC3 останется 4096 — WORKSTATION_TRUST_ACCOUNT, как у любого рядового сервера, — основная группа 515, и в этом списке его не будет; после принудительного понижения без очистки он останется здесь как ни в чём не бывало.
Источники
- Upgrade domain controllers to a newer version of Windows Server — рекомендация заменять, а не обновлять,
adprep /forestprepи/domainprep, нужные права и роли FSMO, порядок ввода нового контроллера и вывода старого; - Windows Server Active Directory schema updates — файлы
schNN.ldfи версии схемы 87, 88 и 91; - Install-ADDSDomainController —
-ADPrepCredential,-ReplicationSourceDC,-AllowDomainControllerReinstall, автоматическая настройка DNS-клиента и пересылки; - Uninstall-ADDSDomainController и Test-ADDSDomainControllerUninstallation — наборы параметров,
-DemoteOperationMasterRole,-ForceRemoval, проверки против-WhatIf; - Demote domain controllers and domains — понижение, принудительное понижение и его последствия, журналы, удаление роли после перезагрузки;
- Uninstall-WindowsFeature — удаление ролей с
-IncludeManagementTools; - Clean up AD DS server metadata — очистка метаданных через оснастки и
ntdsutil, защита от случайного удаления; - How Active Directory Replication Topology Works — соединения, созданные вручную, KCC не изменяет и не удаляет;
- Move-ADDirectoryServerOperationMasterRole — перенос ролей FSMO;
- 4768 и 4769 — поля событий выдачи билетов Kerberos, адрес клиента;
- Set-DnsServerDiagnostics — отладочный журнал DNS-сервера, обязательные пары параметров и
-All; - Set-DnsServerForwarder и Set-DnsClientServerAddress — пересылка и DNS-клиент контроллеров;
- Get-DnsServerResourceRecord и Remove-DnsServerResourceRecord — поиск и удаление записей, передача по конвейеру;
- Remove-DhcpServerv4FailoverScope, Remove-DhcpServerv4Failover, Add-DhcpServerv4Failover и Invoke-DhcpServerv4FailoverReplication — пересоздание связи failover, судьба области у партнёра;
- Netdom computername и Rename a domain controller using Netdom — дополнительные имена контроллера, SPN и записи DNS для них;
- ms-DS-Additional-Dns-Host-Name — атрибут дополнительных имён;
- Active Directory Domain Services functional levels — совместимость уровней и версий контроллеров, функции уровней 2012 R2, 2016 и 2025;
- How to raise Active Directory domain and forest functional levels и ms-DS-Behavior-Version — порядок подъёма, необратимость, где хранится уровень;
- Set-ADDomainMode и Set-ADForestMode — подъём уровней из PowerShell;
- Database 32k pages for Active Directory и What's new in Windows Server 2025 — база со страницами 32 КБ у новых и обновлённых контроллеров, требования и необратимость;
- Delegated Managed Service Accounts overview — dMSA в Windows Server 2025;
- Use the UserAccountControl flags — значения флагов
userAccountControl.
Мы умеем заменять контроллеры и чистить за ними. Остался последний сценарий эксплуатации, самый неприятный: не один контроллер, а каталог целиком, или объекты в нём, которых больше нет ни на одном контроллере.
Дальше — часть 20: резервное копирование и восстановление. Что такое состояние системы и чем резервная копия каталога отличается от копии диска; wbadmin и Windows Server Backup; корзина AD и её пределы; неавторитетное восстановление контроллера и авторитетное восстановление объектов, которые удалили на всех; восстановление SYSVOL в режимах D2 и D4; и снимки виртуальных машин — что они дают, чего не дают и что делает с ними VM-GenerationID.
Оставить комментарий могут только зарегистрированные пользователи.
Войдите на сайт или зарегистрируйтесь, чтобы оставить комментарий.