PowerShell Script To Combine DNS Zones
Have you ever wanted to consolidate or merge duplicate primary DNS zones? This is a common scenario that I find, and usually it is related to reverse zones. This script functionality is similar to the DNSExporter tool, but it is much simpler to use. See the script for syntax and notes.
# -----------------------------------------------------------------------------
# Copy-DNSZone
# Mr. Ashley McGlone
# September, 2010
#
# This script is designed for situations where you find two primary copies of a
# DNS zone and need to copy records from one zone into the other so that you
# have a single copy of all the primary zone data in one location. It works for
# both forward and reverse zone.
#
# REQUIREMENTS
# 1. This script was tested successfully on:
# -Windows Server 2008 R2 with PowerShell v2
# -Windows Server 2003 R2 SP2 x64 with PowerShell v1
# 2. You must have DNS admin and WMI permissions on the servers involved.
# 3. The destination zone must exist (ie. It will not create a new destination
# zone automatically.)
#
# CAVEATS
# 1. Duplicate records of the same name will be overwritten and converted from
# aging to static. TimeStamp is a read-only property.
# 2. Copied DNS records will be static (no aging data copied) and their
# permissions will be reset (no ACLs copied).
# 3. Currently the script only support record types A, CNAME, MX, SRV, PTR.
# Feel free to modify the script for other record types as needed.
# 4. The script does not copy deligated sub-domains within a zone.
#
# MORE INFO
# DNS WMI Classes
# https://msdn.microsoft.com/en-us/library/ms682123(v=VS.85).aspx
# MicrosoftDNS_ResourceRecord Class
# https://msdn.microsoft.com/en-us/library/ms682713(VS.85).aspx
# CreateInstanceFromPropertyData Method of the MicrosoftDNS_AType Class
# https://msdn.microsoft.com/en-us/library/ms682178(VS.85).aspx
#
# -----------------------------------------------------------------------------
Param (
$srcServer,
$srcZone,
$destServer,
$destZone
)
If ( ($srcServer -eq $null) -or
($srcZone -eq $null) -or
($destServer -eq $null) -or
($destZone -eq $null)
) {
Write-Host "
NAME
Copy-DNSZone
SYNOPSIS
Copies DNS records from one zone to another.
SYNTAX
.\Copy-DNSZone SourceServer SourceZone DestinationServer DestinationZone
EXAMPLES
Forward zone:
.\Copy-DNSZone dns1.foo.com myzone.com dns2.foo.com myzone.com
Reverse zone:
.\Copy-DNSZone dns1.foo.com 1.10.in-addr.arpa dns2.foo.com 1.10.in-addr.arpa
Reverse zone roll up:
.\Copy-DNSZone dns1.foo.com 1.10.in-addr.arpa dns2.foo.com 10.in-addr.arpa
DESCRIPTION
This script is designed for situations where you find two primary copies of a
DNS zone and need to copy records from one zone into the other so that you
have a single copy of all the primary zone data in one location. It works for
both forward and reverse zone.
RELATED LINKS
DNS WMI Classes
https://msdn.microsoft.com/en-us/library/ms682123(v=VS.85).aspx
MicrosoftDNS_ResourceRecord Class
https://msdn.microsoft.com/en-us/library/ms682713(VS.85).aspx
CreateInstanceFromPropertyData Method of the MicrosoftDNS_AType Class
https://msdn.microsoft.com/en-us/library/ms682178(VS.85).aspx"
Throw "Insufficient parameters."
}
# The parent class MicrosoftDNS_ResourceRecord will capture all resource record
# subclasses in a single call rather than fetching each separately.
# Filter out NS and SOA records, because we don't want to copy those to the
# destination zone.
# Filter on the zone (ContainerName) so that we only get the zone we want.
# By default WMI will return all records from all zones.
$src = Get-WMIObject -ComputerName $srcServer -Namespace 'root\MicrosoftDNS' `
-Class MicrosoftDNS_ResourceRecord | Where-Object { `
($_.ContainerName -eq $srcZone) -and `
($_.__Class -ne "MicrosoftDNS_NSType") -and `
($_.__Class -ne "MicrosoftDNS_SOAType")}
ForEach ($srcRec in $src) {
# Echo the source record data for logging
$srcRec
$class = $srcRec.__CLASS # A, CNAME, PTR, etc.
$ownerName = $srcRec.OwnerName # Name column in DNS GUI, FQDN
$containerName = $srcRec.ContainerName # Zone FQDN
$domainName = $srcRec.DomainName # Zone FQDN
$ttl = $srcRec.TTL # TTL
$recordClass = $srcRec.RecordClass # Usually 1 (IN)
$recordData = $srcRec.RecordData # Data column in DNS GUI, value
# Dynamically create a new record of the appropriate type (class)
$destRec = [WmiClass]"\\$destServer\root\MicrosoftDNS:$class"
# The CreateInstanceFromPropertyData method varies slightly based on the
# record type (class).
Switch ($class) {
MicrosoftDNS_AType {
$destRec.CreateInstanceFromPropertyData($destServer, $destZone, `
$ownerName, $recordClass, $ttl, $recordData)
}
MicrosoftDNS_CNAMEType {
$destRec.CreateInstanceFromPropertyData($destServer, $destZone, `
$ownerName, $recordClass, $ttl, $recordData)
}
MicrosoftDNS_MXType {
$preference = $srcRec.Preference
$mailExchange = $srcRec.MailExchange
$destRec.CreateInstanceFromPropertyData($destServer, $destZone, `
$ownerName, $recordClass, $ttl, $preference, $mailExchange)
}
MicrosoftDNS_SRVType {
$priority = $srcRec.Priority
$weight = $srcRec.Weight
$port = $srcRec.Port
$destRec.CreateInstanceFromPropertyData($destServer, $destZone, `
$ownerName, $recordClass, $ttl, $priority, $weight, $port, `
$domainName)
}
MicrosoftDNS_PTRType {
$PTRDomainName = $srcRec.PTRDomainName
$destRec.CreateInstanceFromPropertyData($destServer, $destZone, `
$ownerName, $recordClass, $ttl, $PTRDomainName)
}
}
}
Comments
Anonymous
November 26, 2013
What if you want to perserve the ACL's to ensure dynamic updates occur correctly from the computer that created the record (owner)?Anonymous
November 27, 2013
The comment has been removedAnonymous
December 17, 2013
Ashley, I'm working with the account team regarding the premier support. I do believe the account has it, or atleast the company I work for has it (we are a partner with MS... can discuss details elsewhere). How do I get you engaged?Anonymous
December 17, 2013
Hi John,Give my name to your TAM (Technical Account Manager). They can contact me internally.AshleyAnonymous
December 18, 2013
OK will do. Thank youAnonymous
February 07, 2014
The comment has been removedAnonymous
February 08, 2014
The comment has been removedAnonymous
July 31, 2014
The comment has been removed