Windows Server для самых маленьких. Часть 18: Как искать неисправности в домене?

Все части серии «Windows Server для самых маленьких»

«Домен не работает» означает одно из десяти разных состояний, и у каждого свои признаки. В предыдущих частях инструменты диагностики появлялись по одному: dcdiag в части 4, событие 1644 в части 5, ошибки Kerberos в части 6, repadmin в части 10, w32tm /monitor в части 12. Здесь они складываются в порядок действий, а вторая половина части — о трёх состояниях каталога, которые не лечатся перезагрузкой: объекты, вернувшиеся с того света, контроллер, откатившийся в прошлое, и контроллер, пропустивший полгода.

Все команды ниже выполняются с рабочей станции администратора ws1 с RSAT (часть 15) в PowerShell 7; то, что читает журналы и реестр контроллеров, идёт через Invoke-Command (часть 14). В примерах домен corp.example.com с четырьмя контроллерами: dc1 и dc2 в сайте Office, dc3 и dc4 в сайте Branch; dc1 — PDC, dc3 работает на Windows Server 2019, остальные — на 2025.


Порядок проверки

Пять шагов, всегда в этом порядке:

1. dcdiag /s:dc1 /e /q — все контроллеры леса, только ошибки. Без /s: на рабочей станции dcdiag отвечает «is not a Directory Server. Must specify /s:<Directory Server>…»: по умолчанию он проверяет локальную машину. Непустой вывод — читаем, какой тест на каком контроллере, и помним, что не всякий failed — неисправность (об этом ниже).

2. repadmin /replsummary — репликация во всём лесу одной таблицей: наибольшая дельта и число неудач по каждому контроллеру как источнику и как приёмнику. Затем repadmin /showrepl <контроллер> для тех, где ошибки, с кодом.

PS C:\> repadmin /replsummary
Replication Summary Start Time: 2026-10-29 07:44:36

Beginning data collection for replication summary, this may take awhile:
  .......


Source DSA          largest delta    fails/total %%   error
 DC1                       11m:17s    0 /  10    0
 DC2                       10m:17s    0 /  10    0
 DC3                       13m:31s    0 /  15    0
 DC4                       10m:17s    0 /   5    0


Destination DSA     largest delta    fails/total %%   error
 DC1                       03m:31s    0 /  10    0
 DC2                       11m:17s    0 /  10    0
 DC3                       10m:17s    0 /  15    0
 DC4                       13m:31s    0 /   5    0

largest delta — сколько прошло с последней успешной репликации по самой отстающей связи; норма — минуты внутри сайта и не больше интервала связи сайтов между ними (по умолчанию 180 минут). fails/total — неудачные связи из всех; у DC3 их 15 в обе стороны, потому что он плацдарм сайта Branch и связан по пяти разделам с DC1, DC2 и DC4.

3. Журналы контроллеров: Directory Service, DNS Server, DFS Replication, System за последние сутки, только ошибки и предупреждения, сгруппированные по источнику — шаблон из части 1, выполненный на контроллерах через Invoke-Command (готовый вариант — в конце части).

4. w32tm /monitor — время, потому что половина ошибок аутентификации и репликации — это оно.

5. nltest на клиенте, который жалуется: находит ли он контроллер, цел ли защищённый канал.

Дальше — по тому, что нашлось.


dcdiag

Тесты, которые мы видели зелёными в части 4 (в списке dcdiag /? их 29), и ключи, которые делают утилиту инструментом, а не ритуалом:

Ключ Что
/s:dc2 проверять указанный контроллер; без ключа — локальную машину, поэтому на рабочей станции он обязателен
/e все контроллеры леса (/a — все контроллеры сайта)
/q печатать только ошибки
/v подробно: что именно проверялось и что получено
/c все тесты, включая те, что по умолчанию не выполняются (DNS, Topology, CutoffServers, OutboundSecureChannels), кроме DcPromo и RegisterInDNS
/test:X, /skip:X только этот тест или всё, кроме него; ключей может быть несколько
/f:файл вывод в файл
/fix действует только на тест MachineAccount: исправляет SPN в учётной записи контроллера
/test:dns /DnsBasic, /DnsForwarders, /DnsDelegation, /DnsDynamicUpdate, /DnsRecordRegistration, /DnsResolveExtName подтесты DNS по отдельности; без подтеста выполняются все, кроме /DnsResolveExtName
/test:CheckSecurityError /ReplSource:dc1 проверки безопасности, мешающие репликации; с /ReplSource — ещё и связь с конкретным партнёром
/test:CutoffServers контроллеры, с которыми никто не может реплицироваться; по документации тест вызывает DsReplicaSyncAll и тем самым запускает репликацию
/test:Topology, /test:CrossRefValidation, /test:VerifyEnterpriseReferences связность топологии KCC (анализ без репликации), объекты разделов, ссылки на контроллеры из конфигурации

Первый запуск с рабочей станции обычно выглядит так:

PS C:\> dcdiag /s:dc1 /e /q | Select-String 'failed test'

         ......................... DC1 failed test DFSREvent
         ......................... DC1 failed test KccEvent
         ......................... DC1 failed test SystemLog
         ......................... DC3 failed test DFSREvent
         ......................... DC3 failed test KccEvent
         ......................... DC3 failed test Services
         ......................... DC3 failed test SystemLog
         ......................... DC4 failed test DFSREvent
         ......................... DC4 failed test KccEvent
         ......................... DC4 failed test SystemLog

Десять «провалов», и ни один не означает неисправности каталога. Тесты DFSREvent, KccEvent, SystemLog (и FrsEvent) читают журналы контроллеров по протоколу удалённого журнала событий поверх RPC, а правила файрвола Remote Event Log Management на сервере по умолчанию выключены (часть 14): над каждой такой строкой стоит «could not be queried, error 0x6ba "The RPC server is unavailable."». У Microsoft это описано как ожидаемое поведение: либо включить три правила Remote Event Log Management на контроллерах, либо пропускать эти тесты и читать журналы иначе. В этой серии журналы читаются через Invoke-Command, поэтому тесты пропускаем:

PS C:\> dcdiag /s:dc1 /e /q /skip:SystemLog /skip:DFSREvent /skip:KccEvent
            Invalid service type: DnsCache on DC3, current value
            WIN32_SHARE_PROCESS, expected value WIN32_OWN_PROCESS
         ......................... DC3 failed test Services

Остался один, и он тоже ложный. Тест Services сверяет не только состояние служб, но и тип их процесса со списком, зашитым в саму утилиту. В Windows Server 2025 и Windows 11 клиент DNS (DnsCache) работает в собственном процессе, в 2019 — в общем svchost, и dcdiag с рабочей станции Windows 11 считает это ошибкой на контроллере 2019. Тот же тест, запущенный на самом dc3 его собственной версией dcdiag, проходит:

PS C:\> Invoke-Command dc3 { dcdiag /test:services } | Select-String 'Services'
      Starting test: Services
         ......................... DC3 passed test Services

Microsoft описывает ту же историю для службы RpcSs и Windows Server 2003 и советует не менять тип службы по подсказке dcdiag чужой версии. Правило отсюда общее: в лесу с контроллерами разных версий результат тестов, привязанных к версии ОС, проверяют утилитой с того же контроллера.

Когда тест падает по-настоящему, главное — не строка failed, а то, что над ней. Для теста Replications документация Microsoft (статья об ошибке −2146893022) приводит такой шаблон:

[Replications Check,<DC Name>] A recent replication attempt failed:
From <source DC> to <destination DC>
Naming Context: <DN path of directory partition>
The replication generated an error (-2146893022):
The target principal name is incorrect.
The failure occurred at <date> <time>.
The last success occurred at <date> <time>.
<X> failures have occurred since the last success.

Код, направление, раздел, время последнего успеха, число неудач — этого достаточно, чтобы понять, какая связь сломана и с какого момента. Здоровый контроллер на этом месте выдаёт только строку passed:

PS C:\> dcdiag /s:dc3 /test:replications

Directory Server Diagnosis

Performing initial setup:
   * Identified AD Forest.
   Done gathering initial info.

Doing initial required tests

   Testing server: Branch\DC3
      Starting test: Connectivity
         ......................... DC3 passed test Connectivity

Doing primary tests

   Testing server: Branch\DC3
      Starting test: Replications
         ......................... DC3 passed test Replications


   Running partition tests on : ForestDnsZones

   Running partition tests on : DomainDnsZones

   Running partition tests on : Schema

   Running partition tests on : Configuration

   Running partition tests on : corp

   Running enterprise tests on : corp.example.com

Тест Replications падает, если последняя попытка репликации по связи завершилась ошибкой, если репликация выключена или если задержка больше 12 часов.

CheckSecurityError — тест, который стоит знать отдельно: он не выполняется по умолчанию и проверяет то, что repadmin покажет одной цифрой вроде 8453 «Replication access was denied». Без партнёра он ищет KDC домена, проверяет, что объект контроллера реплицирован, флаги и минимальный набор SPN его учётной записи, ошибки безопасности в состоянии репликации и не мешает ли размер пакета Kerberos поверх UDP. С /ReplSource:dc1 добавляются расхождение времени с партнёром (больше 300 секунд — отказ Kerberos), права на разделы, доступ к SYSVOL и NETLOGON и версия объекта контроллера у партнёра.

PS C:\> dcdiag /s:dc3 /test:CheckSecurityError /v | Select-String 'Found KDC|Checking machine account|security related|passed test CheckSecurityError'
         Found KDC DC3 for domain corp.example.com in site Branch
         Checking machine account for DC DC3 on DC DC3.
         [DC3] No security related replication errors were found on this DC!
         ......................... DC3 passed test CheckSecurityError

repadmin

Четыре команды из части 10 плюс те, что нужны для разбора:

PS C:\> repadmin /showrepl * /csv | ConvertFrom-Csv | Where-Object 'Number of Failures' -gt 0 |
    Format-Table 'Destination DSA', 'Source DSA', 'Naming Context', 'Number of Failures', 'Last Failure Status', 'Last Success Time'

/showrepl * /csv — все входящие связи всех контроллеров одной таблицей, и дальше с ней работает PowerShell; это команда, которую кладут в задачу планировщика с отправкой по почте. В здоровом лесу этот фильтр не выводит ничего. Как выглядят строки без фильтра:

PS C:\> repadmin /showrepl * /csv | ConvertFrom-Csv | Select-Object -First 3 |
    Format-Table 'Destination DSA', 'Source DSA', 'Naming Context', 'Number of Failures', 'Last Success Time'

Destination DSA Source DSA Naming Context                             Number of Failures Last Success Time
--------------- ---------- --------------                             ------------------ -----------------
DC2             DC3        DC=corp,DC=example,DC=com                  0                  2026-10-29 07:33:19
DC2             DC1        DC=corp,DC=example,DC=com                  0                  2026-10-29 07:36:32
DC2             DC1        CN=Configuration,DC=corp,DC=example,DC=com 0                  2026-10-29 07:33:19

Все поля CSV — строки, поэтому числа выровнены по левому краю. То же из модуля ActiveDirectory: Get-ADReplicationFailure и Get-ADReplicationPartnerMetadata. Обоим с -Scope Forest нужен -Target с именем леса, без него второй отвечает «The format of the specified domain name is invalid.»; Get-ADReplicationPartnerMetadata по умолчанию показывает только раздел домена, все разделы — с -Partition *.

PS C:\> Get-ADReplicationFailure -Target corp.example.com -Scope Forest
PS C:\> Get-ADReplicationPartnerMetadata -Target corp.example.com -Scope Forest |
    Format-Table Server, @{n='Partner'; e={($_.Partner -split ',')[1] -replace 'CN='}}, LastReplicationResult, ConsecutiveReplicationFailures, LastReplicationSuccess

