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) } } }
What if you want to perserve the ACL's to ensure dynamic updates occur correctly from the computer that created the record (owner)?
Hi John,
That is a great question. Currently the script will not preserve ACLs. I'll add that to my list of feature requests. If you are a Microsoft Premier customer, then we can schedule a time for me to rewrite the script for you to meet all of your needs. Let me know if you would like to pursue that option.
If you want to tackle it on your own, then you'll need to do a Get-ACL on the old record and capture that into a variable. Then you could use Set-ACL to apply the ACE in the variable to the new record after it is created.
Also, we have new DNS cmdlets now that will make this much easier. See the DNSClient and DNSServer modules in the Windows Server 2012 RSAT for a full list of cmdlets.
Hope this helps,
GoateePFE
Ashley McGlone
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?
Hi John,
Give my name to your TAM (Technical Account Manager). They can contact me internally.
Ashley
OK will do. Thank you
When I run the script it takes a long time to run and eventually dies with the error: Get-WMIObject : Quota violation I’m only trying to copy one reverse DNS zone. Any ideas?
How large is the zone? WMI for DNS is known not to scale well. The newer cmdlets for DNS work much better.
Have you ever wanted to roll up all of your reverse zones into a "big 10" super zone? Do you need to copy DNS zones between environments and preserve the record aging? Today’s post is for you.