Недавно для настройки представлений на серверах Bind мне потребовалась выгрузка DNS-записей с серверов Windows. Несмотря на очевидную простоту задачи на деле все оказалось далеко не так просто и быстро.
Пока разбирался каким образом решать задачу и собрал все подводные камни, натолкнулся на множество интересных статей и ресурсов. Обязательно с вами поделюсь.
Если вам интересны статьи о Powershell, рекомендую обратиться к тегу PowerShell scripting на моем блоге
Выгрузка DNS-записей
Кому сразу нужен код/команды – листайте до пункта Скрипт, а пока разберем саму задачу и теорию.
Задача
Есть сервер Windows с ролью DNS. Есть сервер Bind на Linux с настроенными для различных клиентов представлениями. Нужно с сервера Windows выгрузить (крайне желательно в формате, который знает Bind 1) все записи определенной зоны и засунуть в Bind. Вручную копировать не вариант, записей сотни.
Теория
Выгрузить записи нужной вам зоны (или всех зон враз, почему бы и нет) роли Windows Server DNS можно разными путями. Вот основные.
1. Например записи неинтегрированных в AD зон можно просто скопировать из соответствующих файлов в директории C:\Windows\System32\dns. Для AD-integrated зон такой вариант не подойдет.
2. Вполне можно воспользоваться старой доброй утилитой dnscmd, например:
Где dc01.dns_zone.local и dns_zone.local имена контроллера домена и нужной вам зоны соответственно. Тем не менее, эта утилита уже достаточно стара и использовать её – не самый лучший вариант.
3. Самый разумный вариант на текущий момент – использовать Powershell для выгрузки записей. Но этот вариант далеко не самый простой. Почему, рассмотрим ниже.
Скрипт
Для получения всех записей определенной зоны подойдет командлет Get-DnsServerResourceRecord 2. Пример его использования:
Получите подобный вывод (количество записей уменьшено для наглядности):
Многоточие в первой строчке явно намекает, что это сокращение. Этот вариант не подходит, попробуем ограничить выводимые столбцы и указать сортировку:
Уже лучше, но что стало со столбцом RecordData:
Подобный вывод говорит о том, что RecordData – отдельный объект со своими свойствами. Хорошо, проверим что он из себя представляет командой:
Вывод:
Теперь становится понятно, что нам нужно отдельно обрабатывать 3 каждую запись в зависимости от её типа 4. Для этого можно воспользоваться хэш-таблицей 5 6 и командлетом Select-Object 7:
Вот что получилось:
В примере выше я сделал сопоставление только для семи типов записей (потому что для моей задачи больше и не надо), но на деле их будет больше. Мне также было нужно, чтобы каждая запись была определена как fqdn, поэтому к полю HostName нужно добавить суффикс в виде домена. Не лишним также будет выгружать все записи в CSV. Вот как изменится скрипт:
На этом задача решена. Возможно будет логично засунуть этот кусок кода в цикл, если нужно перебирать записи сразу нескольких зон. Это вы уже сделайте сами при необходимости. Успехов!