· 15 мин чтения

DNS-зоны и записи в Windows Server через PowerShell: от разовых команд до массовой автоматизации

DNS-зоны и записи в Windows Server через PowerShell: от разовых команд до массовой автоматизации

Привет! На связи Семёнов Евгений Сергеевич, я директор ITFresh. Знаете, GUI dnsmgmt.msc — отличный инструмент, когда админ правит всего одну запись в неделю. Но вот что делать, если задача действительно масштабная? Например, нужно разом создать 50 A-записей из CSV-файла, или обновить TTL для целой зоны? А может, вообще мигрировать целых три зоны с одного контроллера домена на другой? Тут без PowerShell, поверьте, никак не обойтись. Самое приятное: модуль DnsServer, доступный в Windows Server 2016-2022, решает 95% подобных задач. И часто — одной-единственной строкой кода! Вот почему я и собрал для вас те самые команды, которыми сам пользуюсь вот уже 15 лет, работая с AD-сетями.

Подготовка рабочей станции

# На Windows Server с ролью DNS
Import-Module DnsServer
Get-Command -Module DnsServer | Measure-Object
# ~150 командлетов

# На Windows 10/11 (ставим RSAT DNS Tools)
Add-WindowsCapability -Online -Name "Rsat.Dns.Tools~~~~0.0.1.0"
Import-Module DnsServer

# Все команды работают с -ComputerName
Get-DnsServer -ComputerName dc01.corp.example.ru

Обзор состояния DNS-сервера

# Общие настройки
Get-DnsServerSetting -ComputerName dc01

# Список всех зон
Get-DnsServerZone -ComputerName dc01 |
  Select ZoneName, ZoneType, IsDsIntegrated, IsReverseLookupZone |
  Format-Table -AutoSize

# Forwarders
Get-DnsServerForwarder -ComputerName dc01

# Conditional forwarders
Get-DnsServerZone -ComputerName dc01 | Where ZoneType -eq "Forwarder"

# Root hints
Get-DnsServerRootHint -ComputerName dc01

Создание зон

# AD-integrated primary — для корпоративной сети в домене
Add-DnsServerPrimaryZone -Name "corp.example.ru" `
  -ReplicationScope Domain `
  -DynamicUpdate Secure

# Standalone primary (файловая) — для обособленных DNS без AD
Add-DnsServerPrimaryZone -Name "testlab.local" `
  -ZoneFile "testlab.local.dns" `
  -DynamicUpdate None

# Reverse-зона для 10.0.0.0/24
Add-DnsServerPrimaryZone -NetworkId "10.0.0.0/24" `
  -ReplicationScope Domain `
  -DynamicUpdate Secure

# Conditional forwarder для партнёрской сети
Add-DnsServerConditionalForwarderZone -Name "partner.ru" `
  -MasterServers 192.168.100.10, 192.168.100.11 `
  -ReplicationScope Domain

Работа с записями

ТипAdd-*Когда
AAdd-DnsServerResourceRecordAИмя → IPv4
AAAAAdd-DnsServerResourceRecordAAAAИмя → IPv6
CNAMEAdd-DnsServerResourceRecordCNameАлиас
MXAdd-DnsServerResourceRecordMXПочтовый сервер
TXTAdd-DnsServerResourceRecordTxtSPF, DKIM, verification
SRVAdd-DnsServerResourceRecord (-Srv)Сервисные SRV
PTRAdd-DnsServerResourceRecordPtrReverse lookup
# A-запись
Add-DnsServerResourceRecordA -Name "web01" `
  -ZoneName "corp.example.ru" `
  -IPv4Address "10.0.0.10" `
  -TimeToLive 01:00:00

# CNAME
Add-DnsServerResourceRecordCName -Name "www" `
  -ZoneName "corp.example.ru" `
  -HostNameAlias "web01.corp.example.ru"

# MX
Add-DnsServerResourceRecordMX -Name "@" `
  -ZoneName "corp.example.ru" `
  -MailExchange "mail.corp.example.ru" `
  -Preference 10

