В этой статье мы поговорим об особенностях резервного копирования контроллеров домена Active Directory, рассмотрим, как настроить автоматическое резервное копирование AD с помощью PowerShell и встроенных средств Windows Server.
Нужно ли бэкапить Active Directory?
Не раз слышал от знакомых администраторов мысль, что если у тебя несколько (5, 10 и т.д.) территориально разнесенных контроллеров домена Active Directory, то бэкапать AD вообще не нужно, т.к. при нескольких DC вы уже обеспечили высокую отказоустойчивость домена. Ведь в такой схеме вероятность одновременного выхода из строя всех DC стремится к 0, а если один контроллер домена упал, то быстрее развернуть новый DC на площадке, а старый контроллер домена удалить согласно инструкции (или с помощью ntdsutil).
Однако в своей практике я встречался с различными сценариями, когда все контроллеры домена оказались повреждёнными: в одном случае все контроллеры домена (а их было более 20 штук в разных городах) оказались зашифрованными из-за перехвата пароля домена шифровальщиком через утилиту mimikatz (для предотвращения таких схем см. статьи “Защита Windows от mimikatz” и “Защита привилегированных групп администраторов”), в другом случае домен положила репликация поврежденного файла NTDS.DIT.
В общем, бэкапить AD можно и нужно. Как минимум вы должны регулярно создавать резервные копии ключевых контроллеров доменов, владельцев ролей FSMO (Flexible single-master operations). Вы можете получить список контролеров домена с ролями FSMO командой:
netdom query fsmo
Как проверить дату последнего бэкапа контроллера домена Active Directory?
Вы можете проверить, когда создавалась резервная копия текущего контроллера домена Active Directory с помощью утилиты repadmin:
repadmin /showbackup
В данном примере видно, что последний раз бэкап DC и разделов AD выполнялся 2017-02-18 18:01:32 (скорее всего он не делался с момента развертывания контроллера домена).
Вы можете получить статус по резервному копированию всех DC в домене командой:
repadmin /showbackup *
Бэкап контроллера домена AD с помощью Windows Server Backup
Если у вас нет специального ПО для резервного копирования, вы можете использовать для создания резервных копий встроенный Windows Server Backup (этот компонент пришел на замену NTBackup). Вы можете настроить автоматическое задание резервного копирования в графическом интерфейсе Windows Server Backup, но у него будут ряд ограничений. Основной недостаток – новая резервная копия сервера всегда будет перезаписывать старую.
При создании резервной копии контроллера домена через WSB, вы создаете резервную копию Состояния системы (System State). В System State попадает база Active Directory (NTDS.DIT), объекты групповых политик, содержимое каталога SYSVOL, реестр, метаданные IIS, база AD CS, и другие системные файлы и ресурсы. Резервная копия создается через службу теневого копирования VSS.
Вы можете проверить, установлен ли компонент Windows Server Backup с помощью PowerShell командлета Get-WindowsFeature:
Get-WindowsFeature Windows-Server-Backup
Если компонент WSB отсутствует, его можно установить с помощью PowerShell:
Add-Windowsfeature Windows-Server-Backup –Includeallsubfeature
Или установите его из Server Manager -> Features.
Я буду сохранять бэкап данного контроллера домена AD в сетевую папку на отдельном выделенном сервере для резевного копирования. Например, путь к каталогу будет таким \\srvbak1\backup\dc01. Настроим NTFS разрешения на этой папке: предоставьте права чтения-записи в этот каталог только для Domain Admins и Domain Controllers.
Резервное копирование Active Directory с помощью PowerShell
Попробуем создать бэкап контроллера домена с помощью PowerShell. Для хранения нескольких уровней копий AD мы будем хранить каждый бэкап в отдельном каталоге с датой создания копии в качестве имени папки.
Import-Module ServerManager
[string]$date = get-date -f 'yyyy-MM-dd'
$path=”\\srvbak1\backup\dc1\”
$TargetUNC=$path+$date
$TestTargetUNC= Test-Path -Path $TargetUNC
if (!($TestTargetUNC)){
New-Item -Path $TargetUNC -ItemType directory
}
$WBadmin_cmd = "wbadmin.exe START BACKUP -backupTarget:$TargetUNC -systemState -noverify -vssCopy -quiet"
Invoke-Expression $WBadmin_cmd
Запустите данный скрипт. Должна появится консоль wbadmin с информацией о процессе создании резервной (теневой) копии диска:
The backup operation to \\srvbak1\backup\dc1\2019-10-10 is starting. Creating a shadow copy of the volumes specified for backup...
Detailed error: The filename, directory name, or volume label syntax is incorrect. The backup of the system state failed [10.10.2019 8:31].
Я открыл журнал ошибок WSB — C:\Windows\Logs\WindowsServerBackup\Backup_Error-10-10-2019_08-30-24.log.
В файле содержится одна ошибка:
Error in backup of C:\windows\\systemroot\ during enumerate: Error [0x8007007b] The filename, directory name, or volume label syntax is incorrect.
Забегая вперед, скажу, что проблема оказалась в некорректном пути в одном из драйверов VMWware Tools.
Чтобы исправить эту ошибку, откройте командную строку с правами администратора и выполните:
DiskShadow /L writers.txt
list writers detailed
После формирование списка наберите quit и откройте файл «C:\Windows\System32\writers.txt». Найдите в нем строку, содержащую “windows\\”.
В моем случае найденная строка выглядит так:
File List: Path = c:\windows\\systemroot\system32\drivers, Filespec = vsock.sys
Как вы видите, используется неверный путь к драйверу VSOCK.SYS.
Чтобы исправить путь, откройте редактор реестра и перейдите в раздел HKLM\SYSTEM\CurrentControlSet\Services\vsock.
Измените значение ImagePath с
\systemroot\system32\DRIVERS\vsock.sys
на
System32\DRIVERS\vsock.sys
Запустите скрипт бэкапа еще раз.
Если бэкап выполнен успешно, в логе появятся сообщения:
The backup operation successfully completed. The backup of volume (C:) completed successfully. The backup of the system state successfully completed [10.10.2019 9:52].
Проверим даты последнего бэкапа на DC:
repadmin /showbackup
Теперь тут указано, что последний раз бэкап контроллера домена выполнялся сегодня.
На сервере резевного копирования размер каталога с резервной копией контроллера домена занимает около 9 Гб. По сути на выходе вы получили vhdx файл, который можно использовать для восстановления ОС через WSB, или вы можете вручную смонтировать vhdx файл и скопировать из него нужные файлы или папки.
$WBadmin_cmd = "wbadmin start backup -backuptarget:$path -include:C:\Windows\NTDS\ntds.dit -quiet"
Invoke-Expression $WBadmin_cmd
Размер такого бэкапа будет составлять всего 50-500 Мб в зависимости от размера базы AD.
Для автоматического выполнения бэкапа, нужно на DC создать скрипт c:\ps\backup_ad.ps1. Этот скрипт нужно запускать по расписанию через Task Sheduler. Вы можете создать задание планировщика из графического интерфейса или из PowerShell. Главное требование — задание должно запускать от имени SYSTEM с включенной опцией Run with highest privileges. Для ежедневного бэкапа контролера домена AD создайте следующее задание:
$Trigger= New-ScheduledTaskTrigger -At 01:00am -Daily
$User= "NT AUTHORITY\SYSTEM"
$Action= New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "c:\ps\backup_ad.ps1"
Register-ScheduledTask -TaskName "StartupScript_PS" -Trigger $Trigger -User $User -Action $Action -RunLevel Highest –Force
Итак, мы настроили резевное копирование состояния AD, а в следующей статье мы поговорим о способах восстановления AD из имеющейся резервной копии контроллера домена.
Что если владельцем ролей был один домен контроллер, а бэкапы есть другого, при этом оба умерли. Восстановится нормально?
Поднимать новый сервер и попытаться подменить ntds.dit, SYSVOL. Возможно понадобится подменить кусты реестра SAM и SYSTEM.
Все верно. Досточно развернуть второй DC из бэкапа и принудительно захватить FSMO роли по стандартной процедуре.
Наткнулся в инете на блог с описанием реального случая восстановления AD. Описывался тяжелый случай — из-за помершей батарейки на кеше RAIDа умерли оба DC (ntds.dit был испорчен). Восстановление из резервной копии контроллера давало глючный сервер (постоянный экран смерти). Но в бэкапе была исправнst база AD и sysvol. Для восстановления AD оказалось недостаточно копий ntds.dit и sysvol. Нужно еще кусты реестра SAM и SYSTEM копировать. Получили глючный сервер, но с исправной AD и рабочей консолью. Дальше уже было дело техники.
Есть шутка. Админы делятся на 2 типа: те, кто делают бэкапы и те, кто не делаетт. Первый тип делится на 2 подтипа: те, кто проверяют бэкапы, те , кто не проверяют. )))
Попробовал все работает.
Решил немного изменить команду, у меня на диске «Е» объемные файлы, которые хотелось бы исключить из резервной копии.
$WBadmin_cmd = «wbadmin.exe START BACKUP -backupTarget:$TargetUNC -systemState -noverify -vssCopy -quiet -exclude:e:»
Не работает.
В systemstate другие диски и так не включаются. Да и с системного диска забирается далеко не все.
Вышла статья про восстановление Active Directory — https://winitpro.ru/index.php/2019/10/31/vosstanovlenie-active-directory-backup/
Я правильно понимаю — в такой бэкап не попадают объёкты домена (учётные записи ЭВМ и пользователей)? То есть, если удалить OU с учётными записями ЭВМ, например, то этот бэкап не поможет?
Неправильно. В бэкапе будет присуствовать полностью база данных AD (ntds.dit) со всеми объектами (OU, пользватели, компьютеры). Вы можете восстановить из него что-угодно.
Если вы хотите защититься от случайных удалений, включайте на защищаемых OU атрибут «Protect object from accidental deletion» и корзину AD для всего домена (Active Directory Recycle Bin). Так гораздо проще восстаналивать удаленные объекты.
Спасибо! Хорошая статья!
Может у кого этот скрипт оброс логированием и удалением старых резервных копий?
$(
‘Start_backup’
Import-Module ServerManager
[string]$date = get-date -f ‘yyyy-MM-dd’
$path=”\\nasd2n1\dcbak\srv-dc2\”
$TargetUNC=$path+$date
$TestTargetUNC= Test-Path -Path $TargetUNC
if (!($TestTargetUNC)){
New-Item -Path $TargetUNC -ItemType directory
}
$WBadmin_cmd = «wbadmin.exe START BACKUP -backupTarget:$TargetUNC -systemState -noverify -vssCopy -quiet»
Invoke-Expression $WBadmin_cmd
) *>&1 >> «C:\ps\out-log.txt»
# Выполняем настройку скрипта удаления старых бэкапов.
# Путь к папке логов.
$TargetFolder = «\\nasd2n1\dcbak\srv-dc2»
$Period = «-7» # Количество хранимых дней.
# Вычисляем дату после которой будем удалять файлы.
$CurrentDay = Get-Date
$ChDaysDel = $CurrentDay.AddDays($Period)
# Удаление файлов, дата создания которых больше заданного количества дней
GCI -Path $TargetFolder -Recurse | Where-Object {$_.CreationTime -LT $ChDaysDel} | RI -Recurse -Force
# Удаление пустых папок
GCI -Path $TargetFolder -Recurse | Where-Object {$_.PSIsContainer -and @(Get-ChildItem -Path $_.Fullname -Recurse | Where { -not $_.PSIsContainer }).Count -eq 0 } | RI -Recurse
Здравствуйте. Спасибо очень информативно. Все работает. Подскажите как доработать скрипт. Полный бэкап 1 раз в неделю, состояние системы 6 раз в неделю. Это делается через планировщик. А вот чтобы последующие затирали предыдущие, не понимаю как сделать.
Простите. Не увидел предыдущего коментария
$TargetUNC=$path+$date
И матерится, что Destination not found.
И как-то не видно в скрипте, где команда на создание папки с именем-давтой.
Есть ли скрипт правильный, выше пример не рабочий
Забивает бекапами все пространство.
Т.е. скрипт все-таки рабочий, бэкапы создаются и вам не хватает функции очистки старых бэкапов?
Да конечно, я про скрипт в коментах, тот что в статье работает отлично.
Еще бы как то добавить очистку.
Не поделитесь как можно модернизировать скрипт? Чтобы удалял? копии
Готового нет. Бэкапы сейчас управляются через veeam, там такой скрипт не нужен.
Посмотрите комментарии выше (Сергей 17.07.2020), там есть кусок кода, который удаляет старые файлы старше 7 дней. Вполне пойдет за основу для вашего скрипта.
А для veeam нужно делать какие то специализированные настройки?
Да.
Вариант 1 — на горячую. Поставить в джобе бекапа галку «veeam application aware processing» и ввести там же учетку от ВМ, что бы вим ммог залогиниться в вм и сделать бекап с учетом работы AD . Там еще есть кнопка тест (логина в вм).
Вариант — офлайн. ПО рассписанию выключать вм, бекапить, потом включать.
Import-Module ServerManager
[string]$date = get-date -f 'yyyy-MM-dd'
$path="\\WS-210134305\DC_backup\"
$TargetUNC=$path+$date
$TestTargetUNC= Test-Path -Path $TargetUNC
if (!($TestTargetUNC)){
New-Item -Path $TargetUNC -ItemType directory
}
$WBadmin_cmd = "wbadmin.exe START BACKUP -backupTarget:$TargetUNC -systemState -noverify -vssCopy -quiet"
Invoke-Expression $WBadmin_cmd
# Выполняем настройку скрипта удаления старых бэкапов.
# Путь к папке логов.
$TargetFolder = "\\WS-210134305\DC_backup\"
$Period = "-31" # Количество хранимых дней.
# Вычисляем дату после которой будем удалять файлы.
$CurrentDay = Get-Date
$ChDaysDel = $CurrentDay.AddDays($Period)
# Удаление файлов, дата создания которых больше заданного количества дней
GCI -Path $TargetFolder -Recurse | Where-Object {$_.CreationTime -LT $ChDaysDel} | RI -Recurse -Force
# Удаление пустых папок
GCI -Path $TargetFolder -Recurse | Where-Object {$_.PSIsContainer -and @(Get-ChildItem -Path $_.Fullname -Recurse | Where { -not $_.PSIsContainer }).Count -eq 0 } | RI -Recurse
В таком виде всё работает, делает резервные копии и удаляет старше 31 дня в моём случае, однако после удаления самих файлов с сетевого диска в wbadmin остается запись в журнале о наличии резервной копии на сетевом диске, это чистить руками.
Логика правильная, старые копии надо подчищать.
По хорошему нужно удалять старые резевные копии сразу через wbadmin. На досуге посмотрю как это в скрипте реализовать)
Здравствуйте!
Благодарю Вас за полезную статью.
Подскажите пожалуйста ,сделал все по шагам как указано в статье ,но при подключении к сетевой папке через WSB система просить логин и пароль как это исправить ?
Видимо у вашей учетки нет прав для доступа к удаленному сервер. Он в домене?
Import-Module ServerManager
[string]$date = get-date -f ‘yyyy-MM-dd’
$path=”\\ZAMGLAVBUH\dc”
$TargetUNC=$path+$date
$TestTargetUNC= Test-Path -Path $TargetUNC
if (!($TestTargetUNC)){
New-Item -Path $TargetUNC -ItemType directory
}
$WBadmin_cmd = «wbadmin.exe START BACKUP -backupTarget:$TargetUNC -systemState -noverify -vssCopy -quiet»
Invoke-Expression $WBadmin_cmd Не могу разобраться, в чем ошибка?
New-Item : Путь имеет недопустимую форму.
строка:2 знак:1
+ New-Item -Path $TargetUNC -ItemType directory
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (\\ZAMGLAVBUH\dc2023-06-13:String) [New-Item], ArgumentException
+ FullyQualifiedErrorId : CreateDirectoryArgumentError,Microsoft.PowerShell.Commands.NewItemCommand
К сожалению статья не актуально, скрипт не работает. Обратной связи нет.
Import-Module ServerManager
[string]$date = get-date -f ‘yyyy-MM-dd’
$path=”D:\”
$TargetUNC=$path+$date
$TestTargetUNC= Test-Path -Path $TargetUNC
if (!($TestTargetUNC)){
New-Item -ItemType Directory -Force -Path $TargetUNC
}
$WBadmin_cmd = «wbadmin.exe START BACKUP -backupTarget:$TargetUNC -systemState -noverify -vssCopy -quiet»
Invoke-Expression $WBadmin_cmd
Получения сведений о томе…
Будет выполнена архивация Зарезервировано системой (549.00 МБ) (выбранные файлы),(C:) (выбранные файлы) на D:\2023-06-15.
ОШИБКА: указанное расположение не найдено или не поддерживается в качестве
расположения хранения архивов.
PS C:\Users\Администратор.EA>
часть кавычек в скрипте не те что нужны
Поясните, подробнее или укажите пример. Мне , к сожалению, ничего не видно
Приводить пример не буду так как в вышеприведенных примерах наверняка изначально было все в порядке, но браузер в разных кодировках использует разные кавычки и все ломается.
Все скрипты, по крайней мере я, создаю в кодировке win-1251
Скажу лишь что здесь [string]$date = get-date -f ‘yyyy-MM-dd’ одинарные кавычки.
Во всех остальных местах двойные, но не елочки. Оба вида кавычек находятся на той же клавише что и русская буква Э.