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-* | Когда |
|---|---|---|
| A | Add-DnsServerResourceRecordA | Имя → IPv4 |
| AAAA | Add-DnsServerResourceRecordAAAA | Имя → IPv6 |
| CNAME | Add-DnsServerResourceRecordCName | Алиас |
| MX | Add-DnsServerResourceRecordMX | Почтовый сервер |
| TXT | Add-DnsServerResourceRecordTxt | SPF, DKIM, verification |
| SRV | Add-DnsServerResourceRecord (-Srv) | Сервисные SRV |
| PTR | Add-DnsServerResourceRecordPtr | Reverse 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 рублей, и самое главное — ни одной жалобы от пользователей! Разве это не показатель? Кстати, сопровождение этого клиента продолжаем до сих пор.
Полезные командлеты, которые экономят время
Get-DnsServerStatistics— полная статистика queries, recursion, zone transfers.Set-DnsServerResponseRateLimiting— RRL для защиты от DNS amplification DDoS.Register-DnsClient— принудительная регистрация клиентом своего A в зоне.Get-DnsServerDsSetting— настройки репликации AD-integrated зон.Set-DnsServerGlobalQueryBlockList— блокировка wpad/isatap для безопасности.
Поможем автоматизировать 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 — основные инструменты.