# TXT (SPF/DKIM)
Add-DnsServerResourceRecord -Txt `
  -ZoneName "corp.example.ru" `
  -Name "@" `
  -DescriptiveText "v=spf1 mx a:mail.corp.example.ru include:_spf.yandex.ru -all"

# PTR для reverse
Add-DnsServerResourceRecordPtr -Name "10" `
  -ZoneName "0.0.10.in-addr.arpa" `
  -PtrDomainName "web01.corp.example.ru"

Поиск и фильтрация записей

# Все записи одной зоны
Get-DnsServerResourceRecord -ZoneName "corp.example.ru"

# Только A-записи
Get-DnsServerResourceRecord -ZoneName "corp.example.ru" -RRType A

# Конкретное имя
Get-DnsServerResourceRecord -ZoneName "corp.example.ru" -Name "web01"

# Записи со старым TTL
Get-DnsServerResourceRecord -ZoneName "corp.example.ru" |
  Where TimeToLive.TotalHours -lt 1 |
  Select HostName, TimeToLive

Массовое создание из CSV

# CSV: Name,Type,Value,TTL
# web01,A,10.0.0.10,3600
# www,CNAME,web01.corp.example.ru,3600

$records = Import-Csv C:\Install\dns-bulk.csv
foreach ($r in $records) {
  switch ($r.Type) {
    'A' {
      Add-DnsServerResourceRecordA `
        -Name $r.Name -ZoneName "corp.example.ru" `
        -IPv4Address $r.Value `
        -TimeToLive (New-TimeSpan -Seconds [int]$r.TTL) -PassThru
    }
    'CNAME' {
      Add-DnsServerResourceRecordCName `
        -Name $r.Name -ZoneName "corp.example.ru" `
        -HostNameAlias $r.Value `
        -TimeToLive (New-TimeSpan -Seconds [int]$r.TTL) -PassThru
    }
  }
}

Обновление существующих записей

# Правка TTL и IP у A-записи
$old = Get-DnsServerResourceRecord -ZoneName "corp.example.ru" `
  -Name "web01" -RRType A
$new = $old.Clone()
$new.RecordData.IPv4Address = [IPAddress]"10.0.0.55"
$new.TimeToLive = New-TimeSpan -Hours 4

Set-DnsServerResourceRecord -NewInputObject $new `
  -OldInputObject $old -ZoneName "corp.example.ru"

# Массовое изменение TTL всей зоны
Get-DnsServerResourceRecord -ZoneName "corp.example.ru" -RRType A |
  ForEach-Object {
    $new = $_.Clone()
    $new.TimeToLive = New-TimeSpan -Hours 1
    Set-DnsServerResourceRecord -NewInputObject $new `
      -OldInputObject $_ -ZoneName "corp.example.ru"
  }

Удаление записей

# По имени
Remove-DnsServerResourceRecord -ZoneName "corp.example.ru" `
  -Name "oldserver" -RRType A -Force

# По записи
$rec = Get-DnsServerResourceRecord -ZoneName "corp.example.ru" -Name "web05"
$rec | Remove-DnsServerResourceRecord -ZoneName "corp.example.ru" -Force

Scavenging — уборка устаревших записей

# Включить scavenging на сервере
Set-DnsServerScavenging -ComputerName dc01 `
  -ScavengingState $true `
  -ScavengingInterval 7.00:00:00 `
  -RefreshInterval 7.00:00:00 `
  -NoRefreshInterval 7.00:00:00

# Включить для конкретной зоны
Set-DnsServerZoneAging -Name "corp.example.ru" `
  -ComputerName dc01 `
  -Aging $true

# Принудительно запустить сейчас
Start-DnsServerScavenging -ComputerName dc01 -Force

Есть одно железное правило, которому я всегда следую: включаю scavenging на зонах с DynamicUpdate. Иначе, поверьте, уже через пару лет зона превратится в настоящую помойку. Там плодятся тысячи мёртвых записей от давно уволенных сотрудников и списанных ноутбуков — кому это нужно?

Диагностика

# Проверка резолвинга
Resolve-DnsName www.corp.example.ru -Server dc01
Resolve-DnsName www.corp.example.ru -DnsOnly -NoHostsFile

# Интерактивная проверка сервера
Test-DnsServer -IPAddress 10.0.0.1 -ZoneName "corp.example.ru"

# Здоровье SYSVOL-репликации зон
dcdiag /test:dns /dnsall /s:dc01

# Включение расширенных логов
Set-DnsServerDiagnostics -ComputerName dc01 `
  -Queries $true -Answers $true `
  -Notifications $true `
  -Update $true -ReceivePackets $true `
  -SendPackets $true -TcpPackets $true -UdpPackets $true `
  -LogFilePath "C:\DNS\dns.log" -MaxMBFileSize 500MB

# Проверка кэша
Get-DnsServerCache -ComputerName dc01
Clear-DnsServerCache -ComputerName dc01 -Force

Экспорт и импорт зоны

# Экспорт зоны в файл (только для primary)
Export-DnsServerZone -Name "corp.example.ru" `
  -FileName "corp.example.ru.export" `
  -ComputerName dc01

