Резервирование и восстановление в Active Directory

Введение в резервирование и восстановление Active Directory

Когда я был маленьким, я хорошо знал, кем хочу стать, когда вырасту. Нет, не космонавтом. И не врачом, и не юристом. Я мечтал стать менеджером по продукту инструмента резервирования и восстановления Active Directory.

Шутка. Я был уверен, что стану трансформером.

Сейчас я вырос, трансформером так и не стал, и был озадачен написанием серии заметок о резервном копировании и восстановлении Active Directory, а также о том, почему Вам необходимо уделять этому внимание.

Так в самом деле, почему?

Если кто не знает, Microsoft Active Directory является основной службой аутентификации, используемой большинством организаций по всему миру. То есть это критически важная инфраструктура.

Резервирование и восстановление в Active Directory. К счастью, мне никогда не приходилось непосредственно присутствовать при катастрофическом падении критически важной части инфраструктуры, такой как Active Directory. Тем не менее, имея доступ в Интернет, можно почитать мнения довольно умных людей, которые оценивают убытки бизнеса, являющиеся прямым следствием такого рода сбоев, в среднем от 25 000 до 300 000 долларов в час.

Хотя эти цифры и выглядят весьма пугающе, вероятно, так оценивается воздействие только самых тяжелых сценариев восстановления Active Directory.

Да-да, существуют разные типы сценариев восстановления Active Directory! Мне нравится делить их на пять категорий: восстановление объектов, восстановление атрибутов, восстановление сервера, восстановление домена и восстановление леса.

Восстановление объектов или восстановление объектов каталога Active Directory — это относительно простой процесс, который я постараюсь очень подробно осветить в следующих двух статьях данной серии.

Восстановление атрибутов или восстановление отдельных атрибутов объекта каталога Active Directory — это значительно более сложный процесс, о котором я расскажу в четвёртой части данной серии.

Восстановление сервера или восстановление контроллера домена Active Directory должно быть относительно простой задачей для организации, имеющей более-менее приличный опыт в сфере IT. Даже если не принимать во внимание тот факт, что в организации чаще всего имеется отлаженное решение по резервному копированию серверов, процесс восстановления после физической или логической потери контроллера домена (при наличии в домене нескольких контроллеров) достаточно прост: отремонтировать сервер и восстановить его из существующей резервной копии, либо полностью заменить сервер и выполнить процесс замены контроллера.

Восстановление домена и восстановление леса практически аналогичны, можно сказать, что это взгляд на одну и ту же проблему с разных сторон. В любом случае подобного рода восстановление является необходимым ответом на инцидент, который привел к потере критического числа функциональных контроллеров домена в логической структуре Active Directory. Хотя область работ при восстановлении домена по определению меньше, чем при восстановлении леса, для разрешения обеих ситуаций используется один и тот же фундаментальный набор процессов. В сухом остатке вся разница заключается в принципах охвата и масштаба. Я не буду подробно останавливаться на процессе восстановления леса, но если Вам очень хочется узнать об этом, можете почитать здесь.

Если Вы уже столкнулись с проблемой и наткнулись на эту заметку, ища в Интернете простой способ восстановления после нежелательных изменений в Active Directory в результате случайного или злонамеренного действия, Вам также стоит обратить внимание на StealthRECOVER.

 

Резервирование и восстановление в Active Directory. Восстановление объектов Active Directory

Примечание: Для данной статьи будем считать, что в домене не была включена корзина Active Directory (Active Directory Recycle Bin). Корзина AD и её влияние на восстановление объектов будут рассмотрены в далее.

Когда какой-либо объект удаляется из Active Directory, он на самом деле не удаляется, по крайней мере, не сразу.

И это не какое-то там особое свойство, а следствие того, как реализована репликация с несколькими главными серверами, применяемая в Active Directory. Такой вариант репликации позволяет любому контроллеру домена создавать или обновлять объект, а затем реплицировать эти изменения на другие контроллеры домена.

Для того, чтобы рассмотреть, что же на самом деле происходит при удалении объекта, давайте воспользуемся утилитой LDP. И поможет нам в этом мистер Delete Q. Me, демонстрационная учётная запись пользователя, любезно созданная моим любимым PowerShell-скриптом.

Резервирование и восстановление в Active Directory

Выглядит как счастливая, здоровая пользовательская учётка, готовая поучаствовать в нашем эксперименте. Но, к сожалению, как уже упоминалось выше, жить этому пользователю осталось недолго. Сейчас мы удалим эту учётку, разумеется, из чисто научных побуждений.

Извини, приятель.

Ну а теперь, когда его не стало, у нас могут возникнуть трудности с поиском нашей мёртвой, но всё ещё не исчезнувшей учётной записи. LDP нужно немного подшаманить, чтобы он стал показывать удалённые объекты. Откроем меню «Options» и выберем пункт «Controls». В диалоговом окне «Controls» откроем выпадающий список «Load Predefined», выберем «Return deleted objects» и нажмём кнопку «OK».

Резервирование и восстановление в Active Directory

Теперь в корне нашего раздела каталога стал виден контейнер «Deleted Objects». Мы можем развернуть его и поискать наш недавно умерший пользовательский объект.

Резервирование и восстановление в Active Directory

