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            
#   http://msdn.microsoft.com/en-us/library/ms682123(v=VS.85).aspx            
# MicrosoftDNS_ResourceRecord Class            
#   http://msdn.microsoft.com/en-us/library/ms682713(VS.85).aspx            
# CreateInstanceFromPropertyData Method of the MicrosoftDNS_AType Class            
#   http://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
      http://msdn.microsoft.com/en-us/library/ms682123(v=VS.85).aspx
    MicrosoftDNS_ResourceRecord Class
      http://msdn.microsoft.com/en-us/library/ms682713(VS.85).aspx
    CreateInstanceFromPropertyData Method of the MicrosoftDNS_AType Class
      http://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)            
        }            
    }            
}            
            
 
 

 

Copy-DNSZone.p-s-1.txt