# Файл оказывается в C:\Windows\System32\DNS\corp.example.ru.export

# Импорт зоны
Add-DnsServerPrimaryZone -Name "restored.local" `
  -ZoneFile "corp.example.ru.export"

Реальный кейс: миграция 4 зон на новые DC

Представьте: август 2025 года. К нам обращается ИТ-интегратор — их домену уже 12 лет, он всё ещё работает на Server 2012 R2. Наша задача была такой: поднять два новых контроллера домена на Server 2022. Разместить их нужно было в дата-центре МТС Москва, причём на нашем собственном оборудовании — мощных Dell Xeon Platinum 8280. Мы должны были перенести четыре AD-integrated DNS-зоны (это их основная корпоративная и три партнёрских), а затем безопасно, без даунтайма, отключить старые контроллеры домена.

Мы уложились ровно в два плановых окна. В первом наши инженеры поставили DC03 и DC04 в новом сайте, включили их в репликацию, а также добавили роли DNS. Приятный момент: AD-integrated зоны реплицировались абсолютно автоматически. После этого, конечно, мы всё тщательно проверили с помощью PowerShell.

# Серверы, где активна зона
Get-DnsServerZone -Name "corp.example.ru" -ComputerName dc03 |
  Select ZoneName, ReplicationScope, MasterServers

# Сверка количества записей
(Get-DnsServerResourceRecord -ZoneName "corp.example.ru" `
   -ComputerName dc03).Count
(Get-DnsServerResourceRecord -ZoneName "corp.example.ru" `
   -ComputerName dc01).Count

# Все клиенты, зарегистрировавшиеся в DNS за последние 7 дней
Get-DnsServerResourceRecord -ZoneName "corp.example.ru" -RRType A |
  Where TimeStamp -gt (Get-Date).AddDays(-7) |
  Measure-Object

Во второе окно мы обновили DHCP, чтобы он начал выдавать адреса новых контроллеров домена в качестве DNS-серверов. Затем мы мониторили систему целых 72 часа, убеждаясь в стабильности. Только после этого старые DC были выведены из AD. Итог? Весь проект занял 9 рабочих дней, обошёлся клиенту в 120 000 рублей, и самое главное — ни одной жалобы от пользователей! Разве это не показатель? Кстати, сопровождение этого клиента продолжаем до сих пор.

Полезные командлеты, которые экономят время

Поможем автоматизировать DNS в AD-сети

Я постоянно пишу PowerShell-скрипты, чтобы автоматизировать массовую работу с DNS, занимаюсь миграцией зон между серверами, а также настраиваю scavenging и мониторинг. Мой опыт в этой сфере — более 15 лет, и я работал с AD-доменами самого разного размера: от 30 до 800 рабочих мест. И, кстати, первичная консультация, а также оценка ваших задач — абсолютно бесплатны.

Телефон: +7 903 729-62-41
Telegram: @ITfresh_Boss
Семёнов Евгений Сергеевич, директор АйТи Фреш

FAQ — вопросы о Windows DNS и PowerShell

Какой модуль PowerShell нужен для DNS?
Модуль DnsServer, входит в состав RSAT DNS Server Tools и в Windows Server с ролью DNS.
Можно ли управлять удалённо не-DC сервером DNS?
Да, через параметр -ComputerName. Нужны права администратора и открытый RPC 135.
Как массово создать много A-записей?
Через импорт CSV и цикл с Add-DnsServerResourceRecordA. Для 500+ записей лучше делать в AD-integrated зону.
Чем отличаются primary и AD-integrated зоны?
Primary хранится в файле и реплицируется Zone Transfer. AD-integrated — в AD-партишене с нативной репликацией.
Как диагностировать проблемы с DNS?
Get-DnsServerDiagnostics, dcdiag /test:dns, Resolve-DnsName, Test-DnsServer — основные инструменты.

Подпишитесь на рассылку ITfresh

Хотите быть в курсе самых актуальных решений? Мы выпускаем практические гайды раз в неделю! Они подойдут и для руководителя IT, и для сисадмина. Внутри — всё самое важное: от безопасности и 1С до сложных миграций, резервных копий и лайфхаков, проверенных в наших реальных проектах. Никакой воды, только практика.

Реквизиты оператора персональных данных

ООО «АЙТИ-ФРЕШ», ИНН 7719418495, КПП 771901001. Юридический адрес: 105523, г. Москва, Щёлковское шоссе, д. 92, корп. 7. Контакт: info@itfresh.ru, +7 903 729-62-41. Оператор обрабатывает e-mail подписчика в целях рассылки информационных и рекламных материалов до момента отзыва согласия.