Server               Partner LastReplicationResult ConsecutiveReplicationFailures LastReplicationSuccess
------               ------- --------------------- ------------------------------ ----------------------
dc2.corp.example.com DC1                         0                              0 29.10.2026 7:36:32
dc2.corp.example.com DC3                         0                              0 29.10.2026 7:33:19
dc1.corp.example.com DC2                         0                              0 29.10.2026 7:37:43
dc1.corp.example.com DC3                         0                              0 29.10.2026 7:26:05
dc3.corp.example.com DC4                         0                              0 29.10.2026 7:38:18
dc3.corp.example.com DC1                         0                              0 29.10.2026 7:34:20
dc3.corp.example.com DC2                         0                              0 29.10.2026 7:34:19
dc4.corp.example.com DC3                         0                              0 29.10.2026 7:37:45

Partner — DN объекта NTDS Settings партнёра, второй его компонент — имя сервера.

  • repadmin /queue dc1 — очередь входящей репликации: что контроллер ещё должен запросить у партнёров. В здоровом лесу — Queue contains 0 items.; растущая очередь означает, что контроллер не успевает (слишком много партнёров, изменений или мало канала).
  • repadmin /showutdvec dc1 DC=corp,DC=example,DC=com — вектор актуальности: до какого USN каждого контроллера дошёл dc1, включая давно удалённые контроллеры и прежние invocationID (они помечены (retired) или показаны GUID). С /latency строки сортируются от самой отстающей.
  • repadmin /showchanges dc1 <objectGUID NTDS Settings dc2> DC=corp,DC=example,DC=com — что dc1 ещё не получил от dc2. Источник задаётся не именем, а GUID объекта NTDS Settings.
  • repadmin /latency — задержка репликации по отметкам ISTG; по справке самой утилиты в лесах с уровнем Windows Server 2003 и выше эти отметки не обновляются, и вместо неё нужен repadmin /showutdvec … /latency. В нашем лесу /latency показывает отметки многолетней давности.
  • repadmin /showsig dc1 — текущий invocationID контроллера и список прежних, «отставленных»: каждая запись — восстановление из резервной копии или откат, замеченный по VM-GenerationID.
  • repadmin /istg и /bridgeheads — кто строит межсайтовую топологию и через кого идёт репликация между сайтами.
PS C:\> repadmin /showsig dc1
Office\DC1

Current DSA invocationID: 9b8a7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d

No retired signatures.

Журналы

События, по которым узнают проблему до того, как её сформулирует пользователь. Тексты ниже сверены с таблицами сообщений самой Windows Server 2025 (ntdsmsg.dll, netmsg.dll, dfsrress.dll) и с манифестами журналов.

Directory Service:

Id Что
1864 сводка по разделу: со сколькими контроллерами этот не реплицировался больше суток, недели, месяца, двух месяцев и срока tombstone
2042 с источником не было репликации дольше срока tombstone, репликация с ним остановлена (в repadmin — ошибка 8614)
1988 в строгом режиме: партнёр прислал изменение объекта, удалённого здесь и уже вычищенного, — lingering object, репликация раздела с этим источником заблокирована; 1388 — то же в нестрогом режиме, объект принят
2095 контроллер обнаружил USN rollback: партнёр уже видел изменения с такими USN
2103 база восстановлена неподдерживаемым способом, Netlogon приостановлен
1311, 1865, 1308 KCC: не строится связная топология; список недостижимых сайтов; многократные неудачи с партнёром, KCC строит временное соединение в обход
2087, 2088 не удалось разрешить по DNS имя контроллера-источника: 2087 — репликация не прошла, 2088 — прошла через NetBIOS или полное имя, но DNS неисправен
1925, 1232 не удалось установить связь репликации с источником; RPC-вызов к партнёру не дождался ответа и отменён
1084 не удалось применить к объекту полученные изменения (с GUID объекта и источником), репликация с источником остановлена до исправления
2091, 2092 роль FSMO: владелец удалён или роль не подтверждена (часть 17)
1644 дорогой LDAP-запрос (только с включённой диагностикой)
2886, 2887, 2889 небезопасные LDAP-привязки: 2886 и 2887 — сводки раз в сутки, 2889 — по каждому клиенту, только с диагностикой «16 LDAP Interface Events» = 2 (часть 5)
2089 раздел давно не попадал в резервную копию; пишется раз в сутки, пока копии нет (тема части 20)

DNS Server (часть 7): 4013 — сервер ждёт, пока каталог сообщит о завершении начальной синхронизации (обычное дело после перезагрузки контроллера, плохо — если долго), 4015 — критическая ошибка каталога, 4000 — не удалось открыть каталог, зона не загружена, 7062 — сервер получил пакет, адресованный самому себе (пересылка на себя).

DFS Replication: 2213 — после некорректного завершения база DFSR не закрыта чисто, автоматическое восстановление выключено, репликация тома остановлена до вызова метода ResumeReplication (команда — в тексте события); 2212 — обнаружено неожиданное завершение, служба восстанавливается сама, 2214 — восстановилась; 2202 — переполнение журнала изменений NTFS (USN journal wrap); 4012 — папка не реплицировалась дольше MaxOfflineTimeInDays (60 дней), данные считаются устаревшими, репликация остановлена; 4614, 4604 и 4602 — инициализация SYSVOL (часть 10); 5002 и 5014 — ошибка связи с партнёром, служба повторит попытку (их пара после каждой перезагрузки соседа — норма).

System на контроллере и членах домена:

Id Источник Что
5719 NETLOGON не удалось установить защищённый сеанс с контроллером домена; на члене домена — DNS или сеть, на контроллере сразу после загрузки — порядок старта служб, безвреден, если один
3210 NETLOGON (на члене домена) компьютер не смог аутентифицироваться на контроллере: пароль учётной записи компьютера не принят или в сети есть машина с тем же именем
5805, 5722 NETLOGON (на контроллере) настройка сеанса от компьютера с указанным именем не прошла аутентификацию; 5722 называет ещё и учётную запись
5774, 5781 NETLOGON не удалось зарегистрировать DNS-записи контроллера: сервер отказал (с кодом ответа) или недоступен
5807 NETLOGON за последние часы были клиенты из подсетей, не привязанных ни к одному сайту; имена и адреса — в netlogon.log
4 Security-Kerberos KRB_AP_ERR_MODIFIED: сервер не смог расшифровать билет — SPN зарегистрирован не на той учётной записи (часть 6)
40960, 40961 LsaSrv ошибка аутентификации на сервере с кодом протокола; не удалось установить защищённое соединение — нет подходящего протокола
1054, 1058, 1030 GroupPolicy политики не применены: не найдено имя контроллера; не прочитан файл политики из SYSVOL; не получены настройки
129, 50, 36 Time-Service не найден доменный источник времени; расхождение времени больше порога, служба перестала считаться синхронизированной; время давно не синхронизировалось (часть 12)

Security на контроллере: 4740 — учётная запись заблокирована, с именем компьютера, откуда пришли неверные пароли (Caller Computer Name); 4771 — не прошла предварительная аутентификация Kerberos, с адресом клиента; 4776 — проверка учётных данных по NTLM. 4740 пишется по умолчанию (аудит User Account Management, успех), а 4771 и 4776 с отказами — только если в политике аудита включены отказы в подкатегориях Kerberos Authentication Service и Credential Validation: Windows Server по умолчанию их не пишет, базовые рекомендации Microsoft для контроллеров их включают. Журнал Security на загруженном контроллере перезаписывается за сутки-двое, поэтому искать источник блокировки нужно сразу.


nltest и netlogon.log

nltest — утилита Netlogon, и она отвечает на вопросы, на которые не отвечает ничто другое:

PS C:\> nltest /sc_query:corp.example.com
Flags: 30 HAS_IP  HAS_TIMESERV  Authentication Service: Netlogon
Trusted DC Name \\dc1.corp.example.com
Trusted DC Connection Status Status = 0 0x0 NERR_Success
The command completed successfully

/sc_query — с каким контроллером у машины защищённый канал и в каком он состоянии; это единственный ключ из трёх, который ничего не меняет. /sc_verify:corp.example.com проверяет канал заново и, если он не работает, по документации удаляет его и строит новый; /sc_reset:corp.example.com\dc2 пересоздаёт канал к конкретному контроллеру. То же в PowerShell — Test-ComputerSecureChannel; в PowerShell 7 его нет в собственном модуле Microsoft.PowerShell.Management, и он приходит через слой совместимости (модуль-заместитель версии 1.0):

PS C:\> Test-ComputerSecureChannel
True

Для члена домена с «trust relationship failed» это диагностика, а лечение — Test-ComputerSecureChannel -Repair из части 4. Ошибка репликации −2146893022 «The target principal name is incorrect» между контроллерами чаще всего значит, что у KDC, выдавшего приёмнику билет, старая версия пароля учётной записи источника. Microsoft советует сначала временно отключить KDC на приёмнике и перезагрузить его, чтобы билет выдал другой контроллер, а если не помогло — netdom resetpwd /server:<контроллер, на котором сменить пароль> /userd:CORP\alice.admin /passwordd:* на консоли того контроллера, которому нужен новый пароль.

nltest /dsgetdc и /dclist — из части 3. На самом контроллере есть ещё nltest /dsquerydns — результат последней регистрации его DNS-записей:

PS C:\> Invoke-Command dc1 { nltest /dsquerydns }
Flags: 0
Connection Status = 0 0x0 NERR_Success
There was no failure in the last update for all DC-specific DNS records
The command completed successfully

Какие записи контроллер должен зарегистрировать, Netlogon пишет в %SystemRoot%\System32\config\netlogon.dns. Сверить их с DNS — несколько строк PowerShell:

PS C:\> $lines = Invoke-Command dc1 { Get-Content C:\Windows\System32\config\netlogon.dns }
PS C:\> $lines | Where-Object { $_ -match ' SRV ' } | ForEach-Object {
    $f = $_ -split ' '
    $found = Resolve-DnsName $f[0] -Type SRV -DnsOnly -ErrorAction SilentlyContinue | Where-Object NameTarget -eq $f[7].TrimEnd('.')
    [pscustomobject]@{ Record = $f[0]; Port = $f[6]; InDns = [bool]$found }
} | Format-Table

Record                                                                           Port InDns
------                                                                           ---- -----
_ldap._tcp.corp.example.com.                                                     389   True
_ldap._tcp.Office._sites.corp.example.com.                                       389   True
_ldap._tcp.gc._msdcs.corp.example.com.                                           3268  True
_ldap._tcp.Office._sites.gc._msdcs.corp.example.com.                             3268  True
_ldap._tcp.7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f.domains._msdcs.corp.example.com. 389   True
_kerberos._tcp.dc._msdcs.corp.example.com.                                       88    True
_kerberos._tcp.Office._sites.dc._msdcs.corp.example.com.                         88    True
_ldap._tcp.dc._msdcs.corp.example.com.                                           389   True
_ldap._tcp.Office._sites.dc._msdcs.corp.example.com.                             389   True
_kerberos._tcp.corp.example.com.                                                 88    True
_kerberos._tcp.Office._sites.corp.example.com.                                   88    True
_gc._tcp.corp.example.com.                                                       3268  True
_gc._tcp.Office._sites.corp.example.com.                                         3268  True
_kerberos._udp.corp.example.com.                                                 88    True
_kpasswd._tcp.corp.example.com.                                                  464   True
_kpasswd._udp.corp.example.com.                                                  464   True
_ldap._tcp.DomainDnsZones.corp.example.com.                                      389   True
_ldap._tcp.ForestDnsZones.corp.example.com.                                      389   True
_ldap._tcp.Office._sites.DomainDnsZones.corp.example.com.                        389   True
_ldap._tcp.Office._sites.ForestDnsZones.corp.example.com.                        389   True
_ldap._tcp.pdc._msdcs.corp.example.com.                                          389   True