А вот и он! А теперь давайте коротко разберём, что же произошло в каталоге в результате удаления объекта пользователя:

  1. Объект был перемещён.
    Конечно, Вы обратили внимание, что для того, чтобы найти объект удалённого пользователя, нам пришлось перейти в другое место. У каждого раздела каталога есть свой собственный контейнер «Deleted Objects». Ну, на самом деле не совсем так. У раздела «Schema» нет своего контейнера «Deleted Objects», поскольку удалять объекты из схемы данных каталога нельзя. Как Вы, наверное, уже догадались, предназначение контейнера «Deleted Objects» — хранить удалённые объекты. Active Directory скрывает эти контейнеры, пока Вы их специально не запросите, это Вы тоже уже заметили.
  2. Объект был переименован.
    Имя объекта обновляется с использованием хитроумного шаблона: Common-Name\0ADEL:Object-Guid. Такая схема именования гарантирует уникальность имён объектов даже когда будут удалены несколько объектов с совпадающим относительным уникальным именем.
  3. У объекта появилось несколько новых атрибутов.
    Теперь у нашей старой знакомой учётки три новых атрибута. Первый из них — isDeleted. Если значение этого атрибута «TRUE», значит объект был отмечен для удаления. Следующий новый атрибут — isRecycled. Этот атрибут был добавлен и ему назначено значение только потому, что функциональный уровень данного домена выше, чем Windows 2008. Иначе добавление этого атрибута не имело бы смысла, поскольку в более ранних версиях функционал доменной корзины просто отсутствовал. Наконец, ещё один новый атрибут — lastKnownParent, содержащий уникальное имя последней известной родительской записи для нашего объекта пользователя (оно нам пригодится буквально через пару минут).
  4. Множество атрибутов было удалено.
    При удалении объекта сохраняются только важные атрибуты. Атрибуты, не имеющие флага поиска 0x8 ( PRESERVE_ON_DELETE ), удаляются, так как предполагается, что они больше не нужны. В связи с тем, что я не модифицировал схему данных своего домена так, чтобы по умолчанию иметь возможность сохранить большее количество атрибутов (поскольку это не очень хорошая идея), мой пользовательский объект утратил большинство своих атрибутов вместе со связанными с ними значениями.

 

Получившийся в итоге объект называют «надгробным камнем» («tombstone»). И последнее, что мы попробуем в рамках этой демонстрации — »реанимировать» его. Это не шутки, а вполне официальные технические термины.

Так или иначе, мы можем полностью реанимировать наш «надгробный камень» утилитой LDP, используя ее функцию Modify:

Резервирование и восстановление в Active Directory

  1. Щёлкните правой кнопкой мыши по «камню» и выберите пункт меню «Modify».
  2. В секции «Edit Entry» в поле «Attribute» введите значение «isDeleted», установите переключатель в секции «Operation» в значение «Delete», и нажмите кнопку «Enter» для добавления сведений об операции в список «Entry List».
  3. В секции «Edit Entry» в поле «Attribute» введите значение «distinguishedName», в поле «Values» введите уникальное имя объекта, которое было у него до удаления, установите переключатель в секции «Operation» в значение «Replace», и нажмите кнопку «Enter» для добавления сведений об операции в список «Entry List».
    Помните, я говорил, что атрибут lastKnownParent может оказаться полезным? Так вот, если Вы не знаете, какое же DN было у объекта до удаления, можно попробовать такой трюк: возьмите текущее DN объекта и замените нуль-символ («\0A») и всё, что справа от него, на значение атрибута lastKnownParent.
  4. Выберите пункт «Extended» в левом нижнем углу панели.
  5. Нажмите кнопку «Run».

После нажатия кнопки «Run» мы можем найти вновь реанимированный объект и посмотреть, как он выглядит.

Резервирование и восстановление в Active Directory

Как видите, технически мы восстановили удалённый объект пользователя. Правда, отсутствует большая часть информации, которой он располагал до удаления.

Обойти проблему потери большинства полезных атрибутов можно, делая регулярные VSS-снапшоты Active Directory. При использовании данного метода, если Вам необходимо восстановить удалённый объект, Вы можете просто найти резервную копию, сделанную до удаления этого объекта, смонтировать снапшот с помощью NTDSUTIL, подключиться к смонтированному снапшоту с помощью LDAP-утилиты, найти объект, экспортировать его в… Ладно, не забивайте себе голову.

Но подождите, тут есть ещё один гадкий момент.

Объекты в контейнере «Deleted Objects» не вечны. Метко названное свойство tombstoneLifetime («время жизни надгробного камня») объекта CN=Directory Service,CN=Windows NT,CN-Services,CN=Configuration,ForestDistinguishedName определяет количество дней до того момента, как удалённый объект будет навсегда удалён из Active Directory.

Значение свойства tombstoneLifetime основывается на версии Windows Server, с помощью которого был создан лес используемого нами домена. В лесах, созданных с использованием Windows Server выше версии 2003, по умолчанию установлено значение 180 дней (текущий рекомендуемый параметр Microsoft). В более старых версиях значение по умолчанию — 60 дней. Обработка значения свойства tombstoneLifetime — то, на что действительно стоит обратить внимание. Если свойство существует, время жизни надгробного камня будет соответствовать заданному в нём значению. Но только в том случае, если это значение не меньше, чем 2. А если меньше, то по умолчанию время жизни будет 60 дней (для Windows Server от 2000 до 2008) или 2 дня (Windows Server 2008 R2 или выше). Если значение свойства не задано, то время жизни будет 60 дней.

Если Вам интересно, каково значение tombstoneLifetime в Вашем окружении, данный PowerShell-скрипт выдаст его Вам (для его работы требуются инструменты AD DS и AD LDS):

(Get-ADObject -Identity "CN=Directory Service,CN=Windows NT,CN=Services,$((Get-ADRootDSE).configurationNamingContext)" -Properties *).tombstoneLifetime

Как только объект провёл в контейнере «Deleted Objects» количество дней, равное значению tombstoneLifetime, он логически удаляется сборщиком мусора Active Directory. В этот момент он уходит от нас навсегда и восстановлению больше не подлежит.

В качестве альтернативы я бы предложил разрабатываемое нами программное решение, как раз направленное на разрешение этой существенной проблемы. StealthRECOVER восстанавливает удалённые объекты в любое зарезервированное до момента их удаления состояние. Оно также способно восстановить объекты, превысившие установленное для леса время tombstoneLifetime.

Восстановление объектов Active Directory с использованием корзины

Выше мы обсуждали прелести восстановления объектов Active Directory в окружении без корзины AD (AD Recycle Bin). Если Вы пропустили этот пост, я настоятельно рекомендую Вам вернуться и прочитать его, поскольку это, пожалуй, самый замечательный пост в блоге, который я когда-либо писал о восстановлении объектов Active Directory в среде без корзины AD. Если коротко, при удалении объекта Active Directory в домене без корзины он становится «надгробным камнем». Этот объект, лишённый большинства своих атрибутов, затем находится в контейнере «Deleted Objects» раздела Active Directory на время, установленное в параметре tombstoneLifetime домена. В течение этого периода объект технически поддаётся восстановлению, но его утраченные атрибуты в общем случае можно считать невосстановимыми. При превышении «надгробным камнем» времени tombstoneLifetime сборщик мусора отправит объект в небытие. Совсем коротко этот процесс выглядит так:

Резервирование и восстановление в Active Directory

Корзина Active Directory была представлена в Windows Server 2008 R2. Целью данного функционала было облегчить восстановление удалённых объектов Active Directory без необходимости восстановления из резервных копий, перезапуска доменных служб Active Directory или перезагрузки контроллеров домена. Для достижения этой цели корзина AD вносит изменение в жизненный цикл удалённых объектов Active Directory.

Фундаментальное изменение, представленное корзиной Active Directory, относится к управлению атрибутами удалённого объекта. После включения корзины AD большинство атрибутов удалённого объекта, включая его ссылочные атрибуты, сохраняются в течение определённого периода времени. Данное изменение существенно упрощает процесс полного восстановления удалённых объектов в состояние, в котором они находились непосредственно перед удалением.

Объекты в этом новом восстанавливаемом состоянии называются «удалёнными объектами» («deleted object»), а период времени, в течение которого они сохраняют свои атрибуты, определяется в новом атрибуте msDS-DeletedObjectLifetime. При включении корзины AD значение атрибута msDS-DeletedObjectLifetime по умолчанию соответствует значению атрибута tombstoneLifetime. Если значение атрибута msDS-deletedObjectLifetime является нулевым, либо этот атрибут вообще отсутствует, его значение интерпретируется как эквивалентное значению атрибута tombstoneLifetime. Если также отсутствует и значение tombstoneLifetime, то оба они по умолчанию считаются равными 60 дням.

Если время пребывания объекта в статусе «удалённый объект» превышает период, указанный в msDS-DeletedObjectLifetime, то объект отправляется на переработку. Переработанный объект («recycled object») подозрительно похож на «надгробный камень» у которого появился атрибут isRecycled, установленный в TRUE. Как и у «надгробного камня» большинство из его атрибутов удаляются, и он присутствует в Active Directory в течение времени tombstoneLifetime, после чего зачищается сборщиком мусора Active Directory.

Упрощённо жизненный цикл удалённого объекта при включённой корзине AD выглядит так:

Теперь, когда у нас есть общее представление о поведении удалённых объектов в среде с корзиной AD, давайте воспользуемся утилитой LDP и поближе познакомимся с моей подопытной учётной записью.

Как видите, благодаря чудесам PowerShell-скрипта, создавшего, а затем и оживившего нашего пользователя, у нас есть множество заполненных атрибутов.

Теперь после удаления этого объекта мы можем наблюдать существенную разницу, ведь в состоянии «удалённый объект» большинство его атрибутов сохранилось.

Итак, в результате удаления объекта произошли следующие изменения:

  1. Объект был перемещён.
    Как и в нашем предыдущем эксперименте без использования корзины, объект был перемещён в контейнер «Deleted Objects» раздела каталога.
  2. Объект был переименован.
    Как и в прошлый раз, имя объекта было обновлено по тому же шаблону Common-Name\0ADEL:Object-Guid.
  3. У объекта появилось несколько новых атрибутов.
    И снова у нас появился атрибут isDeleted со значением TRUE, а также соответствующим образом заполненный атрибут lastKnownParent с (хотя в данном случае он уже был заполнен в результате удаления и восстановления объекта, которое мы проводили в прошлом эксперименте). Новый атрибут msDS-LastKnownRDN заполняется последним относительным уникальным именем (RDN) объекта. Этот атрибут позволяет корзине AD правильно переназначить RDN объекта при его восстановлении даже в том случае, если переименование объекта привело к усечению его исходного RDN.
  4. Два атрибута были удалены.
    Благодаря корзине AD, было утрачено только два атрибута: objectCategory и sAMAccountType. Фактически, при удалении объекта эти два атрибута всегда удаляются из него, независимо от работы корзины или наличия флага поиска 0x8 ( PRESERVE_ON_DELETE ). При восстановлении объекта значение атрибута objectCategory автоматически устанавливается в наиболее подходящее для объектного класса (атрибут objectClass) данного объекта, а значение sAMAccountType вычисляется на основании либо значения атрибута userAccountControl (для объектов пользователей), либо значения атрибута groupType (для объектов групп).
    Внимательные читатели могут также отметить, что на приведённом скриншоте нет ещё и атрибутов manager и memberOf. На самом деле они просто прячутся. Оба этих типа атрибута имеют так называемые ссылочные значения (то есть они содержат ссылки на другие объекты), и LDAP не возвращает деактивированные ссылки, если не был задан элемент управления с говорящим названием «Return Deactivated Links». Если бы я включил этот элемент управления, атрибуты и их значения были бы видны на моём скриншоте, но тогда я бы упустил случай упомянуть об этом поучительном моменте.

 

Перейдём к процессу восстановления объекта корзины AD. Хотя выгод от корзины AD довольно много, изначально работа с ней была затруднена тем, что её было относительно сложно использовать. До Windows Server 2012 для просмотра содержимого корзины требовалось использовать инструмент LDAP или PowerShell. Например, вот такой PowerShell-запрос возвращает всё удалённые объекты в домене:

Get-ADObject -filter 'isDeleted -eq $true -and name -ne "Deleted Objects"' -includeDeletedObjects

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

Можно использовать дополнительные фильтры, чтобы уменьшить диапазон запроса и, следовательно, количество возвращаемых удалённых объектов. Но Вы наверняка представляете себе, как могут выглядеть результаты этого запроса в реальной производственной среде.

Предположим, что объект, который Вы хотите восстановить, найден. Тогда для его восстановления можно использовать такой запрос:

Restore-ADObject -Identity '562f229c-e03a-4005-a098-10046e9b8942'

