Skip to content

Migrate Windows DNS and BIND zones

Zone files are the most common road into DTM, and the most common way to get hurt on that road is misjudging the Active Directory boundary or trusting that “import” means “sync”. This tutorial migrates a mixed Windows DNS and BIND estate with a parallel run: classify first, import with a dry run, prove parity, repoint clients in waves behind a freeze rule that cannot lose writes, and enrich with health checks only after the last import.

The 3 AD-integrated zones (the domain zone and _msdcs) stay on the domain controllers: DTM does not implement GSS-TSIG, so domain controllers and domain-joined Windows clients cannot self-register into it, and the supported pattern is coexistence, not replacement (the boundary in full). The other 11 zones move. Write the classification down; it is the migration’s contract.

  • Windows DNS: Export-DnsServerZone per zone. Zones with aging enabled carry inline [AGE:] stamps that the BIND-format parser rejects; strip them before upload:

    Terminal window
    Get-Content example.dns | ForEach-Object { $_ -replace '\s*\[AGE:\d+\]', '' } |
    Set-Content example.zone

    The dry run in step 3 reports any file that still carries them as a parse error, so nothing slips through silently.

  • BIND: copy the zone files from the named zone directory.

Both formats carry the SOA, which matters: the bulk import derives each zone’s name from its SOA owner (see the format notes before massaging any file by hand).

Upload all 11 files in one multipart request with ?dry_run=true and review the plan: the aggregate to_create / to_modify / unchanged record counts (summed across the request), plus the per-zone lists of new zones, parse errors, and SOA conflicts, before anything is written. Caps to know: 20 MB per request, 50 zones per request, 50,000 records per zone.

Commit the import, then compare answers between DTM and the old servers across a spread of names and types per zone:

Terminal window
for n in app db mail; do
echo "$n: DTM=$(dig @10.0.250.4 $n.ops.example.internal +short) \
old=$(dig @10.10.0.2 $n.ops.example.internal +short)"
done

Re-running an import is safe in a specific, bounded sense: re-importing an existing zone is skipped as already present, and a re-imported record replaces its same-name-same-type predecessor. It is a replace, not a merge; that nuance drives steps 7 and 8.

Make DTM client-ready before any client points at it: conditional forwarders for the AD domain and _msdcs toward the domain controllers (the AD coexistence guide owns the pattern, including the stub-zone variant), plus forwarders for anything not yet migrated. A client that lands on DTM must be able to resolve everything from day one, migrated or not.

6. Repoint clients in waves, and freeze at wave one

Section titled “6. Repoint clients in waves, and freeze at wave one”

Move clients by DHCP scope (option 006) or VNet dnsServers, in waves. After each wave, verify plain lookups and the AD service records resolve through DTM’s forwarding:

Terminal window
dig @10.0.250.4 _ldap._tcp.dc._msdcs.corp.example.com SRV +short

One rule keeps the wave model coherent: since any client wave queries every zone, freeze writes to all migrated zones on the old servers when the first wave repoints. Zone-by-zone freezing sounds gentler and quietly serves stale answers to migrated clients instead.

After the freeze, re-export and re-import once to sweep up late adds and edits made between your first import and the freeze.

Now, and not earlier, add health checks and load-balancing policies to the records that deserve them. The ordering is deliberate: an import that collides with an enriched record replaces it, stripping its policy and reaping its auto-created health checks. If a re-import is ever needed after enrichment, scope it to one zone, dry-run the diff, and apply the genuine changes through the per-record API instead of the file.

Watch query volume on the old servers via their own logs and consoles until it falls to zero (stragglers show up here: hardcoded resolvers, forgotten scopes). Then decommission the two Windows servers and the BIND box. The three AD-integrated zones stay where they are, behind their forwarders, by design.

Need a hand? Email [email protected].

Last validated: 2026-07-26