Двадцать одна SRV-запись у контроллера, который одновременно GC и PDC (у остальных нет записи pdc, а у контроллера без GC — записей gc и _gc), плюс A и AAAA для имени домена, gc._msdcs, DomainDnsZones и ForestDnsZones и CNAME <GUID>._msdcs, о котором ниже. Строка с False — запись, которую Netlogon не смог зарегистрировать; ищем рядом событие 5774 или 5781. Перерегистрацию запускает nltest /dsregdns на контроллере (часть 4), иначе Netlogon повторяет её сам раз в час.

Когда Locator находит не тот контроллер, или не находит, или клиент оказывается не в том сайте, нужен журнал Netlogon — %windir%\debug\netlogon.log. На контроллере он ведётся и без отладки, и в нём оседают клиенты из подсетей без сайта — те самые, о которых сводкой сообщает событие 5807:

PS C:\> Invoke-Command dc1 { Get-Content C:\Windows\debug\netlogon.log -Tail 3 }
10/28 12:13:24 [3188] CORP: NO_CLIENT_SITE: LAPTOP-7 192.168.9.44
10/28 13:53:25 [3188] CORP: NO_CLIENT_SITE: LAPTOP-7 192.168.9.44
10/28 15:52:26 [3288] CORP: NO_CLIENT_SITE: LAPTOP-7 192.168.9.44

Дата, время, номер потока, домен, имя клиента и его адрес: подсеть 192.168.9.0/24 не привязана ни к одному сайту, и этот клиент может получить контроллер на другом конце страны. Лечится объектом подсети в CN=Subnets (часть 10).

Подробный журнал Locator на клиенте включает nltest /dbflag:0x2080ffff; с Windows Server 2012 R2 и Windows 10 перезапускать Netlogon обычно не нужно, достаточно убедиться, что в журнал пошли новые строки. В нём видны поиски контроллера и запросы к DNS, которые Netlogon делал по пути. Журнал растёт до 20 МБ, затем переименовывается в netlogon.bak и начинается заново; выключается он nltest /dbflag:0x0.


Типичные причины

Шесть состояний, в которые попадает домен чаще всего, с признаками в том порядке, в котором они обнаруживаются.

DNS. repadmin — 8524 «The DSA operation is unable to proceed because of a DNS lookup failure»; Directory Service — 2087, 2088; dcdiag — падает Connectivity. Приёмник ищет источник не по имени, а по CNAME <objectGUID NTDS Settings>._msdcs.<корень леса>, поэтому проверять надо именно его — на больном контроллере, тем же DNS-сервером, которым пользуется он:

PS C:\> $guid = (Get-ADObject (Get-ADDomainController dc1).NTDSSettingsObjectDN).ObjectGUID
PS C:\> Resolve-DnsName "$guid._msdcs.corp.example.com" -Type CNAME

Name                                                         Type  TTL Section NameHost
----                                                         ----  --- ------- --------
2f3e4d5c-6b7a-4899-8a7b-6c5d4e3f2a1b._msdcs.corp.example.com CNAME 600 Answer  dc1.corp.example.com

Затем A-запись dc1, DNS-клиент контроллера (порядок серверов из части 10), проверка netlogon.dns выше и dcdiag /test:dns с подтестами. Самая частая причина из всех.

Время. Клиенты — ошибки входа у всех разом в одном сайте; repadmin — 8453 или −2146893022; System — 40960 с кодом Kerberos; dcdiag /test:CheckSecurityError /ReplSource:… называет расхождение словами. Проверить w32tm /monitor; поправить w32tm /resync /force и найти, откуда взялось: снимок виртуальной машины, батарейка на материнской плате, PDC без внешнего источника (часть 12).

Защищённый канал. На члене домена — «trust relationship failed», System 5719 и 3210; на контроллере — 5805 и 5722 с именем машины. Причина почти всегда — откат виртуальной машины к снимку или восстановление из образа, сделанного до очередной смены пароля учётной записи компьютера (машина меняет его сама, по умолчанию раз в 30 дней): машина знает старый пароль. Test-ComputerSecureChannel -Repair.

RPC и файрвол. repadmin — 1722 «The RPC server is unavailable» или 1753 «There are no more endpoints available from the endpoint mapper»; dcdiag — падают Replications и Connectivity при живом DNS. Проверить порт сопоставителя конечных точек:

PS C:\> Test-NetConnection dc2 -Port 135 -InformationLevel Quiet
True

Затем динамические порты: portqry -n dc2 -e 135 (утилита PortQry скачивается у Microsoft отдельно) перечисляет интерфейсы RPC и порты, на которых они слушают; между сайтами порты репликации фиксируют и открывают, часть 10. Ошибка 1753 приходит и тогда, когда имя разрешилось в адрес машины, которая не контроллер.

SYSVOL. Политики применяются на одних машинах и не применяются на других; GPMC показывает разные версии в каталоге и в SYSVOL; на членах домена — GroupPolicy 1058; на контроллере — DFS Replication 2213 или 4012; dcdiag — падают SysVolCheck и Advertising, контроллер не объявляет себя клиентам. Состояние реплицируемой папки SYSVOL на всех контроллерах — одна строка WMI на каждом:

PS C:\> $dcs = (Get-ADDomainController -Filter *).HostName
PS C:\> Invoke-Command $dcs {
    Get-CimInstance -Namespace root\microsoftdfs -ClassName DfsrReplicatedFolderInfo -Filter "ReplicatedFolderName='SYSVOL Share'"
} | Sort-Object PSComputerName | Format-Table PSComputerName, ReplicatedFolderName, State