Для указания объекта, который я пытаюсь восстановить, задаю его идентификатор ObjectGUID в параметре Identity. Можно было бы поступить и по-другому: напрямую передать результаты запроса Get-ADObject через конвейер командлету Restore-ADObject.

В этом была своя прелесть: если бы корзину AD не было так сложно использовать, было бы труднее проникнуться всей полнотой её полезности. К счастью, после получения Microsoft множества недовольных отзывов от сообщества пользователей, они упростили работу, добавив в Windows Server 2012 функционал корзины в Центр администрирования Active Directory (Active Directory Administrative Center, ADAC).

Давайте заглянем в контейнер «Deleted Objects» с помощью ADAC:

Как видите, те же четыре объекта, которые вернул мой PowerShell-запрос, представлены в гораздо более дружественном для пользователя интерфейсе. Также имеется возможность простой генерации фильтров для ограничения количества отображаемых пользователю объектов, а в списке задач (Tasks) правой части окна предусмотрен пункт Restore. Сейчас я по нему кликну, а затем снова зайду в LDP, чтобы посмотреть на наш свежевосстановленный объект.

Здорово, правда?

Однако перед тем, как все побегут включать корзину Active Directory, необходимо предупредить о непосредственных и потенциально вредных последствиях этого шага:

  1. Включение корзины Active Directory влечёт за собой изменение схемы данных каталога.
    В результате такого изменения схемы становится невозможно отключить корзину, не прибегая к полному восстановлению леса. Другими словами, если Вы включите корзину, отключить её Вы уже не сможете.
  2. Active Directory станет немного больше.
    После включения корзины AD удалённые объекты сохранят все свои атрибуты до истечения срока своего пребывания в статусе «удалённый объект». И вообще, время нахождения объекта в каталоге увеличится вдвое (на период пребывания в статусе «надгробного камня»). За счёт обоих этих факторов Active Directory будет использовать немного больше дискового пространства, чем раньше.
  3. Корзина не может работать ретроспективно.
    Из этого есть очень серьёзное следствие: в момент включения корзины AD все «надгробные камни» в лесу перестают существовать. Если Вы злорадны, можете поискать в Интернете «удалённые объекты, исчезнувшие после включения корзины». Для весьма немалого количества людей знания об этом конкретном следствии стало запоздалым и неприятным откровением.

Хотя мы и должны были об этом предупредить, ни одна из этих проблем не является настолько серьёзной, чтобы перевесить преимущества от включения корзины AD. Но мы также должны отметить, что StealthRECOVER работает как с включённой, так и не с включённой корзиной Active Directory, и предоставляет дополнительный уровень защиты за счёт способности восстанавливать из резервных копий объекты, которые превысили период mdDS-DeletedObjectLifetime своего леса, и более не могут быть восстановлены с помощью корзины AD.

Выполнение отката значений и восстановления атрибутов объекта Active Directory

В начале истории перед нами возникает ещё не набивший достаточного количества шишек IT-специалист, недавно взявшийся за изучение PowerShell. Заметив, что в большинстве учётных записей пользователей домена нет никакой информации о почтовом адресе, наш главный герой быстро приходит к пониманию, что у него есть прекрасная возможность использовать свои зарождающиеся сверхспособности в области написания сценариев.

Затем наш герой решает, что наилучшим решением в данной ситуации будет сначала идентифицировать все учётки, у которых отсутствуют атрибуты адреса, а затем обновить эти объекты, указав в незаполненных атрибутах почтовый адрес главного офиса их организации. Это всё-таки лучше, чем ничего, верно? Усилия нашего героя вылились в следующий скрипт:

Get-ADUser -Filter {streetAddress -ne '*'} | Set-ADUser -streetAddress '123 Main Street' -l 'Madison' -st 'Wisconsin' -postalCode '53701'

К несчастью для нашего вундеркинда PowerShell, используемый в фильтре оператор -ne является оператором равенства. Эта невинная оплошность вкупе с необъяснимой беспечностью, в результате которой скрипт не был протестирован (впрочем, необходимой, чтобы наш поучительный пример имел хоть какой-то шанс) привели к созданию сценария PowerShell, применимого лишь для обновления всех адресных атрибутов в каждом объекте пользователя в домене, у которого значение атрибута streetAddress явно не соответствует символу «звёздочка».

Да, неловко получилось…

Хотя описываемые события являются исключительно плодом разыгравшегося воображения автора и любые совпадения случайны, они иллюстрируют ситуацию, когда возникает необходимость восстановления значений ряда атрибутов в большом количестве объектов Active Directory.

В предыдущей заметке этой серии мы обсуждали корзину Active Directory, позволяющую сохранять значения атрибутов объекта в течение определённого периода времени. К сожалению, этот период времени начинается только с момента удаления объекта, а это означает, что в данной ситуации корзина Active Directory ничем нам не поможет.

На самом деле Active Directory вообще не хранит значения изменяемых атрибутов, а значит в нём нет никакого решения для подобного сценария восстановления. Я представляю, что технически Вы можете попытаться построить процесс восстановления на основании надежды на быстрое обнаружение любых нежелательных изменений, чтобы затем найти контроллер домена, который ещё не получил эти изменения посредством репликации, и сделать его объекты авторитетными. Это похоже на построение планов на пенсию, первым пунктом которых значится выигрыш крупной суммы денег в лотерею.

Поскольку Active Directory не ведёт хронологическую запись значений атрибутов объекта, первым шагом на пути к решению этой проблемы будет найти что-то, что делает это. К счастью, в инструментах создания резервных копий Active Directory недостатка нет.

Один из вариантов — использовать инструмент Microsoft’s Windows Server Backup («WBADMIN»). При инсталляции функционала резервного копирования Windows Server (Windows Server Backup) будет установлен инструмент командной строки wbadmin.exe. Кроме того, станут доступны командлеты Windows PowerShell для Windows Server Backup, а также MMC-оснастка Windows Server Backup.

Все три указанных варианта — это просто разные способы использования одного и того же базового приложения, соответственно, резервная копия, созданная одним из них, будет восприниматься и всеми остальными.

