Backup & Restore Active Directory integrated DNS zones
DNS is one of the core components for Active Directory Domain Services. In a disaster scenario, it becomes impossible to locate resources within the network and all AD operations come to a screeching halt. Therefore, it’s absolutely necessary to restore the DNS servers. One way to set this right is by performing an AD DS authoritative restore by using Microsoft’s preferred method for backing up a DNS server by performing a system state backup. That process is a time-consuming and a complex process in which the domain controllers must be restarted for the changes to take effect also you will also end up restoring the Registry, Active Directory database and a number of other components. Eventually, it leads to increased downtime, which impacts productivity.
Luckily, it’s possible to back up a DNS server independently using PowerShell.
Backup:
For AD integrated zones, the support tool dnscmd.exe can get the job done. To back up any DNS zone with dnscmd.exe, you just need to use the /zoneexport switch with the command. To back up the Zone1.com zone locally on a DNS server, you’d run the below command on the DNS server:
1 |
dnscmd DC1 /zoneexport Zone1.com backup\zone1.com.dns.bak |
where DC1 is DNS server name, This command writes a copy of the Zone1.com zone to the %systemroot%\system32\dns\backup\Zone1.com.dns.bak file.
PowerShell Script to backup DNS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
#AD-DNS-Backup.ps1 #PowerShell 2.0+ required #Run this script locally on a DNS Server #Backup all DNS Zones defined on a Windows DNS Server #Get Name of the server with env variable $DnsServer = Get-Content env:computername #Define folder where to store backup $BackupFolder = ”c:\windows\system32\dns\backup” #Output File to store Dns Settings $StrFile = Join-Path $BackupFolder “input.csv” #Check if folder exists. if exists, delete contents if (-not(test-path $BackupFolder)) { New-Item $BackupFolder -Type Directory | Out-Null } else { Remove-Item $BackupFolder”\*” -recurse } #Get DNS Settings using WMI Object $List = Get-WmiObject -ComputerName $DnsServer -Namespace root\MicrosoftDNS -Class MicrosoftDNS_Zone #Export information into input.csv file #Line wrapped should be only one line $list | Select-Object Name, ZoneType, AllowUpdate, @{Name = ”MasterServers”; Expression = { $_.MasterServers } }, DsIntegrated | Export-csv $strFile -NoTypeInformation #Call Dnscmd.exe to export dns zones $list | ForEach-Object { $path = ”backup\” + $_.name $cmd = ”dnscmd {0} /ZoneExport {1} {2}” -f $DnsServer, $_.Name, $path Invoke-Expression $cmd } |
Restore:
Make sure the zone does not exist on DNS manager as it will give an error. If you need to re-create a new zone from the export file, you’ll find that you can do this by using dnscmd.exe with the /zoneadd switch. The only catch with this approach is that if you’re looking to recover an AD-integrated zone, you need to add the zone as a primary first and then convert it to AD-integrated. For example, to recover my Zone1.com zone:
1 |
dnscmd DC1 /zoneadd Zone1.com /primary /file Zone1.com.dns /load |
The /load switch to tell the command to load the configuration from the existing file. Without it, the command will create a new zone data file that will overwrite the contents of the backup file.
After adding the zone to the DNS server, you can convert it to an AD-integrated zone by running:
1 |
dnscmd /zoneresettype Zone1.com /dsprimary |
At this point, you can then enable secure dynamic updates for the zone by running:
1 |
dnscmd /config Zone1.com /allowupdate 2 |
This command configures the zone to accept only secure dynamic updates, as specified by the allowupdate value of 2 (use 0 to specify No dynamic updates, 1 for nonsecure and secure dynamic updates).
PowerShell Script to restore DNS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
#AD-DNS-Restore.ps1 #PowerShell 2.0+ required #Run this script locally on a DNS Server #Restore all DNS Zones defined on a Windows DNS Server # Get Name of the server with env variable $DNSSERVER = Get-Content env:computername #Define folder where to pick a backup $BackupFolder = ”c:\windows\system32\dns\backup” #Input File to read Dns Settings $StrFile = Join-Path $BackupFolder “input.csv” #Restore Zones based on settings found in input.csv $Zone = Import-Csv $StrFile $Zone | ForEach-Object { $path = ”backup\” + $_.name $Zone = $_.name $IP = $_.MasterServers $Update = $_.AllowUpdate #Check if AD Integrated or Not if ($_.DsIntegrated -eq $True) { Switch ($_.ZoneType) { 1 { #Create Zone As Primary to get all records imported $cmd0 = ”dnscmd {0} /ZoneAdd {1} /primary /file {2} /load” -f $DNSSERVER, $Zone, $path Invoke-Expression $cmd0 $cmd1 = ”dnscmd {0} /ZoneResetType {1} /dsprimary” -f $DNSSERVER, $Zone } 3 { $cmd1 = ”dnscmd {0} /ZoneAdd {1} /dsstub {2} /load” -f $DNSSERVER, $Zone, $IP } 4 { $cmd1 = ”dnscmd {0} /ZoneAdd {1} /dsforwarder {2} /load” -f $DNSSERVER, $Zone, $IP } } } else { Switch ($_.ZoneType) { 1 { $cmd1 = ”dnscmd {0} /ZoneAdd {1} /primary /file {2} /load” -f $DNSSERVER, $Zone, $path } 2 { $cmd1 = ”dnscmd {0} /ZoneAdd {1} /secondary {2}” -f $DNSSERVER, $Zone, $IP } 3 { $cmd1 = ”dnscmd {0} /ZoneAdd {1} /stub {2}” -f $DNSSERVER, $Zone, $IP } 4 { $cmd1 = ”dnscmd {0} /ZoneAdd {1} /forwarder {2}” -f $DNSSERVER, $Zone, $IP } } } #Restore DNS Zones Invoke-Expression $cmd1 Switch ($_.AllowUpdate) { #No Update 0 { $cmd2 = ”dnscmd /Config {0} /allowupdate {1}” -f $Zone, $Update } #Secure and non secure 1 { $cmd2 = ”dnscmd /Config {0} /allowupdate {1}” -f $Zone, $Update } #Only Secure Updates 2 { $cmd2 = ”dnscmd /Config {0} /allowupdate {1}” -f $Zone, $Update } } #Reset DNS Update Settings Invoke-Expression $cmd2 } |