Windows Server для самых маленьких. Часть 20: Как делать резервные копии Active Directory и восстанавливать его?
Все части серии «Windows Server для самых маленьких»У каталога с четырьмя контроллерами есть встроенная защита от потери одного из них: остальные хранят всё то же самое, и в прошлой части мы видели, что умерший контроллер проще заменить, чем восстанавливать. Но репликация защищает от потери контроллера, а не от потери данных. OU с пятьюстами пользователями, удалённая по ошибке, через несколько секунд удалена на всех контроллерах сайта, а с ближайшей репликацией между сайтами — везде; схема, расширенная не тем файлом, расширена во всём лесу; шифровальщик, добравшийся до учётной записи администратора домена, добирается до каждого контроллера. От этого защищает только копия, лежащая вне каталога, и умение из неё восстановить ровно то, что нужно.
Команды ниже выполняются с рабочей станции администратора ws1 в PowerShell 7 (часть 15); то, что должно работать на самом контроллере (wbadmin, ntdsutil, журналы, реестр), идёт через Invoke-Command (часть 14) или в консоли контроллера, когда он загружен в режим восстановления. Домен — corp.example.com с четырьмя контроллерами: dc1 и dc2 в сайте Office, dc3 и dc4 в сайте Branch, dc1 — PDC.
Что копировать
Для Windows резервная копия контроллера — это состояние системы (System State): загрузочные файлы, реестр вместе с регистрацией COM+, SYSVOL, база каталога ntds.dit с журналами транзакций (C:\Windows\NTDS), а если на сервере есть удостоверяющий центр, IIS или кластер — их база, метабаза и конфигурация. Зоны DNS, интегрированные в AD, лежат в базе каталога и попадают в копию вместе с ней; файловые зоны (System32\dns\*.dns) в состояние системы не входят, их копируют вместе с томом.
Копируется база не как файлы. Windows делает снимок тома через службу теневого копирования VSS (Volume Shadow Copy Service): приложения, у которых есть свой VSS writer, на мгновение приостанавливают запись и приводят данные в согласованное состояние, снимок фиксируется, и копия читается уже из него. У службы каталога такой writer есть (NTDS): он отдаёт базу и журналы согласованными, а после успешной копии записывает отметку о ней в каталог. Копия файла ntds.dit, снятая без VSS, — Copy-Item с работающего контроллера, копия файла виртуального диска на лету, — это база в середине транзакции, и восстанавливать из неё нельзя.
Отметка о копии — атрибут dSASignature на корне каждого раздела. Он реплицируется, поэтому с любого контроллера видно, когда и каким контроллером раздел копировался последний раз: это показывает repadmin /showbackup (вывод — в конце части). Раз в сутки каждый контроллер сверяет возраст этой отметки с порогом и, если раздел не копировался дольше, пишет в журнал Directory Service предупреждение 2089 — по одному на каждый такой раздел, каждый день, пока копию не сделают. Порог — параметр реестра Backup Latency Threshold (days) в HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Parameters, по умолчанию — половина срока tombstone, то есть 90 дней при 180. Справка repadmin /?:showbackup советует в рабочей среде ставить 1 день, статья Microsoft о событии — получать его через день без копии. Параметр задаётся на каждом контроллере отдельно, и у него есть обратная сторона: большое значение просто глушит предупреждение, и это единственный способ, которым каталог мог напомнить, что копии нет.
Что и как часто:
| Что | Чем | Как часто |
|---|---|---|
| Состояние системы минимум двух контроллеров, в том числе по одному в каждом домене | Windows Server Backup или продукт с поддержкой VSS writer NTDS | ежедневно; хранить дольше, чем между проверками, но короче срока tombstone: копия старше 180 дней не восстанавливается |
| База DHCP | Backup-DhcpServer или Export-DhcpServer (часть 8) |
ежедневно в другое место; сам сервер раз в 60 минут кладёт копию в System32\dhcp\backup, но на тот же диск |
| Групповые политики | Backup-GPO -All -Path |
после каждого изменения; тема части 24 |
| Удостоверяющий центр: база, ключ, шаблоны | Backup-CARoleService |
после каждого изменения; часть 25 |
| Файловые зоны DNS, если есть | копия тома или файлов System32\dns\*.dns |
вместе с состоянием системы |
| Пароль DSRM каждого контроллера и пароли аварийных учётных записей | менеджер паролей вне домена | при каждом изменении |
Последняя строка важнее всех: восстановление начинается с входа в режим восстановления по паролю DSRM из части 4, и если пароль лежит в менеджере паролей, который аутентифицируется через этот же домен, восстанавливать будет некому.
И одно правило про хранение: копия должна лежать там, куда не дотянется администратор домена. Шифровальщик работает с его правами, и копия на сетевой папке, доступной Domain Admins, будет зашифрована вместе с контроллерами. Отдельная учётная запись для резервного копирования, хранилище с неизменяемыми снимками или просто отключаемый диск — любой из вариантов лучше общей папки.
Windows Server Backup
Встроенный инструмент — компонент Windows-Server-Backup: служба, консоль, утилита wbadmin и модуль WindowsServerBackup. По умолчанию он не установлен, и пока его нет, на сервере нет и самой wbadmin:
PS C:\> $dcs = (Get-ADDomainController -Filter *).HostName
PS C:\> Invoke-Command $dcs { Get-WindowsFeature Windows-Server-Backup } | Sort-Object PSComputerName | Format-Table PSComputerName, Name, InstallState
PSComputerName Name InstallState
-------------- ---- ------------
dc1.corp.example.com Windows-Server-Backup Available
dc2.corp.example.com Windows-Server-Backup Available
dc3.corp.example.com Windows-Server-Backup Available
dc4.corp.example.com Windows-Server-Backup Available
Available — компонент доступен, но не установлен. Ставим на dc2 и делаем разовую копию состояния системы на отдельный диск E::
PS C:\> Invoke-Command dc2 { Install-WindowsFeature Windows-Server-Backup }
PS C:\> Invoke-Command dc2 { wbadmin start systemstatebackup -backupTarget:E: -quiet }
wbadmin создаёт теневую копию томов, на которых лежат файлы состояния системы, и пишет копию в E:\WindowsImageBackup\<имя компьютера>\; -quiet убирает вопрос «продолжить?». Целевой том по умолчанию не может быть **критическим** — томом, на котором лежит хоть один файл из состояния системы (обычно C:); разрешить это можно параметром реестра AllowSSBToAnyVolume в ключе HKLM\SYSTEM\CurrentControlSet\Services\wbengine\SystemStateBackup, но копия на том же диске, что и база, переживёт только логическую ошибку, а не потерю диска. Вместо тома можно указать сетевую папку (-backupTarget:\\server\share), но версий там Windows Server Backup не держит: следующая копия того же сервера в ту же папку перезаписывает предыдущую, и если она не удалась, не остаётся ни одной.
Расписание — через политику модуля:
PS C:\> Invoke-Command dc2 {
$policy = New-WBPolicy
Add-WBSystemState -Policy $policy
Add-WBBackupTarget -Policy $policy -Target (New-WBBackupTarget -VolumePath E:)
Set-WBSchedule -Policy $policy -Schedule 02:00
Set-WBPolicy -Policy $policy -Force
}
New-WBPolicy создаёт пустую политику, Add-WBSystemState добавляет в неё состояние системы, New-WBBackupTarget -VolumePath — том для копий, Set-WBSchedule — время ежедневного запуска (можно несколько через запятую), Set-WBPolicy делает политику действующей. Что получилось, показывают Get-WBSummary (последняя успешная копия и следующая по расписанию) и wbadmin get versions (список копий).
Add-WBBareMetalRecovery вместо Add-WBSystemState добавляет в политику всё, что нужно для восстановления сервера на пустое железо или в пустую виртуальную машину: системный том и загрузочные разделы целиком; из такой копии можно восстановить и состояние системы отдельно. Для единственного контроллера домена она обязательна; для контроллера, у которого есть партнёры, достаточно состояния системы, потому что сам сервер проще переустановить.
Коммерческие продукты делают то же самое через тот же VSS writer; при выборе важно одно слово в их описании — application-aware (или «с поддержкой VSS для Active Directory»). Копия виртуальной машины целиком без него — это та самая копия диска на лету: VSS writer NTDS о ней не знает, dSASignature не меняется, и 2089 продолжает приходить.
Корзина
Первый сценарий — удалённые объекты, и он закрывается без резервной копии, если корзина AD включена, как в части 5. Включение необратимо (IsDisableable у функции — False), и в EnabledScopes видно, что она действует на весь лес — на каждом контроллере и в объекте разделов:
PS C:\> (Get-ADOptionalFeature 'Recycle Bin Feature').EnabledScopes
CN=NTDS Settings,CN=DC4,CN=Servers,CN=Branch,CN=Sites,CN=Configuration,DC=corp,DC=example,DC=com
CN=NTDS Settings,CN=DC3,CN=Servers,CN=Branch,CN=Sites,CN=Configuration,DC=corp,DC=example,DC=com
CN=NTDS Settings,CN=DC1,CN=Servers,CN=Office,CN=Sites,CN=Configuration,DC=corp,DC=example,DC=com
CN=NTDS Settings,CN=DC2,CN=Servers,CN=Office,CN=Sites,CN=Configuration,DC=corp,DC=example,DC=com
CN=Partitions,CN=Configuration,DC=corp,DC=example,DC=com
Удалённый объект сохраняет все атрибуты, включая связи (членство в группах, manager), SID и пароль, на срок msDS-DeletedObjectLifetime. В лесу его обычно никто не задаёт, и тогда он равен сроку tombstone:
PS C:\> Get-ADObject "CN=Directory Service,CN=Windows NT,CN=Services,$((Get-ADRootDSE).configurationNamingContext)" -Properties tombstoneLifetime, 'msDS-DeletedObjectLifetime' | Format-List tombstoneLifetime, msDS-DeletedObjectLifetime
tombstoneLifetime : 180
msDS-DeletedObjectLifetime :
Сценарий: удалили OU Departments целиком, со всем содержимым — вложенными OU Sales и Branch, пользователями, группами и учётной записью gMSA. В контейнере Deleted Objects это выглядит так:
PS C:\> $t = Get-Date '2026-10-26 02:00'
PS C:\> Get-ADObject -SearchBase (Get-ADDomain).DeletedObjectsContainer -Filter 'whenChanged -ge $t' -IncludeDeletedObjects -Properties msDS-LastKnownRDN, lastKnownParent |
Format-Table ObjectClass, msDS-LastKnownRDN, @{n='Parent'; e={($_.lastKnownParent -split ',')[0]}}
ObjectClass msDS-LastKnownRDN Parent
----------- ----------------- ------
organizationalUnit Departments DC=corp
organizationalUnit Sales OU=Departments\0ADEL:7c1d5e2a-4b3f-4e8d-9a61-0f2b8c7d3e15
organizationalUnit Branch OU=Departments\0ADEL:7c1d5e2a-4b3f-4e8d-9a61-0f2b8c7d3e15
user Alice Smith OU=Sales\0ADEL:2e5a8f14-9c3b-4d7a-b6e0-5f1c3a9d8b27
user Bob Jones OU=Sales\0ADEL:2e5a8f14-9c3b-4d7a-b6e0-5f1c3a9d8b27
group sales OU=Departments\0ADEL:7c1d5e2a-4b3f-4e8d-9a61-0f2b8c7d3e15
group branch-admins OU=Departments\0ADEL:7c1d5e2a-4b3f-4e8d-9a61-0f2b8c7d3e15
user Carol White OU=Sales\0ADEL:2e5a8f14-9c3b-4d7a-b6e0-5f1c3a9d8b27
user Erin Brown OU=Branch\0ADEL:b83d2c6f-1e4a-4f9b-8c75-d2a6e0f4b913
container Printers OU=Branch\0ADEL:b83d2c6f-1e4a-4f9b-8c75-d2a6e0f4b913
msDS-GroupManagedServiceAccount web OU=Departments\0ADEL:7c1d5e2a-4b3f-4e8d-9a61-0f2b8c7d3e15
msDS-LastKnownRDN — прежнее имя объекта, lastKnownParent — где он лежал. Только у самой Departments родитель живой (DC=corp,…); у всех остальных lastKnownParent указывает на удалённого родителя, в Deleted Objects. Это не строка, записанная в момент удаления: lastKnownParent, как любой DN-атрибут, хранит ссылку на объект, и показывает его текущий DN. Пока родитель удалён, это DN с \0ADEL:<GUID>; как только родителя восстановят, у детей там окажется его живой DN.
Отсюда порядок восстановления — сверху вниз, потому что Restore-ADObject возвращает объект в lastKnownParent, и родитель к этому моменту должен существовать:
PS C:\> Get-ADObject -Filter 'msDS-LastKnownRDN -eq "Departments"' -IncludeDeletedObjects | Restore-ADObject
PS C:\> Get-ADObject -Filter 'lastKnownParent -eq "OU=Departments,DC=corp,DC=example,DC=com"' -IncludeDeletedObjects | Restore-ADObject
PS C:\> Get-ADObject -Filter 'lastKnownParent -eq "OU=Sales,OU=Departments,DC=corp,DC=example,DC=com"' -IncludeDeletedObjects | Restore-ADObject
PS C:\> Get-ADObject -Filter 'lastKnownParent -eq "OU=Branch,OU=Departments,DC=corp,DC=example,DC=com"' -IncludeDeletedObjects | Restore-ADObject
Каждая следующая строка ищет детей по живому DN только что восстановленного родителя. Restore-ADObject ничего не выводит (с -PassThru — восстановленный объект), а -TargetPath и -NewName возвращают объект в другое место или под другим именем.
Искать детей, пока родитель ещё удалён, через -Filter не получится: DN удалённого родителя содержит \0A, и фильтр модуля такой объект не находит. LDAP-фильтр находит, если обратную косую черту экранировать как \5C:
PS C:\> $ou = Get-ADObject -Filter 'msDS-LastKnownRDN -eq "Departments"' -IncludeDeletedObjects
PS C:\> Get-ADObject -Filter "lastKnownParent -eq '$($ou.DistinguishedName)'" -IncludeDeletedObjects | Measure-Object | Select-Object Count
Count
-----
0
PS C:\> Get-ADObject -LDAPFilter "(lastKnownParent=$($ou.DistinguishedName -replace '\\', '\5C'))" -IncludeDeletedObjects -Properties msDS-LastKnownRDN |
Format-Table ObjectClass, msDS-LastKnownRDN
ObjectClass msDS-LastKnownRDN
----------- -----------------
organizationalUnit Sales
organizationalUnit Branch
group sales
group branch-admins
msDS-GroupManagedServiceAccount web
Что корзина хранит у удалённого пользователя:
PS C:\> Get-ADObject -Filter 'msDS-LastKnownRDN -eq "Carol White"' -IncludeDeletedObjects -Properties * |
Format-List Name, isDeleted, isRecycled, lastKnownParent, objectSid, memberOf, sAMAccountName
Name : Carol White
DEL:9f8e7d6c-5b4a-4c3d-8e2f-1a0b9c8d7e6f
isDeleted : True
isRecycled :
lastKnownParent : OU=Sales\0ADEL:2e5a8f14-9c3b-4d7a-b6e0-5f1c3a9d8b27,CN=Deleted Objects,DC=corp,DC=example,DC=com
objectSid : S-1-5-21-3623811015-3361044348-30300820-1108
memberOf : {CN=sales\0ADEL:6a1f3e9d-2c8b-4b7e-a5d4-3e9f1c2b8a70,CN=Deleted Objects,DC=corp,DC=example,DC=com}
sAMAccountName : cwhite
SID на месте, членство — тоже: memberOf показывает группу sales, которая сама лежит в корзине, и после восстановления обоих связь оживёт. isRecycled пуст — объект ещё восстановим. Когда срок msDS-DeletedObjectLifetime выйдет, объект станет recycled: большинство атрибутов у него отнимут, как у tombstone в лесу без корзины, и корзиной он больше не восстанавливается — путь к нему остаётся только через копию.
Чего корзина не делает: не хранит объекты дольше этого срока; не восстанавливает атрибуты, изменённые у живого объекта (неправильно отредактированный member у группы — не удаление); и не помогает, если включили её после того, как удалили. Для этих случаев — резервная копия.
Неавторитетное восстановление
Второй сценарий — контроллер потерян или испорчен, партнёры живы. Восстановление состояния системы возвращает контроллер в состояние на момент копии, после чего он дореплицирует с партнёров всё, что изменилось с тех пор. Копия при этом считается менее актуальной, чем партнёры, — отсюда «неавторитетное». Каталог при таком восстановлении получает новый invocationID, и USN rollback из части 18 не происходит: для партнёров это новый источник изменений.
Процедура идёт в режиме восстановления служб каталогов (DSRM, Directory Services Restore Mode): контроллер загружается как обычный сервер без службы каталога, база лежит как файлы, и её можно заменить. Входят в него не клавишей F8 при загрузке, а через конфигурацию загрузки — так контроллер заодно не перезагрузится случайно в обычный режим посреди работы:
PS C:\> bcdedit /set safeboot dsrepair
PS C:\> Restart-Computer
Вход — локальной учётной записью .\Administrator с паролем DSRM. Затем, в консоли контроллера:
PS C:\> wbadmin get versions -backupTarget:E: -machine:dc2
PS C:\> wbadmin start systemstaterecovery -version:10/15/2026-00:00 -backupTarget:E: -machine:dc2 -quiet
PS C:\> bcdedit /deletevalue safeboot
PS C:\> Restart-Computer
wbadmin get versions перечисляет копии с их идентификаторами версии в виде ММ/ДД/ГГГГ-ЧЧ:ММ; -machine обязателен вместе с -backupTarget, когда на одном диске копии нескольких серверов. Без -quiet wbadmin дважды спросит подтверждение: продолжить ли и не менялся ли с момента копии механизм репликации SYSVOL. SYSVOL при таком восстановлении тоже неавторитетный: контроллер заберёт его с партнёров (о ключе -authsysvol — ниже).
После обычной загрузки в журнале Directory Service — событие 1109:
The invocationID attribute for this directory server has been changed. The highest update sequence number at the time the backup was created is as follows:
Дальше в событии — старый и новый invocationID и USN на момент копии, а в пояснении — когда invocationID меняется: восстановление из копии, применение снимка виртуальной машины, её импорт. Затем репликация с партнёров и проверка из части 4.
Когда это делать, а когда нет: восстанавливать имеет смысл, если контроллер — единственный или на нём есть то, что долго настраивать заново (DHCP, сертификаты, приложения, которым там не место). Контроллер с партнёрами и без особенностей быстрее переустановить и повысить заново — с носителя IFM (Install From Media: копия базы, снятая ntdsutil ifm на живом контроллере, чтобы не тянуть всю базу по сети) или просто по сети. Результат тот же, а мест для ошибки меньше.
Авторитетное восстановление
Третий сценарий — объекты удалены на всех контроллерах, корзины нет или срок вышел, а копия есть. Неавторитетное восстановление вернёт объекты на один контроллер — и репликация тут же удалит их снова: партнёры помнят удаление, и оно новее. Нужно сделать восстановленные объекты авторитетными: поднять номера версий их атрибутов так, чтобы при разрешении конфликтов из части 10 они победили.
Это делает ntdsutil на остановленной базе: в DSRM — сразу после неавторитетного восстановления и до перезагрузки. Если есть контроллер, до которого удаление ещё не дошло, можно обойтись без копии: выключить на нём входящую репликацию (repadmin /options <контроллер> +DISABLE_INBOUND_REPL), остановить службу NTDS и пометить объекты прямо на нём. С работающей службой ntdsutil к базе не подключится:
PS C:\> Invoke-Command dc2 { ntdsutil "activate instance ntds" "authoritative restore" quit }
C:\WINDOWS\system32\ntdsutil.exe: activate instance ntds
Active instance set to "ntds".
C:\WINDOWS\system32\ntdsutil.exe: authoritative restore
Service "NTDS" is running. Stop the service before binding to this Active Directory database.
C:\WINDOWS\system32\ntdsutil.exe: quit
В DSRM служба не запущена, и последовательность такая:
PS C:\> ntdsutil
ntdsutil: activate instance ntds
ntdsutil: authoritative restore
authoritative restore: restore subtree "OU=Sales,OU=Departments,DC=corp,DC=example,DC=com"
ntdsutil переспросит в окне подтверждения (в сценарии его отключают командой popups off). Конец вывода в документации выглядит так (имена файлов — с нашей датой и доменом):
Successfully updated 3 records.
The following text file with a list of authoritatively restored
objects has been created in the current working directory:
ar_20261015-193512_objects.txt
One or more specified objects have back-links in this domain. The
following LDIF files with link restore operations have been created
in the current working directory:
ar_20261015-193512_links_corp.example.com.ldf
Authoritative Restore completed successfully.
Версия каждого атрибута каждого объекта поддерева поднимается по документации на 100 000 за каждый день с момента копии (verinc <число> в конце команды меняет 100 000 на другое значение — это нужно, если одну и ту же копию восстанавливают авторитетно второй раз). Ни одно изменение, сделанное за это время на других контроллерах, столько версий не накопило, и восстановленные атрибуты побеждают. Побеждают целиком: если кому-то из объектов после копии меняли телефон или пароль, это изменение проиграет — пароль вернётся к значению на момент копии, и об этом нужно предупредить. Зато атрибуты и значения, которых в копии не было, сохраняются: пользователь, добавленный в восстановленную группу после копии, из неё не исчезнет.
restore object "<DN>" вместо restore subtree помечает один объект; документация советует выбирать как можно более низкий уровень дерева, чтобы не откатить в прошлое то, что к удалению отношения не имеет. Пометить авторитетной всю базу целиком в ntdsutil для Windows Server 2008 и новее нельзя: такой откат — уже не восстановление объектов, а восстановление леса (ниже).
После этого — перезагрузка в обычный режим, и порядок из статьи Microsoft о восстановлении удалённых пользователей и групп: контроллер на время отключают от сети, выключают ему входящую репликацию, чтобы партнёры не успели прислать удаление, возвращают сеть и выталкивают восстановленное наружу:
PS C:\> repadmin /options dc2 +DISABLE_INBOUND_REPL
PS C:\> repadmin /syncall /d /e /P dc2 DC=corp,DC=example,DC=com
/syncall с /P (push) отправляет изменения с dc2 партнёрам, /e — во всех сайтах, /d — с именами вместо GUID в выводе.
Строка про back-links в выводе ntdsutil — то, из-за чего авторитетное восстановление сложнее, чем кажется. Членство пользователя в группе хранится в member группы (прямая ссылка), а memberOf пользователя (обратная ссылка) вычисляется из неё и не реплицируется. В лесах с функциональным уровнем Windows Server 2003 и выше каждое значение member реплицируется отдельно (LVR, linked-value replication), и ntdsutil поднимает версии и у ссылок на восстановленные объекты — членство возвращается само. Но порядок репликации может его потерять, поэтому документация советует в любом случае применить LDIF-файл (LDAP Data Interchange Format — текстовый файл с операциями над каталогом), который ntdsutil создал рядом:
PS C:\> ldifde -i -k -f ar_20261015-193512_links_corp.example.com.ldf
PS C:\> repadmin /options dc2 -DISABLE_INBOUND_REPL
-i — импорт, -k — пропускать ошибки «такое значение уже есть». Для групп в других доменах леса LDIF-файл строят в каждом из них отдельно из ar_…_objects.txt (create ldif file from в том же меню ntdsutil), а членство в доменных локальных группах чужих доменов глобальный каталог не хранит вовсе.
SYSVOL
Четвёртый сценарий — не каталог, а файлы: SYSVOL на контроллерах разошёлся (после 2213 или 4012 из части 18, после того, как кто-то правил файлы политик прямо на диске) или все контроллеры восстановлены одновременно и никто не может быть источником. У DFS-R для этого два режима. Их названия унаследованы от старой службы репликации файлов FRS (File Replication Service), которую DFS-R заменила: в FRS это были значения D2 и D4 параметра BurFlags, и так их до сих пор и называют.
- D2 — неавторитетная синхронизация: «забудь свою копию и возьми с партнёра». Для контроллера, у которого SYSVOL неверен; остальных не трогают.
- D4 — авторитетная: «моя копия правильная, все остальные берут с меня». Для одного контроллера — по рекомендации Microsoft, PDC, у которого SYSVOL обычно самый свежий; все остальные после этого обязаны сделать D2, иначе будут конфликты.
Оба режима — атрибуты объекта подписки контроллера на SYSVOL в каталоге: msDFSR-Enabled (участвует ли папка в репликации) и msDFSR-Options (1 — «я авторитетен»). Как они выглядят в обычном состоянии:
PS C:\> Get-ADObject -LDAPFilter '(cn=SYSVOL Subscription)' -SearchBase (Get-ADDomain).DomainControllersContainer -Properties msDFSR-Enabled, msDFSR-Options |
Format-Table @{n='DC'; e={($_.DistinguishedName -split ',')[3]}}, msDFSR-Enabled, msDFSR-Options
DC msDFSR-Enabled msDFSR-Options
-- -------------- --------------
CN=DC2 True
CN=DC1 True
CN=DC3 True
CN=DC4 True
msDFSR-Options не задан ни у кого, репликация включена везде. D2 для одного dc3:
PS C:\> $sub = 'CN=SYSVOL Subscription,CN=Domain System Volume,CN=DFSR-LocalSettings,CN=DC3,OU=Domain Controllers,DC=corp,DC=example,DC=com'
PS C:\> Set-ADObject $sub -Replace @{ 'msDFSR-Enabled' = $false } -Server dc1
PS C:\> repadmin /syncall dc1 /APed
PS C:\> Invoke-Command dc3 { dfsrdiag pollad }
# ждать событие 4114 в журнале DFS Replication на dc3
PS C:\> Set-ADObject $sub -Replace @{ 'msDFSR-Enabled' = $true } -Server dc1
PS C:\> repadmin /syncall dc1 /APed
PS C:\> Invoke-Command dc3 { dfsrdiag pollad }
# ждать 4614, затем 4604 на dc3
Изменение пишется на dc1 и сразу выталкивается оттуда на все контроллеры леса (/A — все разделы, /P — от dc1 к партнёрам, /e — и в других сайтах, /d — имена вместо GUID в выводе): DFS Replication на dc3 читает свою конфигурацию из каталога, и она должна туда дойти. dfsrdiag pollad заставляет службу перечитать конфигурацию, не дожидаясь очередного опроса. 4114 — «папка отключена», 4614 — «инициализирована и ждёт первой синхронизации с партнёром», 4604 — «первая синхронизация с партнёром завершена». Пока на контроллере не появилось 4604, он не публикует SYSVOL, и клиенты не берут с него политики.
D4 длиннее. На всех контроллерах домена останавливают службу DFSR (и ставят ей тип запуска Manual, чтобы не поднялась сама); на авторитетном ставят msDFSR-Enabled = FALSE и msDFSR-Options = 1, на всех остальных — msDFSR-Enabled = FALSE; реплицируют AD и проверяют, что дошло везде. Затем запускают DFSR на авторитетном и ждут 4114; ставят ему msDFSR-Enabled = TRUE, снова реплицируют AD, dfsrdiag pollad на нём и ждут 4602 — «инициализирован, этот участник — основной». Только после этого запускают DFSR на остальных (у каждого 4114), включают им msDFSR-Enabled, делают dfsrdiag pollad, и каждый проходит 4614 → 4604, забирая копию с авторитетного. В конце типу запуска DFSR возвращают Automatic.
Та же логика — после восстановления контроллера из копии: восстановленный SYSVOL по умолчанию неавторитетный (D2), а wbadmin start systemstaterecovery -authsysvol делает его авторитетным (D4). Авторитетный SYSVOL нужен только первому контроллеру каждого домена, восстановленному при восстановлении леса; на остальных он даст те самые конфликты.
Восстановление леса
Пятый сценарий — тот, которого никто не хочет: каталог испорчен или скомпрометирован на всех контроллерах. Неудачное расширение схемы, шифровальщик, злонамеренный администратор, восстановление из копии, которая оказалась копией уже испорченного. План для него Microsoft опубликовала отдельным руководством (Active Directory Forest Recovery Guide), и его стоит прочитать и отрепетировать до того, как он понадобится. Фазы в нём такие: определить проблему и убедиться, что восстановление леса действительно нужно (это последний вариант, а не первый); решить, из каких копий восстанавливать; провести начальное восстановление в изоляции; ввести остальные контроллеры заново; навести порядок с DNS и приложениями.
Начальное восстановление — по одному доступному для записи контроллеру в каждом домене, начиная с корневого. Для него руководство перечисляет шаги, главные из них:
- Восстановить из копии, сделанной до инцидента, без подключения к рабочей сети: неавторитетно для AD DS и авторитетно для SYSVOL (
-authsysvolили D4 после восстановления). Проверить, что данные не задеты, иначе — другая копия. - Если причина — взлом: сменить пароли всех административных учётных записей (Enterprise Admins, Domain Admins, Schema Admins и прочих), пересоздать gMSA, при необходимости — пароли доверий и пароли всех пользователей.
- Захватить роли FSMO (часть 17) и очистить метаданные всех остальных контроллеров домена (часть 19).
- Проверить DNS на этом контроллере: служба работает, контроллер указывает DNS-клиентом на себя, записи удалённых контроллеров убраны.
- Поднять
rIDAvailablePoolна 100 000 — чтобы новые учётные записи не получили RID, уже выданные после копии (и права, оставшиеся у тех SID на ресурсах), — и сделать недействительным текущий пул RID. - Дважды сменить пароль учётной записи компьютера этого контроллера и дважды —
krbtgt(часть 6): история паролейkrbtgt— два значения, и только второй сброс вытесняет из неё пароль, бывший до сбоя. - В многодоменном лесу снять с него глобальный каталог: GC из копии новее, чем копии других доменов, принесёт lingering objects.
- Настроить время на PDC корневого домена.
Затем восстановленные контроллеры соединяют в общей изолированной сети, проверяют репликацию (repadmin /replsum, dcdiag /v), добавляют глобальный каталог, делают новые копии — и только потом ставят остальные контроллеры с нуля. Почему по одному на домен: самое важное в восстановлении леса — база, на которую не повлияло то, что сломало лес, и проверить на это одну копию проще, чем несколько; остальные контроллеры получают данные уже с неё.
Снимки и клоны
Снимок виртуальной машины контроллера — не резервная копия, и в части 18 было почему: откат к снимку на гипервизоре без VM-GenerationID — USN rollback. С VM-GenerationID (идентификатор, который гипервизор меняет в виртуальной машине при применении снимка или импорте копии) контроллер замечает откат, берёт новый invocationID, отказывается от текущего пула RID и неавторитетно синхронизирует каталог и SYSVOL с партнёров. Каталог это переживает, но изменения, сделанные на этом контроллере после снимка и не успевшие уйти партнёрам, потеряны навсегда, а всё, что не приходит обратно репликацией (файлы, базы приложений, настройки на самом сервере), прыгает в прошлое. Microsoft прямо пишет, что безопасное восстановление снимка не заменяет ни копию состояния системы, ни корзину. И одновременно восстанавливать из снимков все контроллеры домена нельзя: каждый объявит свой SYSVOL неавторитетным и будет ждать авторитетного партнёра, которого нет, — тогда спасает D4 из раздела выше.
В Hyper-V два вида контрольных точек. Стандартная (standard) сохраняет диск и память работающей машины, и документация Hyper-V прямо предупреждает, что для систем, реплицирующих данные между узлами, таких как Active Directory, это источник несогласованности. Рабочая (production, по умолчанию) делается изнутри гостя через VSS, без памяти, и после применения машина стоит выключенной и загружается заново. Это делает откат аккуратнее, но не превращает снимок в копию: он живёт на том же хранилище, что и машина. У снимка есть одно честное применение — откат в течение часа после неудачного обновления, пока ни одно изменение каталога не успело разойтись.
Есть и снимки самой базы — ntdsutil snapshot. Это теневая копия VSS томов с базой и журналами, сделанная без остановки контроллера; её можно смонтировать и открыть как отдельный LDAP-сервер утилитой dsamain, чтобы посмотреть, как каталог выглядел в момент снимка: что было в удалённой OU, какие были права, кто состоял в группе. Это инструмент выбора, что восстанавливать, а не способ восстановления: данные в смонтированном снимке только для чтения.
PS C:\> Invoke-Command dc2 { ntdsutil "activate instance ntds" snapshot "?" "list all" quit quit }
C:\WINDOWS\system32\ntdsutil.exe: activate instance ntds
Active instance set to "ntds".
C:\WINDOWS\system32\ntdsutil.exe: snapshot
snapshot: ?
? - Show this help information
Activate Instance %s - Set "NTDS" or a specific AD LDS instance
as the active instance.
Create - Create a snapshot
Delete %s - Delete snapshot with index or guid %s. Specify * to delete all snapshots
Help - Show this help information
List All - List snapshots
List Mounted - List mounted snapshots
Mount %s - Mount snapshot with index or guid %s
Quit - Return to the prior menu
Unmount %s - Unmount snapshot with index or guid %s. Specify * to unmount all mounted snapshots
snapshot: list all
No snapshots found.
snapshot: quit
C:\WINDOWS\system32\ntdsutil.exe: quit
Снимков нет. Порядок работы по документации: ntdsutil "activate instance ntds" snapshot create quit quit (его же ставят в задачу планировщика), затем mount <GUID> — снимок появляется как папка C:\$SNAP_<дата>_VOLUMEC$\; затем на том же контроллере
PS C:\> dsamain -dbpath 'C:\$SNAP_202610151800_VOLUMEC$\Windows\NTDS\ntds.dit' -ldapPort 51389
и пока dsamain работает, снимок отвечает как LDAP-сервер на порту 51389 (и следующих трёх — LDAPS и глобальный каталог). Читать его можно ldp.exe или командлетами модуля с -Server dc2:51389; доступ по умолчанию только у Domain Admins и Enterprise Admins. Остальные ключи (-logpath, -allowUpgrade, -allowNonAdminAccess, порты LDAPS и глобального каталога) dsamain /? печатает сам. Снимок содержит все хэши паролей домена, так что хранить его нужно так же бережно, как копию.
Что виртуализация действительно даёт — клонирование контроллеров, с Windows Server 2012. Вместо установки и повышения нового контроллера копируют виртуальную машину существующего, и при первом старте копия сама становится новым контроллером с новым именем, адресом, invocationID и учётной записью. Условия: PDC на Windows Server 2012 или новее и доступен во время клонирования, гипервизор поддерживает VM-GenerationID, исходный контроллер — член группы Cloneable Domain Controllers (по умолчанию пустой) и на нём нет программ и служб, о совместимости которых с клонированием система не знает. Проверка последнего:
PS C:\> Get-ADGroup 'Cloneable Domain Controllers' -Properties member | Format-List Name, GroupScope, member
Name : Cloneable Domain Controllers
GroupScope : Global
member : {}
PS C:\> $x = Invoke-Command dc2 { Get-ADDCCloningExcludedApplicationList }
PS C:\> $x | Group-Object Type | Format-Table Count, Name
Count Name
----- ----
6 Program
83 Service
4 WoW64Program
PS C:\> $x | Where-Object Name -in 'DHCPServer', 'NtFrs', 'LocalKdc', 'sshd' | Format-Table Name, Type
Name Type
---- ----
DHCPServer Service
LocalKdc Service
NtFrs Service
sshd Service
Девяносто три записи на контроллере Windows Server 2025 с DNS, DHCP, OpenSSH и PowerShell 7. В списке не только роль DHCP, OpenSSH из части 16 и PowerShell 7, но и десятки встроенных служб самой ОС (LocalKdc, NtFrs и другие): список разрешённого, зашитый в систему, их не знает. Клонирование не начнётся, пока каждую такую запись не удалят с сервера или не внесут в CustomDCCloneAllowList.xml (Get-ADDCCloningExcludedApplicationList -GenerateXml создаёт его из текущего списка — решать, что из этого действительно безопасно копировать, остаётся администратору).
Дальше, на самом dc2:
PS C:\> Add-ADGroupMember 'Cloneable Domain Controllers' -Members (Get-ADComputer dc2)
PS C:\> New-ADDCCloneConfigFile -CloneComputerName dc5 -Static -IPv4Address 192.168.1.12 -IPv4SubnetMask 255.255.255.0 -IPv4DefaultGateway 192.168.1.1 -IPv4DNSResolver 192.168.1.10 -SiteName Office
New-ADDCCloneConfigFile проверяет условия выше и пишет DCCloneConfig.xml в C:\Windows\NTDS. Затем dc2 штатно выключают (копировать работающий контроллер нельзя), удаляют его контрольные точки, экспортируют машину и импортируют копию с новым ID; статический MAC-адрес, если он был задан у источника, копии меняют. При старте гипервизор выдаёт копии новый VM-GenerationID, каталог находит DCCloneConfig.xml, через PDC создаёт учётную запись нового контроллера и повышает его из своей же базы. Через несколько минут в домене пять контроллеров. Это самый быстрый способ добавить контроллер, и он же — причина, по которой образ виртуальной машины контроллера должен храниться так же бережно, как резервная копия: в нём весь каталог.
Смотрим руками
Когда каталог копировался последний раз, с его собственной точки зрения:
PS C:\> repadmin /showbackup
Repadmin: running command /showbackup against full DC dc2.corp.example.com
Loc.USN Originating DSA Org.USN Org.Time/Date Ver Attribute
======= =============== ========= ============= === =========
DC=DomainDnsZones,DC=corp,DC=example,DC=com
12694 4a7e9c21-6b0d-4f3e-9a58-2c1d7e8b6f40 447603 2011-12-04 21:24:31 155 dSASignature
DC=ForestDnsZones,DC=corp,DC=example,DC=com
12618 4a7e9c21-6b0d-4f3e-9a58-2c1d7e8b6f40 447604 2011-12-04 21:24:31 155 dSASignature
CN=Schema,CN=Configuration,DC=corp,DC=example,DC=com
4101 4a7e9c21-6b0d-4f3e-9a58-2c1d7e8b6f40 447602 2011-12-04 21:24:31 155 dSASignature
CN=Configuration,DC=corp,DC=example,DC=com
8589 4a7e9c21-6b0d-4f3e-9a58-2c1d7e8b6f40 447601 2011-12-04 21:24:31 155 dSASignature
DC=corp,DC=example,DC=com
11899 4a7e9c21-6b0d-4f3e-9a58-2c1d7e8b6f40 447600 2011-12-04 21:24:31 155 dSASignature
Формат — тот же, что у repadmin /showobjmeta: это метаданные репликации атрибута dSASignature на корне каждого из пяти разделов. Org.Time/Date — когда его записала последняя успешная копия, Ver — сколько раз он менялся, то есть примерно столько копий и было сделано (155). Originating DSA — контроллер, на котором делали копию; вместо имени здесь GUID: repadmin не нашёл в лесу контроллер с таким invocationID — его давно нет (или его база с тех пор восстанавливалась и получила новый). Иначе говоря, в этом лесу копию последний раз делали почти пятнадцать лет назад, на контроллере, которого уже не существует.
Почему тогда не все контроллеры кричат об этом событием 2089:
PS C:\> Invoke-Command $dcs { Get-WinEvent -FilterHashtable @{LogName='Directory Service'; Id=2089} -ErrorAction SilentlyContinue | Measure-Object } | Sort-Object PSComputerName | Format-Table PSComputerName, Count
PSComputerName Count
-------------- -----
dc1.corp.example.com 0
dc2.corp.example.com 995
dc3.corp.example.com 0
dc4.corp.example.com 190
PS C:\> Invoke-Command $dcs { Get-ItemProperty 'HKLM:\SYSTEM\CurrentControlSet\Services\NTDS\Parameters' | Select-Object 'Backup Latency Threshold (days)' } | Sort-Object PSComputerName | Format-Table PSComputerName, 'Backup Latency Threshold (days)'
PSComputerName Backup Latency Threshold (days)
-------------- -------------------------------
dc1.corp.example.com 7300
dc2.corp.example.com 3650
dc3.corp.example.com 7300
dc4.corp.example.com
Ровно то, о чём шла речь в начале: на dc1 и dc3 порог когда-то подняли до 7300 дней (двадцать лет), и они молчат; на dc2 — до 3650, десять лет давно прошли, и он снова пишет; на dc4, введённом недавно, параметра нет, действует половина срока tombstone. Число событий — сколько их уместилось в журнале, по пять в день, на каждый раздел. Само событие:
PS C:\> Invoke-Command dc4 { Get-WinEvent -FilterHashtable @{LogName='Directory Service'; Id=2089} -MaxEvents 1 } | Select-Object -ExpandProperty Message
This directory partition has not been backed up since at least the following number of days.
Directory partition:
DC=DomainDnsZones,DC=corp,DC=example,DC=com
'Backup latency interval' (days):
90
It is recommended that you take a backup as often as possible to recover from accidental loss of data. However if you haven't taken a backup since at least the 'backup latency interval' number of days, this message will be logged every day until a backup is taken. You can take a backup of any replica that holds this partition.
By default the 'Backup latency interval' is set to half the 'Tombstone Lifetime Interval'. If you want to change the default 'Backup latency interval', you could do so by adding the following registry key.
'Backup latency interval' (days) registry key:
System\CurrentControlSet\Services\NTDS\Parameters\Backup Latency Threshold (days)
Лечится это одной копией состояния системы любого контроллера: dSASignature всех его разделов обновится, реплицируется, и 2089 перестанет приходить везде. Заглушки порога после этого стоит убрать.
Что видит авторитетное восстановление — метаданные атрибутов удалённой Carol White с dc1:
PS C:\> $carol = Get-ADObject -Filter 'msDS-LastKnownRDN -eq "Carol White"' -IncludeDeletedObjects
PS C:\> repadmin /showobjmeta dc1 "<GUID=$($carol.ObjectGUID)>" | Select-String -CaseSensitive 'Ver Attribute| cn$|isDeleted| name$|unicodePwd|sAMAccountName$|lastKnownParent'
Loc.USN Originating DSA Org.USN Org.Time/Date Ver Attribute
56808235 Office\DC1 56808235 2026-10-26 02:21:55 4 cn
56808235 Office\DC1 56808235 2026-10-26 02:21:55 3 isDeleted
56808235 Office\DC1 56808235 2026-10-26 02:21:55 4 name
56808148 Office\DC1 56808148 2026-10-26 02:16:52 2 unicodePwd
56808146 Office\DC1 56808146 2026-10-26 02:16:52 1 sAMAccountName
56808207 Office\DC1 56808207 2026-10-26 02:18:53 1 lastKnownParent
repadmin /showobjmeta принимает и удалённый объект, если указать его GUID. Удаление — это изменение атрибутов: isDeleted версии 3 (объект удаляли, восстанавливали из корзины и удалили снова), cn и name версии 4 — переименование в Carol White\0ADEL:…. Именно эти версии видят партнёры, и именно их должна перебить копия: авторитетное восстановление сделанной накануне копии подняло бы версию isDeleted у этого объекта до 100 000 с небольшим, и удаление проиграло бы.
И SYSVOL глазами DFS-R — как dc4, когда его вводили в домен, получил SYSVOL неавторитетно, тем же путём, что и D2:
PS C:\> Invoke-Command dc4 {
foreach ($id in 4614, 4604) {
Get-WinEvent -FilterHashtable @{LogName='DFS Replication'; Id=$id} | Select-Object TimeCreated, Id, @{n='Partner'; e={$_.Properties[6].Value}}
}
} | Format-Table TimeCreated, Id, Partner
TimeCreated Id Partner
----------- -- -------
22.09.2026 19:32:01 4614 dc3.corp.example.com
22.09.2026 19:32:04 4604 dc3.corp.example.com
4614 — папка инициализирована и ждёт первой синхронизации, 4604 через три секунды — синхронизация с dc3 завершена, SYSVOL опубликован. Поле Partner вычисляется внутри Invoke-Command: у событий, пришедших с сервера, Properties уже без значений.
Источники
Резервное копирование
- wbadmin start systemstatebackup — копия состояния системы, том или сетевая папка как цель;
- wbadmin start backup — состав состояния системы, критические тома, перезапись копии на сетевой папке;
- Known Issues for AD DS Backup and Recovery — файловые зоны DNS не входят в состояние системы,
AllowSSBToAnyVolume; - New-WBPolicy, New-WBBackupTarget, Set-WBSchedule, Set-WBPolicy, Add-WBBareMetalRecovery и Get-WBSummary — расписание копий из модуля
WindowsServerBackup; - NTDS Replication Event 2089 is logged —
dSASignature, событие 2089 иBackup Latency Threshold (days); - Shelf life of a system-state backup of AD и Tombstone-Lifetime — почему копия старше срока tombstone не годится;
- Backup-DhcpServer, Backup-GPO и Backup-CARoleService — копии DHCP, групповых политик и удостоверяющего центра.
Корзина
- Enable Active Directory Recycle Bin — что сохраняется у удалённого объекта, необратимость, восстановление;
- Restore-ADObject —
lastKnownParent,msDS-LastKnownRDN,-TargetPathи-NewName; - MS-ADTS: Tombstone Lifetime and Deleted-Object Lifetime — пустой
msDS-DeletedObjectLifetimeравен сроку tombstone.
Восстановление
- Restart the domain controller in Directory Services Restore Mode —
bcdedit /set safeboot dsrepairи вход с паролем DSRM; - Restore AD DS from backup (nonauthoritative restore), wbadmin get versions и wbadmin start systemstaterecovery — неавторитетное восстановление,
-machine,-authsysvol; - Performing Authoritative Restore of Active Directory Objects и Mark an object or objects as authoritative — процедура, остановленная служба вместо DSRM, LVR и back-links, пример вывода,
verinc; - authoritative restore — подкоманды
ntdsutil, 100 000 за каждый день с момента копии; - Restore user accounts and groups in AD — порядок с
+DISABLE_INBOUND_REPLиrepadmin /syncall /d /e /P, LDIF-файлы; - Run an LDIF file to recover back-links —
ldifde -i -k -f.
SYSVOL и лес
- Force synchronization for DFSR-replicated sysvol replication — D2 и D4,
msDFSR-Enabled,msDFSR-Options, события 4114, 4602, 4614, 4604; - Active Directory Forest Recovery Guide, Steps for restoring the forest и Perform initial recovery — фазы восстановления леса и шаги для первого контроллера домена.
Снимки и клоны
- Safely virtualizing Active Directory Domain Services — USN rollback, VM-GenerationID, снимок не заменяет копию;
- Virtualized Domain Controller Deployment and Configuration — условия и шаги клонирования,
CustomDCCloneAllowList.xml, одновременное восстановление всех контроллеров; - Get-ADDCCloningExcludedApplicationList и New-ADDCCloneConfigFile — командлеты клонирования;
- Using checkpoints — стандартные и рабочие контрольные точки Hyper-V;
- Active Directory Domain Services Database Mounting Tool Step-by-Step Guide —
ntdsutil snapshotиdsamain.
Блок об эксплуатации закончен. Следующие три части — о том, что лежит за границей одного домена: когда доменов нужно несколько, когда нужен второй лес, и как два леса договариваются доверять друг другу.
Дальше — часть 21: несколько доменов и лесов. Дочерний домен против отдельного леса: что общего у доменов одного леса и чего не отменить, схема и Enterprise Admins как граница, когда второй лес действительно нужен, и как выглядит создание дочернего домена и нового дерева командами Install-ADDSDomain и Install-ADDSForest.
Оставить комментарий могут только зарегистрированные пользователи.
Войдите на сайт или зарегистрируйтесь, чтобы оставить комментарий.