PSComputerName       ReplicatedFolderName State
--------------       -------------------- -----
dc1.corp.example.com SYSVOL Share             4
dc2.corp.example.com SYSVOL Share             4
dc3.corp.example.com SYSVOL Share             4
dc4.corp.example.com SYSVOL Share             4

State: 0 — не инициализирована, 1 — инициализирована, 2 — начальная синхронизация, 3 — автоматическое восстановление, 4 — норма, 5 — ошибка. Отставание между парой контроллеров:

PS C:\> dfsrdiag backlog /rgname:"Domain System Volume" /rfname:"SYSVOL Share" /smem:dc1 /rmem:dc2

No Backlog - member <dc2> is in sync with partner <dc1>

Operation Succeeded

То же даёт командлет Get-DfsrBacklog (модуль DFSR в PowerShell 7 загружается через слой совместимости, без отставания он не выводит ничего). После 2213 — ResumeReplication командой из события, удалять базу DFSR не нужно; после 4012 или расхождения содержимого — неавторитетная синхронизация SYSVOL, тема части 20.

Блокировки. Пользователь блокируется каждые пять минут, хотя пароль не вводит. Источник — там, где остался старый пароль: сохранённое подключение к сетевому диску, задача планировщика, служба, телефон с почтой, RDP-сеанс, оставленный неделю назад. Неверный пароль контроллер перепроверяет на PDC-эмуляторе, блокировки сходятся туда же (часть 17), поэтому искать 4740 проще всего на нём:

PS C:\> Invoke-Command (Get-ADDomain).PDCEmulator {
    Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4740; StartTime=(Get-Date).AddDays(-1)} -ErrorAction SilentlyContinue |
        Select-Object TimeCreated, @{n='User'; e={$_.Properties[0].Value}}, @{n='From'; e={$_.Properties[1].Value}}
} | Format-Table TimeCreated, User, From

В домене без блокировок команда ничего не выводит. Если блокировки есть, в колонке User — заблокированная учётная запись (поле Account Name), в From — Caller Computer Name, машина, с которой приходят неверные пароли; на ней Get-ScheduledTask | Where-Object { $_.Principal.UserId -like '*carol*' }, Get-CimInstance Win32_Service -Filter "StartName like '%carol%'", cmdkey /list и query session. Если From пуст — попытки шли через сервер, который не передал имя клиента (веб, VPN, почта), и тогда нужны события 4771 на всех контроллерах с адресом в поле Client Address (Properties[6]) — при включённом аудите отказов, см. выше.


Lingering objects

Объект удалён, стал tombstone, прожил срок (tombstoneLifetime, 180 дней) и был вычищен со всех контроллеров. Кроме одного: dc3 был выключен весь этот срок и до сих пор хранит объект живым — он не получил даже уведомления об удалении. Такой объект называется lingering. Когда dc3 возвращается и объект на нём меняется, партнёр получает изменение объекта, которого у него нет. Что он сделает, решает параметр Strict Replication Consistency в HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Parameters у приёмника. По документации он равен 1 у контроллеров, поставленных в новый лес; в лесах, обновлённых с Windows 2000, новые контроллеры получают 0, пока в конфигурацию леса не добавлен специальный объект CN=94fdebc6-8eeb-4640-80de-ec52b9ca17fa,CN=Operations,CN=ForestUpdates,….

  • строгий режим (1): приёмник отказывается принять изменение, пишет событие 1988 с именем объекта, его GUID и адресом источника вида <GUID>._msdcs.<лес>, и репликация этого раздела с этого источника блокируется (ошибка 8606 «Insufficient attributes were given to create an object»);
  • нестрогий (0): приёмник запрашивает объект целиком и создаёт его заново (событие 1388), и удалённый пользователь воскресает во всём лесу — с SID, членством в группах и паролем полугодовой давности.

Первый исход правильный, и событие 1988 — инструкция: в нём есть всё для удаления. Удаляет repadmin /removelingeringobjects: ему указывают контроллер, который нужно почистить, GUID объекта NTDS Settings эталонного контроллера с записываемой копией раздела и раздел. Сначала в режиме отчёта:

repadmin /removelingeringobjects dc3.corp.example.com 2f3e4d5c-6b7a-4899-8a7b-6c5d4e3f2a1b DC=corp,DC=example,DC=com /advisory_mode

Результат — в журнале Directory Service dc3: 1938 в начале проверки, 1946 на каждый найденный объект и 1942 со сводкой. Убедившись, что список ожидаем, — та же команда без /advisory_mode: тогда события 1937, 1945 на каждый удалённый объект и 1939. Повторить для каждого раздела (конфигурация, схема, DNS-разделы) и для каждого контроллера, на котором lingering могут быть, включая глобальные каталоги. Microsoft предпочитает для этого утилиту Lingering Object Liquidator v2, которая проходит по всем парам сразу; после события 1388 (объект уже принят) ни она, ни repadmin его не уберут — нужна другая процедура из той же документации.

Режим на всех контроллерах сразу:

PS C:\> Invoke-Command $dcs {
    Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters' | Select-Object 'Strict Replication Consistency'
} | Sort-Object PSComputerName | Format-Table PSComputerName, 'Strict Replication Consistency'

PSComputerName       Strict Replication Consistency
--------------       ------------------------------
dc1.corp.example.com                              1
dc2.corp.example.com                              1
dc3.corp.example.com                              1
dc4.corp.example.com                              1

Где значение 0 или пусто, его включают repadmin /regkey <контроллер> +strict.


USN rollback

Каталог контроллера dc2 вернули из снимка виртуальной машины недельной давности. Его USN откатился: вчера highestCommittedUSN был 13 400, сегодня снова 12 900. Партнёры помнят в векторе актуальности, что от dc2 с этим invocationID они видели всё до 13 400. Теперь dc2 создаёт новые объекты с USN 12 901, 12 902 — и при запросе «дай всё после 13 400» не отдаёт их никогда. Пользователи, созданные на dc2 после отката, существуют только на нём; пароли, сменённые через него, работают только у него. Это USN rollback, и его главная опасность — он тихий: репликация формально успешна, ошибок нет, а каталог разъехался.