При работе с WBADMIN следует помнить одну важную тонкость: при его настройке на хранение резервных копий в определённой папке, там сохраняется только самая последняя версия резервной копии. Последующие резервные копии перезаписывают содержимое предыдущей резервной копии, что добавляет некоторую сложность в управлении процессом резервного копирования.

Ничего не мешает сделать batch-скрипт, который будет создавать внутри заданного UNC-пути папку с именем, сформированным на основе текущей даты в формате YYYYMMDD, а затем выполнять в эту папку резервирование файла Active Directory ntds.dit с помощью команды START BACKUP инструмента WBADMIN:

@echo off
set backupRoot=\\FILESHARE\NtdsBackups\
set backupFolder=%date:~-4,4%%date:~-10,2%%date:~7,2%
set backupPath=%backupRoot%%backupFolder%
mkdir %backupPath%
wbadmin start backup -backuptarget:%backupPath% -include:C:\Windows\NTDS\ntds.dit -quiet

В результате такой операции вы получите VSS-снапшот (Volume Shadow Copy Service) файла ntds.dit. Из недостатков данного подхода можно отметить то, что в результате создаётся файл, по размерам значительно превышающий исходные файлы: в моей лаборатории ntds.dit занимает 20 Мбайт, а полученный снапшот гораздо больше 20 Мбайт. В лабораторных условиях это не имеет принципиального значения, но в производственной среде может приводить к значительному расходу дискового пространства.

Другой вариант решения от Microsoft — NTDSUTIL.exe, утилита командной строки для доступа и управления базой данных Windows Active Directory. NTDSUTIL — экстремально мощный инструмент, и Ваше рабочее окружение — неподходящее место для изучения его возможностей. Набор полезных команд его невероятно широк, но в рамках данной заметки нас интересует команда SNAPSHOT, которая фиксирует состояние Active Directory на момент создания снапшота:

Большим недостатком данного подхода является то, что NDTSUTIL записывает резервные копии на тот же том, где размещается Active Directory, что не идеально.

Эти два варианта далеко не единственные, но с их помощью мы уже получили множество резервных копий на выбор для выполнения восстановления. Пришла пора открыть их и заглянуть внутрь. Для того чтобы сделать это мы воспользуемся инструментом Active Directory Domain Services Database Mounting Tool («DSAMAIN»). DSAMAIN позволяет монтировать файлы ntds.dit, прячущиеся в наших резервных копиях, после чего мы можем исследовать их с помощью LDAP.

Начнём с одного из VHD-образов, созданных WBADMIN. В первую очередь нужно найти один из наших VHD, смонтировать его и назначить буквенный идентификатор диска его первичному разделу.

Затем нам нужно определить путь к файлу ntds.dit в смонтированной резервной копии, открыть командную строку с правами администратора и выполнить следующую команду для монтирования этого файла ntds.dit:

dsamain -dbpath "E:\Windows\NTDS\ntds.dit" -ldapport 10389

При закрытии окна командной строки DSAMAIN остановится, так что не закрывайте её пока не закончите процедуру восстановления.

А теперь, когда мы подключили каталог из резервной копии WBADMIN, смонтируем снимок, сделанный NTDSUTIL. Для этого откроем ещё один экземпляр командной строки с правами администратора и с помощью команды snapshot утилиты ntdsutil сначала просмотрим список наших резервных копий, смонтируем одну из них и скопируем путь к диску, назначенный утилитой NTDSUTIL.

Затем нам нужно найти путь к файлу ntds.dit внутри пути, назначенного NTDSUTIL, открыть ещё один экземпляр командной строки с правами администратора и с помощью следующей команды смонтировать нужный нам файл ntds.dit:

dsamain -dbpath "C:\$SNAP_201903261110_VOLUMEC$\Windows\NTDS\ntds.dit" -ldapport 20389

Смонтировав две разных резервных копии, можно приступать к экспериментам. Я поменял значение атрибута Description моего старого товарища — тестовой учётной записи Delete Q. Me.

Открыв PowerShell, мы можем с помощью командлета Get-ADUser взглянуть на нашего тестового пользователя. По умолчанию Active Directory ожидает подключения на порту 389. Вы наверняка обратили внимание, что смонтированные нами резервные копии ожидают соединения на портах 10389 и 20389. С помощью дополнительного параметра Server мы можем посмотреть как наш тестовый пользователь выглядит в живом каталоге и в обеих наших смонтированных резервных копиях.

Как видите, текущее значение атрибута Description — »Oops», а в обеих резервных копиях содержится предыдущее значение — »Demo User Account».

Мы можем использовать тот же PowerShell-командлет Get-ADUser так, чтобы с его помощью получить данные для восстановления нужного нам атрибута до значения, найденного в наших резервных копиях. Если мы получим копию объекта из одной из смонтированных резервных копий, мы можем использовать значение атрибута из неё для восстановления значения атрибута живого объекта:

$UserBackup = Get-ADUser -Identity dqme -Properties Description -Server dc01:10389
Set-ADUser -Identity dqme -Description $UserBackup.Description -Server dc01:389

На практике это выглядит так. Обратите внимание, что значение атрибута Description было восстановлено до значения, полученного из смонтированной резервной копии.

Как видите, всё не так плохо. Однако, необходимо отметить, что это было всё-таки лабораторное упражнение, затронувшее только один конкретный изменённый атрибут в одном конкретном объекте. Также нам было известно, в какой резервной копии находится информация, требуемая для операции восстановления. В реальном сценарии восстановления этот процесс может оказаться крайне непростым, особенно когда нужно всё делать в сжатые сроки. Данный сценарий восстановления — тот самый случай, когда инструмент типа StealthRECOVER может принести очень много пользы. Он позволяет делать снапшоты Active Directory по заданному расписанию, искать изменения среди множества снапшотов, и откатывать изменения на уровне объекта в целом или на уровне атрибута.

Резервирование и восстановление объектов групповых политик (GPO)

Вот и финальная заметка из серии о резервировании и восстановлении Active Directory, где мы обсудим резервное копирование и восстановление объектов групповых политик. Хотя технически групповые политики отделены от каталога Active Directory, эти два решения очень тесно связаны. Active Directory не только содержит все объекты пользователей и компьютеров, контролируемые групповыми политиками, но также предоставляет структуру, позволяющую применять данные политики к этим пользователям и компьютерам.

