Monday, October 24, 2011

Migrating a lot of zones from Microsoft DNS to BIND

In my last post, I gave some solutions to migrating zones from Microsoft DNS to BIND dns zones. If you have a lot of zones, you may be wondering if there is an easy way to run these steps on all of them to migrate the whole configuration. Well with dnscmd and some basic scripting, that is just adding a few more minutes of work.

When you want to see all of your zones:

dnscmd [dnsserver] /enumzones

will list out every zone on the server. The format needs some work though, and you will need to ignore the header and footer output for the command. The rest comes out in the format of Zone Type Partition Options, with no standardization to the whitespacing between them. Since the zone happens to be what we need, we can easily extract that and use it for follow on commands.

If we want to export our zone's to files, we can try this in powershell:

$zones = dnscmd $dnsserver /enumzones
for ($i = 7; $i -lt ($zones.length -3); $i++) {
$zonename = $zones[$i].substring(1)
$zonename = $zonename.substring(0,$zonename.indexof(" "))
$file = $zonename[$i] + ".txt"
dnscmd $dnsserver /exportzone $zonename $file

This will go through all the output, strip out the zone names and export them all to a text file named after the zone name. You could use this same method as a way to backup records if you have issues with them being deleted, or zones going missing. Here I started at the 7th line of output, which should bypass all of the headers and ignore the first zone, which will likely be the "." zone. You can check where you want to start by looking at the lines of the $zone array before doing a loop. We end 3 lines short of the end of the output to skip the footer information.

Alternatively if you were to go with the secondary zone on BIND method, you could use dnscmd to set up the allow zone transfer and provide the BINDS server's IP. While doing this and the above example, you could even throw in extra output to file using the zone name to build all of the BIND config file's entries for the new zones (primary or secondary).

In any case, to use dnscmd to set an IP for zone transfers:

dnscmd [dnsservername] /zoneresetsecondaries /Securelist [secondary dns server ip]

If you are running this on a lot of zones and you don't want to do this to all of them, find another method. This will reset the existing settings on the zone.

These examples are just a few ways to do this. There may be some existing powershell cmdlets available that will accomplish some of these tasks. For obtaining a list of zones, and better filtering/handling of them, you could also take a look at doing this with: Get-wmiobject -namespace root\microsoftdns -class microsoftdns_zone -computer [remote dns server name].


  1. Very helpfull, i still cannot discover what should be the best way to migrate a lot of Windows 2003 AD Server zones to Bind.
    I liked the first option but Windows 2003 does not have powershell...


  2. Nico, There are several options. First you could install powershell on the server, or run the commands from another machine that has powershell...using an account that has rights to the dns server. The dnscmd can point to remote systems.

    Overall, the use of powershell here is just text processing and putting entries into the dnscmd.exe dos command. You could do all of this with any scripting language. There are even ways to do it without using dnscmd, though it gets more complicated. If your existing windows zones are primary (non AD) zones, then they would already have text file zones on the dns server that you can copy off. If they are integrated in AD, then they are accessible by ldap query, however its all binary encoded, so its more work to decode it all and try to make a formatted text zone file with that.

    If you went the route of turning on zone transfers, on the windows side that is just a single command to turn it on for all zones, then you can take the list of zones to the system running bind (assuming that is unix/linux), it wouldn't be too hard to clean up the zone list and create a simple shell script to write a bind config file to declare all the zones as secondary and point it to your Windows master box. Once they are all transferred, you can change the config file to have the zones as primary instead.

  3. I'm getting errors of ERROR_ALREADY_EXISTS and when I navigate to the folder the .txt documents are to export to, I have about 8 files but they are all named e, i, m, o, a, etc. but none of my other DNS zone files are there because of the error. Advice?

  4. Hi Tyler,

    My script is pretty hackish and deals with text output. Based on what your saying, I'm thinking there might be a difference in how dnscmd may output between different windows versions. I'm guessing from the date of my post that I was doing this with posh v1 on windows 2003 server. I haven't tried again on newer OS's to see if there is any difference, but it would certainly be worth the try. What OS and posh version are you trying this with?

  5. Sorry! After more research it seems to be a problem with how the zonename is being parsed. I'll try and comment back here when I have a solution for that.

  6. Sorry for the comment flurry - to fix this issue simply replace the line
    "$file = $zonename[$i] + ".txt""
    "$file = $zonename + ".txt".

    Indexing the zone name will only give the $i'th character of the zone name, which means it won't export to a file properly.

    Hope this helps!


  7. 9) Test DDNS updates sent to your BIND Master are now forwarded & show up in MSFT DNS

    10) Use DDNS or a MSFT command line tool to update the SOA record for every zone with the host name for your BIND Master instead of the name of a MSFT DC.

    11) DNS Updates are now flowing though your BIND server.

    12) For large networks I would recommend building a secondary master server (in your 2nd primary data center). Copy the config from this server and make update everything you need with find and replace this server should slave from the master BIND Server.

    13) Create your slave / recursion servers servers the two servers above should not be doing recursion or forwarding for recursion they are just zone masters. You could do this split views and mulitple IP addresses on the same server... but I wouldn't go there unless you fancy your self a Master of BIND. NOTE: MSFT AD requires authoritative responses for AD DNS so you must have the zones slaved to your DNS resolvers.

    14) configure also-notify and allow-notify after this is up and running all your servers should be updating very smoothly

    Option 1:
    15) reconfigure your DHCP servers with your new DNS recursion server IP addresses & re-point your statically configured servers and devices to your new recursion servers.

    Option 2:
    15) Shut down your old dedicated MSFT recursion server and move those IP addresses to your bind recursion server. (Preferred but depends if you have other hard to move services on your old DNS servers.)

    16) Use your favorite text editor to change all (clever find and replace stuff here) the Zones on your Master DNS server from Slave Zones to Master zones.

    17) Run RNDC reload

    Again I am doing this from memory so test test test and this is a methodology for a seamless migration for people with BIND experience not a beginners guide, anyone who wants to take this and improve it or make money with it... please do. :)