Контроллер умеет его обнаруживать. Когда партнёр запрашивает изменения и по его вектору видно, что он уже получил от этого контроллера USN, которые тот выдаёт заново, при том же invocationID, контроллер пишет 2095 в Directory Service, приостанавливает Netlogon, чтобы на нём больше не создавались изменения, которые никуда не уйдут, и ставит в реестре Dsa Not Writable = 4 — карантин, который документация запрещает снимать вручную. Событие 2103 — «The Active Directory Domain Services database has been restored using an unsupported restoration procedure» и приостановленный Netlogon. Сами события могут перезаписаться, а значение реестра остаётся. Выходов три: понизить контроллер принудительно, очистить метаданные и повысить заново (часть 19), восстановить состояние системы из корректной резервной копии, при котором каталог сам меняет invocationID (часть 20), или заставить каталог взять новый invocationID по процедуре для снимков без резервной копии.

Почему восстановление из резервной копии не вызывает rollback: при нём каталог получает новый invocationID, и для партнёров это новый источник — вектор актуальности для старого invocationID остаётся, для нового создаётся, и всё, что новый источник выдаст, будет запрошено. Откат снимка invocationID не меняет, в этом вся разница.

С Windows Server 2012 есть защита — VM-GenerationID: гипервизор, который его поддерживает (Hyper-V с Windows Server 2012 и другие), меняет этот идентификатор в виртуальной машине при применении снимка и при импорте её копии. Контроллер хранит своё значение в атрибуте msDS-GenerationId своей учётной записи и сверяет его с текущим при загрузке и перед фиксацией каждого изменения. Не совпало — новый invocationID, отказ от текущего пула RID, затем неавторитетная докачка изменений и неавторитетная синхронизация SYSVOL; в журнале — событие 2170 «A Generation ID change has been detected». Такой откат безопасен для каталога и SYSVOL, но не для всего остального: файлы, базы приложений и настройки на самом сервере, всё, что не приходит обратно репликацией, всё равно прыгнут в прошлое. Снимки контроллеров остаются способом вернуть машину после неудачного обновления в течение часа, а не способом резервного копирования.


Контроллер, пропустивший полгода

Третий сценарий связан с первыми двумя. dc3 в филиале не реплицировался 200 дней: канал лежал, никто не смотрел. Всё это время событие 1864 на остальных контроллерах показывало растущее число «не реплицировался больше месяца», «больше двух месяцев», а когда прошли 180 дней — «больше срока tombstone». Когда dc3 возвращается, репликация между ним и партнёрами останавливается с событием 2042 «It has been too long since this machine last replicated with the named source machine» и ошибкой 8614 в repadmin. Блокировка защищает от lingering objects, которых у dc3 теперь почти наверняка много.

Правильный выход один: dc3 не возвращать. Понизить принудительно, вычистить метаданные, переустановить и повысить заново — всё это в следующей части. Документированный обходной путь — найти и вычистить lingering objects (Lingering Object Liquidator или repadmin /removelingeringobjects по всем разделам), временно поставить на приёмнике Allow Replication With Divergent and Corrupt Partner = 1 (repadmin /regkey <контроллер> +allowDivergent), дать репликации пройти и вернуть параметр (-allowDivergent). Он существует для случаев, когда переустановка невозможна, и занимает больше времени, чем переустановка.

Срок tombstone, от которого всё это отсчитывается:

PS C:\> (Get-ADObject 'CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,DC=corp,DC=example,DC=com' -Properties tombstoneLifetime).tombstoneLifetime
180

Пустое значение здесь означает 60 дней: 180 выставляется при создании леса начиная с Windows Server 2003 SP1, а в лесах, созданных раньше и не исправленных вручную, атрибут пуст. Им стоит явно выставить 180. С включённой корзиной AD к нему добавляется msDS-DeletedObjectLifetime — срок, в течение которого удалённый объект ещё можно восстановить целиком (тема части 20).


Смотрим руками

Вся диагностика леса в одном скрипте, который имеет смысл запускать по расписанию:

$dcs = (Get-ADDomainController -Filter *).HostName
$report = [ordered]@{}
$report.dcdiag = dcdiag /s:$((Get-ADDomain).PDCEmulator) /e /q /skip:SystemLog /skip:DFSREvent /skip:KccEvent 2>&1 | Out-String
$report.repl   = repadmin /showrepl * /csv | ConvertFrom-Csv | Where-Object 'Number of Failures' -gt 0 | Out-String
$report.time   = w32tm /monitor 2>&1 | Select-String 'offset' | Out-String
$report.events = Invoke-Command $dcs {
    Get-WinEvent -FilterHashtable @{LogName='Directory Service','DNS Server','DFS Replication'; Level=1,2,3; StartTime=(Get-Date).AddDays(-1)} -ErrorAction SilentlyContinue |
        Select-Object LogName, Id
} | Group-Object PSComputerName, LogName, Id | Select-Object Count, Name | Out-String
$report.sysvol = Invoke-Command $dcs {
    Get-CimInstance -Namespace root\microsoftdfs -ClassName DfsrReplicatedFolderInfo -Filter "ReplicatedFolderName='SYSVOL Share'"
} | Select-Object PSComputerName, State | Out-String
$report | Format-List

Журналы читаются на самих контроллерах через Invoke-Command, а не Get-WinEvent -ComputerName: тот ходит по тому же RPC, что и тесты dcdiag, и упирается в тот же файрвол. Отчёт в нашем лесу:

Name  : dcdiag
Value :             Invalid service type: DnsCache on DC3, current value

                    WIN32_SHARE_PROCESS, expected value WIN32_OWN_PROCESS

                 ......................... DC3 failed test Services



Name  : repl
Value :