Резервное копирование и восстановление объектов групповых политик

Перед тем, как погрузиться в резервирование и восстановление объектов групповых политик (Group Policy Object, GPO), давайте, по сложившейся в этой серии заметок традиции, немного отвлечёмся, разбавив повествование некоторой справочной информацией об этих самых объектах групповой политики.

Создание объекта групповой политики в домене — сфера ответственности контроллера домена Active Directory с FSMO-ролью (Flexible Single Master Operator) эмулятора основного контроллера домена (PDC Emulator). В домене Windows NT было разрешено существование только одного доменного контроллера с возможностью записи данных, он назывался основным контроллером домена (Primary Domain Controller или PDC). Это было следствием архитектуры репликации Windows NT с единственным главным сервером. В противовес этому, Active Directory использует архитектуру с несколькими главными серверами, в которой все доменные контроллеры могут иметь возможность записи данных. Роль эмулятора PDC в Active Directory была разработана как часть стратегии упрощения миграции доменов Windows NT в Active Directory.

Эмулятор PDC имитирует поведение основного контроллера домена Windows NT как единственного главного сервера, делая его идеально подходящим для выполнения определённых функций, таких как минимизация возможности добавления конфликтующих GPO. Он также выполняет ряд столь же важных функций в домене: служит авторитетным источником для синхронизации времени и отвечает за фиксацию и репликацию особенно важной информации, например, при смене пароля.

При создании нового объекта групповой политики эмулятор PDC назначает идентификатор GUID, который используется для именования каждого из двух компонентов, составляющих объект групповой политики. Это гарантирует, что каждый объект групповой политики может быть уникально идентифицирован. Кроме того, это помогает защитить две групповые политики по умолчанию: Политику домена по умолчанию (Default Domain Policy) и Политику контроллеров домена по умолчанию (Default Domain Controllers Policy). Обе они именуются с использованием общеизвестных идентификаторов GUID: Политика домена по умолчанию всегда {31B2F340-016D-11D2-945F-00C04FB984F9}, а Политика контроллеров домена по умолчанию всегда {6AC1786C-016F-11D2-945F-00C04fB984F9}.

Первый компонент объекта групповой политики — шаблон групповой политики (Group Policy Template, GPT), состоящий из набора директорий внутри общей папки SYSVOL («C:\Windows\SYSVOL\domain\Policies\{GUID}\»). Эти директории используются для хранения большей части содержимого объекта групповой политики (например, шаблонов, настроек, сценариев, сведений о пакетах MSI и т. д.). GPT реплицируются на каждый контроллер домена с помощью Службы репликации файлов (File Replication Service, FRS) или Репликации распределенной файловой системы (Distributed File System Replication, DFSR) в зависимости от версии Windows. Фактически, объекты групповой политики имеют эффект лишь в пределах домена, поскольку SYSVOL реплицируется только внутри домена.

Второй компонент объекта групповой политики — контейнер групповой политики (Group Policy Container, GPC), представляющий собой объект Active Directory groupPolicyContainer, располагающийся в ветке CN=System,CN=Policies в контексте именования домена. Атрибуты этого объекта используются для хранения справочной информации, относящейся к объекту групповой политики. В частности, в атрибуте gPCFileSysPath содержится путь к шаблону GPT объекта групповой политики в SYSVOL. В отличие от GPT, GPC реплицируется Доменными службами Active Directory (Active Directory Domain Services) в соответствии с настроенными стоимостью, расписанием и интервалом репликации.

После создания объекта групповой политики его можно связать с одним или несколькими объектами Active Directory. Эта связь поддерживается не на уровне объекта групповой политики, а в каждом объекте Active Directory, связанном с данным объектом групповой политики.

Такие связи являются внешними по отношению к самому GPO и содержатся в атрибуте gPLink, доступном в трёх классах объектов Active Directory: Organizational Unit («OU»), Domain и Site. Значение атрибута gPLink представляет собой список путей к GPC каждого объекта групповой политики, с которым связан данный объект. При создании или удалении связи GPO с каким-либо объектом фактически модифицируется только значение атрибута gPLink соответствующего объекта.

(Примечание: Хотя репликация SYSVOL ограничивает эффект применения объекта групповой политики лишь конкретным доменом, тот факт, что объекты групповой политики могут быть связаны с объектом узла (Site), означает, что информация, связанная с объектом групповой политики, не обязательно ограничена доменом. Объекты узла хранятся в разделе Configuration Active Directory, который реплицируется на все контроллеры домена в лесу. В результате этого путь к GPC объекта групповой политики, содержащийся в атрибуте gPLink, так или иначе выводится за рамки конкретного домена во время репликации Active Directory.)

Порядок обработки групповой политики

Объекты Organizational Unit, Domain и Site также играют важную роль при определении приоритета применения политик в ситуациях, когда имеются конфликтующие друг с другом политики.

Active Directory применяет GPO в следующем порядке: локальные политики, политики узла, политики домена, политики контейнера OU, причём «побеждает» последняя применяемая групповая политика (если не была использована опция «Enforce», предотвращающая переопределение групповой политики со стороны следующих применяемых групповых политик). Групповые политики, привязанные к контейнерам Organizational Unit, обрабатываются, начиная с корня дерева каталога, поэтому объект групповой политики, связанный с вложенным контейнером OU, будет иметь приоритет над объектом групповой политики, связанным с его родительским контейнером OU.

И последнее, на что следует обратить внимание: объекты групповой политики содержат две подгруппы: Конфигурация компьютера (Computer Configuration) и Конфигурация пользователя (User Configuration). В обеих подгруппах находятся практически идентичные наборы параметров политики. Принципиальное различие между каждой из подгрупп заключается в том, когда эти параметры политики применяются.

