# ----------------------------------------------------------------------------- # 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 delicated 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) } } }