Name  : time
Value :
            NTP: -0.0002433s offset from dc1.corp.example.com
            NTP: +0.0000000s offset from dc1.corp.example.com
            NTP: -0.0008230s offset from dc1.corp.example.com
            NTP: -0.0007763s offset from dc1.corp.example.com



Name  : events
Value :
        Count Name
        ----- ----
            2 dc1.corp.example.com, Directory Service, 3079
            5 dc2.corp.example.com, Directory Service, 2089
            1 dc3.corp.example.com, Directory Service, 3041
            5 dc4.corp.example.com, Directory Service, 2089
            3 dc4.corp.example.com, Directory Service, 3079



Name  : sysvol
Value :
        PSComputerName       State
        --------------       -----
        dc3.corp.example.com     4
        dc1.corp.example.com     4
        dc2.corp.example.com     4
        dc4.corp.example.com     4

Так выглядит здоровый лес: в dcdiag только известный ложный провал теста Services на контроллере 2019, repl пуст, смещения времени — доли миллисекунды (по строке на контроллер, каждое — относительно PDC dc1, у самого dc1 ноль), SYSVOL везде в состоянии 4. В журналах — предупреждения, а не ошибки: 2089 на dc2 и dc4 — разделы давно не попадали в резервную копию (по одному событию на каждый из пяти разделов), 3079 — контроллер Windows Server 2025 не отдал конфиденциальные атрибуты клиенту, читавшему их по LDAP без шифрования, 3041 — совет требовать привязку каналов (channel binding) для LDAPS. Ничего из этого не ломает домен сейчас, но первое — прямой повод для части 20.

Как выглядит lingering object до того, как его нашли: на одном контроллере объект есть, на другом его нет вовсе — ни живого, ни tombstone. repadmin /showobjmeta с GUID объекта отвечает на втором так:

PS C:\> repadmin /showobjmeta dc1 "<GUID=5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a>"
DsReplicaGetInfo() failed with status 8439 (0x20f7):
    The distinguished name specified for this replication operation is invalid.

С DN вместо GUID ответ другой — «failed with status 8333 (0x208d): Directory object not found.». А на контроллере, где объект жив, та же команда покажет обычные метаданные его атрибутов. Объект, который есть на одном контроллере и которого на другом нет даже в виде tombstone, — это и есть определение lingering object.

USN rollback до того, как его обнаружил контроллер, — собственный USN контроллера рядом с тем, что о нём помнит партнёр:

PS C:\> (Get-ADRootDSE -Server dc2).highestCommittedUSN
53424732
PS C:\> (Get-ADReplicationUpToDatenessVectorTable -Target dc1 -Partition 'DC=corp,DC=example,DC=com' | Where-Object Partner -like '*CN=DC2,*').UsnFilter
53424720

Партнёр помнит dc2 на USN не выше, чем dc2 выдал сам: всё в порядке (разница — изменения последних секунд, ещё не дошедшие до dc1). Если UsnFilter у партнёра больше highestCommittedUSN самого контроллера, dc2 в прошлом, и при следующем запросе изменений он напишет 2095. Фильтр по CN=DC2, нужен потому, что в векторе остаются и прежние invocationID того же контроллера, у них Partner пуст. Если контроллер уже обнаружил откат — в реестре:

PS C:\> Invoke-Command dc2 { Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters' -Name 'Dsa Not Writable' -ErrorAction SilentlyContinue }

У здорового контроллера значения нет, и команда ничего не выводит; 4 — «восстановлен неподдерживаемым способом», и дальше — следующая часть.

И защита от отката. msDS-GenerationId не реплицируется, поэтому читать его нужно с самого контроллера — так же, как rIDNextRID в части 17:

PS C:\> (Get-ADComputer dc1 -Server dc1 -Properties 'msDS-GenerationId').'msDS-GenerationId'.Length
8
PS C:\> (Get-ADComputer dc1 -Server dc2 -Properties 'msDS-GenerationId').'msDS-GenerationId'.Length
0

При каждой загрузке виртуальный контроллер отмечает в журнале, что сверил идентификатор:

PS C:\> Invoke-Command dc1 { Get-WinEvent -FilterHashtable @{LogName='Directory Service'; Id=2168} -MaxEvents 2; Get-WinEvent -FilterHashtable @{LogName='Directory Service'; Id=2172} -MaxEvents 2 } |
    Sort-Object TimeCreated | Format-Table TimeCreated, Id, @{n='Message'; e={($_.Message -split "`r?`n")[0]}}

TimeCreated           Id Message
-----------           -- -------
19.10.2026 0:29:06  2168 The DC is running on a supported hypervisor. VM Generation ID is detected.
19.10.2026 0:29:06  2172 Read the msDS-GenerationId attribute of the Domain Controller's computer object.
26.10.2026 13:40:52 2168 The DC is running on a supported hypervisor. VM Generation ID is detected.
26.10.2026 13:40:52 2172 Read the msDS-GenerationId attribute of the Domain Controller's computer object.

2168 — гипервизор отдаёт VM-GenerationID, 2172 — прочитано сохранённое значение; после отката к снимку вместо обычной пары появилось бы 2170.


Источники


Теперь у нас есть порядок проверки, мы умеем отличать настоящий провал dcdiag от ложного и знаем три состояния каталога, после которых контроллер не чинят, а заменяют. Как это делается, — следующая часть.

Дальше — часть 19: замена и вывод контроллеров. Штатное понижение через Uninstall-ADDSDomainController и принудительное, когда контроллер уже мёртв; очистка метаданных — что остаётся в каталоге и DNS от исчезнувшего контроллера и как это убрать; перенос DHCP и настроек DNS-клиентов; повышение функционального уровня леса и домена; и почему новая версия Windows Server на контроллере — это всегда новый контроллер, а не обновление старого.

Оставить комментарий могут только зарегистрированные пользователи.

Войдите на сайт или зарегистрируйтесь, чтобы оставить комментарий.