Параметры конфигурации компьютера применяются к компьютерам во время загрузки, а параметры конфигурации пользователя применяются при входе в систему. Это означает, что параметры в подгруппе Конфигурация компьютера групповой политики всегда применяются к связанным с этой политикой компьютерам, а параметры в подгруппе Конфигурация пользователя применяются только тогда, когда пользователь c учётной записью, связанной с этой политикой, входит в систему на компьютере.

Если пользователь вошёл в систему на каком-то компьютере и возник конфликт между параметрами Конфигурации компьютера и Конфигурации пользователя, то параметры Конфигурации компьютера всегда будут превалировать над параметрами Конфигурации пользователя.

Ну а теперь давайте вернёмся к нашей основной теме и обсудим резервное копирование и восстановление объектов групповой политики.

Начнём с командлетов PowerShell Group Policy, доступных как часть пакета Windows Remote Server Administration Tools от Microsoft, включающего в себя командлеты Backup-GPO и Restore-GPO. С помощью командлета Backup-GPO очень просто создать снапшот как всех объектов групповой политики в домене, так и одного конкретного объекта групповой политики. Командлет Restore-GPO может восстановить объект групповой политики до его состояния, зафиксированного в резервной копии, созданной командлетом Backup-GPO.

В следующем PowerShell-скрипте используется командлет Backup-GPO с параметром -All для создания резервных копий всех GPO в домене с явно заданным именем с использованием контроллера домена, который также указан явно. Поддерживается многократное резервное копирование в одно и то же место, но в данном случае при каждом выполнении скрипта создаётся уникальная папка для выгрузки данных:

$BackupPath = '\\HOSTNAME\GPOBackup\'
$Domain = 'domain.com'
$DomainController = 'DC.domain.com'

$BackupFolder = New-Item -Path $BackupPath -Name (Get-Date -format yyyyMMddTHHmmss) -ItemType Directory
Backup-GPO -All -Domain $Domain -Server $DomainController -Path $BackupFolder

Выгружаемые данные командлета Backup-GPO состоят из отдельных подпапок для резервной информации каждого GPO, а также файла manifest.xml, содержащего информацию, необходимую для связывания каждой из этих подпапок с соответствующими объектами групповой политики.

Подпапки именуются с использованием специфичных для резервной копии идентификаторов GUID, генерируемых во время выполнения командлета, что практически исключает вероятность возникновения конфликта имён в результате многократного резервного копирования в одно и то же место.

Заглянув внутрь одной из таких подпапок, мы обнаружим, что каждая резервная копия состоит из одной папки и трёх XML-файлов.

Резервирование и восстановление в Active Directory

В папке содержится копия GPT объекта групповой политики, а XML-файлы содержат данные из GPC объекта групповой политики, информацию, относящуюся к выполнению резервного копирования, а также отчёт, который описывает содержимое объекта групповой политики.

Как уже упоминалось выше, разделение выгружаемых данных при каждом выполнения скрипта на уникальные папки не является строго необходимым. Однако такая стратегия создает преимущество при выполнении командлета Restore-GPO. Командлет Restore-GPO позволяет восстановить все GPO сразу, но он будет использовать самую последнюю резервную копию каждого из объектов групповой политики согласно информации из файла manifest.xml. При разделении наборов резервных копий по отдельным папкам, каждый такой набор получает свой собственный файл manifest.xml. Это позволяет выполнить восстановление всех GPO из любого такого набора за одну операцию.

Недостатком использования параметра -All командлета Backup-GPO в приведённом выше сценарии является то, что он производит резервное копирование всех объектов групповой политики в домене, независимо от того, были они изменены или нет, при каждом его исполнении.

Поскольку мы работаем с PowerShell, мы можем попытаться обойти эту проблему, например, так, как представлено ниже:

$BackupPath = '\\HOSTNAME\GPOBackup'
$Domain = 'domain.com'
$DomainController = 'DC.domain.com'

if((Test-Path "$BackupPath\lastBackup")) {
    $LastBackup = Get-Content -Path "$BackupPath\lastBackup"
    Set-Content -Path "$BackupPath\lastBackup" -Value (Get-Date)
    $GPOs = Get-GPO -All -Domain $Domain -Server $DomainController
    $GPOs | Where-Object { $_.ModificationTime -gt $LastBackup } | ForEach-Object {
        Backup-GPO -Guid $_.Id -Domain $Domain -Server $DomainController -Path $BackupPath
    }
}
else {
    Set-Content -Path "$BackupPath\lastBackup" -Value (Get-Date)
    Backup-GPO -All -Domain $Domain -Server $DomainController -Path $BackupPath
} 

В этом скрипте PowerShell командлет Backup-GPO выполняется дифференцировано в зависимости от содержимого файла, который создается в папке обновлений и хранит отметку времени последнего выполнения сценария. Если данный файл существует, скрипт создаёт резервные копии только тех GPO домена, которые были изменены позднее той отметки времени, которая хранится в файле. Если же данного файла не существует, скрипт создаёт его, помещает в него отметку времени, и создаёт резервные копии всех GPO домена.

Хотя данный подход экономит дисковое пространство за счёт ограничения количества ненужных копий, все созданные им резервные копии в итоге оказываются в одной папке, что затрудняет восстановление объектов групповой политики до состояния на определенный момент времени.

Ничто не мешает нам скомбинировать подходы из обоих скриптов и решить тем самым все наши проблемы:

$BackupPath = '\\HOSTNAME\GPOBackup'
$Domain = 'domain.com'
$DomainController = 'DC.domain.com'

$BackupFolder = New-Item -Path $BackupPath -Name (Get-Date -format yyyyMMddTHHmmss) -ItemType Directory

if((Test-Path "$BackupPath\lastBackup")) {
    $LastBackup = Get-Content -Path "$BackupPath\lastBackup"
    Set-Content -Path "$BackupPath\lastBackup" -Value (Get-Date)
    $GPOs = Get-GPO -All -Domain $Domain -Server $DomainController
    $GPOs | Where-Object { $_.ModificationTime -gt $LastBackup } | ForEach-Object {
        Backup-GPO -Guid $_.Id -Domain $Domain -Server $DomainController -Path $BackupFolder
    }
}
else {
    Set-Content -Path "$BackupPath\lastBackup" -Value (Get-Date)
    Backup-GPO -All -Domain $Domain -Server $DomainController -Path $BackupFolder
} 

Но оказывается, что изоляция каждого из результатов дифференцированного резервного копирования в их собственных папках на самом деле делает всё намного хуже. Ведь при данном подходе также изолируются в отдельных папках и файлы manifest.xml, что с одной стороны лишает нас возможности одновременного восстановления всех объектов групповой политики, а с другой стороны значительно усложняет процесс поиска резервной копии, связанной с каким-либо конкретным объектом групповой политики.

На практике некоторые ограничения, с которыми сталкиваются рассмотренные нами подходы, — это ограничения, накладываемые относительно скромными возможностями командлета Restore-GPO.

# Восстановление одного GPO из его самой последней резервной копии
Restore-GPO -Name 'GpoName' -Path '\\HOSTNAME\GPOBackup' -Domain 'domain.com' -Server 'DC.domain.com'

# Восстановление одного GPO из конкретной резервной копии
Restore-GPO -BackupId 12345678-09ab-cdef-1234-567890abcdef -Path '\\HOSTNAME\GPOBackup' -Domain 'domain.com' -Server 'DC.domain.com' 

# Восстановление всех GPO домена из их самой последней резервной копии
Restore-GPO -All -Path '\\HOSTNAME\GPOBackup' -Domain 'domain.com' -Server 'DC.domain.com'

Restore-GPO может восстанавливать конкретный объект групповой политики либо из самой последней резервной копии, указанной в файле manifest.xml, либо из заданной резервной копии. Но восстановление всех GPO домена сразу ограничено использованием самых последних резервных копий из указанного файла manifest.xml.

Когда объект групповой политики восстанавливается из резервной копии, версия этого объекта увеличивается (то есть увеличение версии — часть процесса восстановления).

Резервирование и восстановление в Active Directory

Данное увеличение версии предусмотрено для того, чтобы при репликации предпочтение отдавалось восстановленной копии объекта групповой политики.

Придётся нам ещё немного отвлечься.

Вывод командлета Restore-GPO включает два набора номеров версий: один для Конфигурации компьютера, второй — для Конфигурации пользователя.

GPT и GPC раздельно ответственны за поддержание своего собственного номера версии, причём отдельные значения UserVersion и ComputerVersion рассчитываются на основе соответствующих номеров версий Конфигурации пользователя и Конфигурации компьютера. Это становится возможным из-за применяемого метода увеличения номера версии. Он увеличивается на 1 при изменении Конфигурации компьютера объекта групповой политики, и на 65536 каждый раз при изменении Конфигурации пользователя.

Всё это важно, поскольку, как обсуждалось ранее, GPT и GPC объектов групповых политик реплицируются отдельно друг от друга разными сервисами, в результате чего номера версий GPT и GPC какой-либо групповой политики на каком-то контроллере домена могут оказаться рассинхронизированными (не совпадать). Пока объект групповой политики находится в этом состоянии, при его обработке будет возникать сбой. После того, как номера версий придут в состояние синхронизации, GPO вновь будут успешно обрабатываться.

А мы вновь возвращаемся к нашему повествованию.

Задокументированное ограничение командлета Restore-GPO — то, что он не может быть использован для восстановления объекта групповой политики, который был удалён. Попытка сделать это приведёт к примерно такой ошибке:

Резервирование и восстановление в Active Directory

Причина, по которой работа командлета Restore-GPO завершается неудачей в данной ситуации — то, что он не может найти компонент GPC объекта групповой политики в каталоге Active Directory.

Если Вы сможете сначала восстановить GPC, то тогда Restore-GPO фактически может быть использован для восстановления объекта групповой политики. Посмотрите:

Резервирование и восстановление в Active Directory

Когда GPC снова на месте (в последнем примере для полного восстановления компонента объекта групповой политики, хранящегося в Active Directory, из корзины Active Directory был использован командлет Restore-ADObject), командлет Restore-GPO способен восстановить GPO.

Хотя с помощью данного процесса можно восстановить удалённый GPO, но при этом не получится восстановить значения gPLink, существовавшие до того, как этот GPO был удалён. Всё потому, что, как мы уже упоминали, данные значения не были частью объекта групповой политики, а находились в самих связанных с этим GPO объектах каталога. Единственный безопасный способ обойти это ограничение — использовать отдельно созданные резервные копии Active Directory, содержащие данные значения gPLink.

Кроме командлетов PowerShell для работы с объектами групповой политики, Microsoft также предлагает Консоль управления групповыми политиками (Group Policy Management Console, GPMC), оснастку MMC, которая может использоваться для резервного копирования и восстановления объектов групповых политик. Как и командлет Backup-GPO, она может создавать резервные копии как отдельного заданного объекта групповой политики, так и всех GPO домена. В отличие от командлета Restore-GPO, её возможности ограничены восстановлением единственного GPO за раз.

GPMC предоставляет метод восстановления удалённого объекта групповой политики из резервной копии. Но на самом деле он не восстанавливает удалённый GPO, а просто создаёт новый и заполняет его параметры, используя информацию из резервной копии.

Ещё одним преимуществом GPMC является улучшенная наглядность представления содержимого резервных копий GPO, хотя по-прежнему сложно сравнивать параметры, содержащиеся в резервной копии, с текущими параметрами действующего объекта групповой политики.

Инструмент Microsoft Расширенное управление групповой политикой (Advanced Group Policy Management, AGPM), доступный как часть пакета Microsoft Desktop Optimization Pack, дополняет функциональные возможности GPMC за счёт внедрения в неё функции контроля версий. Это помогает расширить возможности просмотра и понимания содержимого созданных резервных копий.

Однако преимущества AGPM нивелируются с одной стороны тем, что он не очень-то хорошо поддерживается, а также тем, что он, по-видимому, плохо совместим с другими инструментами (например, модификация GPO, управляемого AGPM, произведённая за рамками AGPM, может привести к разрушению базы данных AGPM).

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

Возможно вам будет интересно — Подборка программ — инструментов для системного администратора

источник