A ten-phase checklist for adding new Windows Server domain controllers to an existing Active Directory domain, moving the FSMO roles, and retiring the old DCs safely.
Who this is for
Administrators who already run an Active Directory domain and need to replace its domain controllers with new servers, one at a time, without downtime.
Before you start
- Domain Admins membership, and Enterprise Admins for the forest-wide FSMO roles and the automatic schema update
- A current, tested system-state backup of at least two existing DCs
- A maintenance window and a written rollback plan for each phase
- The new servers' names, static IPv4 addresses and AD site, decided in advance
Applies to
Adding Windows Server 2022 or 2025 domain controllers to an existing single-domain Active Directory forest, then demoting the older DCs. Commands for Windows PowerShell 5.1 with the ActiveDirectory, ADDSDeployment, DnsServer and DhcpServer modules. Checked against Microsoft Learn on 2026-10-26; not tested on hardware.
Ask AI about this guideChatGPT, Claude, or any assistant
These open a new chat with a prompt that points the assistant to this guide. It only sees the guide if it can open the link. If it says it can't, use Copy guide for AI and paste the text into the chat.
Nothing goes to an AI service unless you choose one. AI answers can be wrong: check them against the guide before you change anything important.
This runbook is for replacing the domain controllers in an Active Directory domain you already run. You add new DCs alongside the old ones, prove they're healthy, move the FSMO roles, repoint everything that used the old DCs, and only then demote the old ones. Done in that order, nobody should notice.
It doesn't cover building a new forest from nothing, an in-place OS upgrade of an existing DC, read-only DCs, or multi-domain forests. Every name and address below is a made-up example: corp.example.com and addresses from the documentation ranges in RFC 5737. Swap in your own before you run anything.
Your progress
Before you start#
New forest or existing domain?#
These are different jobs, and mixing their commands is a classic way to break things.
| You're doing | Cmdlet | This runbook? |
|---|---|---|
| Building a brand-new forest (first DC of a new domain) | Install-ADDSForest | No. That creates a new, separate directory. |
| Adding a DC to a domain that already exists | Install-ADDSDomainController | Yes |
| Removing a DC that isn't the last one in its domain | Uninstall-ADDSDomainController | Yes |
Example names used on this page#
| Placeholder | Meaning | Example |
|---|---|---|
corp.example.com | Your AD DNS domain (also the forest root here) | corp.example.com |
DC=corp,DC=example,DC=com | The same domain as a distinguished name | |
<OldDC> | A DC you're retiring (repeat per DC) | DC-OLD-01 at 192.0.2.10 |
<NewDC> | A new DC you're adding (repeat per DC) | DC-NEW-01 at 192.0.2.20 |
<Site> | The AD site the new DC belongs to | Default-First-Site-Name |
<Gateway> | The subnet's default gateway | 192.0.2.1 |
How to read the steps#
- Where to run it is in each code block's title. "Elevated" means an administrator Windows PowerShell 5.1 session. Some cmdlets used here (
Add-Computer,Test-ComputerSecureChannel) aren't in PowerShell 7. - Steps tagged Changes production in the checklists change directory, DNS, DHCP or server state. Each has a caution above it and, where the cmdlet supports it, a
-WhatIfor test run first. - Only commands checked against Microsoft's documentation appear in copyable code blocks. Emergency procedures (seizing roles, metadata cleanup) are described in text on purpose: read the linked article before you do either.
- Nothing on this page runs anything. Your ticks and notes stay in your browser, and they're only saved if you turn saving on above.
Phase 1: Health baseline and safety net#
Record a known-good state before you change anything, and make sure you can get back to it. If the domain isn't healthy now, fix that first: a new DC copies whatever problems the old ones have.
Install-WindowsFeature Windows-Server-Backup
wbadmin start systemstatebackup -backupTarget:E:
New-Item -ItemType Directory -Path C:\Migration -ErrorAction SilentlyContinue
dcdiag /v /c /s:<OldDC> /f:C:\Migration\dcdiag_<OldDC>_baseline.txt
dcdiag /test:DNS /v /s:<OldDC>
dcdiag /test:Advertising /test:NetLogons /test:SysVolCheck /test:DFSREvent /s:<OldDC>
repadmin /replsummary
repadmin /showrepl * /csv > C:\Migration\showrepl_baseline.csv
repadmin /queue
dfsrmig /getglobalstate
dfsrmig /getglobalstate should report the Eliminated state, which means SYSVOL already replicates with DFS Replication. Windows Server 2019 and later can't be added as DCs while the domain still uses FRS for SYSVOL. If yours does, migrate first with Microsoft's SYSVOL migration guide, and treat that as its own change: moving to Eliminated can't be undone.
Get-ADDomainController -Filter * | Select-Object Name,IPv4Address,Site,OperationMasterRoles
Get-ADForest | Select-Object Name,ForestMode
Get-ADDomain | Select-Object DNSRoot,DomainMode
Get-SmbShare -CimSession <OldDC> -Name SYSVOL,NETLOGON
w32tm /monitor
Check the functional levels against the new DCs' OS. Per Microsoft's functional-level table, a Windows Server 2025 DC needs domain and forest functional levels of at least Windows Server 2016. Earlier releases accept some lower levels, so look up your exact combination in that table. If your levels are too low for the release you want, plan an intermediate step.
Phase 2: Build and patch the new servers#
Build each new server with a supported Windows Server release, give it its final name, and patch it fully before it joins the domain. Server Core is a good fit for a DC.
Rename-Computer -NewName <NewDC> -Restart
Patch with whatever your organization already uses (WSUS, your update management tool, or Windows Update). On Server Core, sconfig option 6 (Install updates) installs quality updates. Repeat until no updates are offered, then reboot.
Set the time zone if it isn't right (Get-TimeZone -ListAvailable lists the IDs). Don't configure a separate time source on a DC that isn't the PDC emulator: members of the domain follow the domain hierarchy.
Set-TimeZone -Id "<Time zone ID>"
Phase 3: Static IP, DNS client and domain join#
Point each new server at the existing DCs for DNS before it joins, so the join resolves the domain correctly.
New-NetIPAddress -InterfaceAlias "Ethernet" -IPAddress 192.0.2.20 -PrefixLength 24 -DefaultGateway 192.0.2.1
Set-DnsClientServerAddress -InterfaceAlias "Ethernet" -ServerAddresses 192.0.2.10,192.0.2.11
Adding a static address this way turns DHCP off on that interface. Run it at the console or through out-of-band access: if you're connected over the old address, you'll lose the session.
Add-Computer -DomainName "corp.example.com" -Credential (Get-Credential) -Restart
Test-ComputerSecureChannel -Verbose
nltest /dsgetdc:corp.example.com
Phase 4: Install AD DS and promote, one server at a time#
Promote one server, let it replicate cleanly, and only then start the next. Run the prerequisite test with the same parameters first: it changes nothing and tells you what would fail.
Install-WindowsFeature AD-Domain-Services,DNS -IncludeManagementTools
Import-Module ADDSDeployment
Test-ADDSDomainControllerInstallation -DomainName "corp.example.com" -SiteName "<Site>" -InstallDns:$true -Credential (Get-Credential) -SafeModeAdministratorPassword (Read-Host -AsSecureString "DSRM password")
Install-ADDSDomainController -DomainName "corp.example.com" -SiteName "<Site>" -InstallDns:$true -Credential (Get-Credential) -SafeModeAdministratorPassword (Read-Host -AsSecureString "DSRM password")
The new DC is a global catalog by default. Store the DSRM password the way you store other break-glass credentials: you'll need it for a directory restore.
Phase 5: Validate replication#
Confirm each new DC is a healthy replication partner before you move on.
dcdiag /v /s:<NewDC>
repadmin /showrepl <NewDC>
repadmin /replsummary
repadmin /kcc <NewDC>
Get-ADReplicationPartnerMetadata -Target <NewDC> -Scope Server | Format-Table Partner,LastReplicationSuccess,LastReplicationResult -AutoSize
If you need to push a change out quickly, repadmin /syncall <NewDC> /AdeP synchronizes all partitions across all sites, pushing from that DC. It's safe, but it generates replication traffic across every site link.
Phase 6: Confirm SYSVOL and NETLOGON#
A DC can finish promotion but not yet share SYSVOL. Until it does, it can't hand out Group Policy or logon scripts, so check for this explicitly.
Get-SmbShare -CimSession <NewDC> -Name SYSVOL,NETLOGON
Test-Path "\\<NewDC>\SYSVOL"
Test-Path "\\<NewDC>\NETLOGON"
dcdiag /test:NetLogons /test:SysVolCheck /test:DFSREvent /s:<NewDC>
Get-DfsrState -ComputerName <NewDC>
Phase 7: Find and repoint everything that uses the old DCs#
Do this before you move roles or demote anything. The usual surprises are DHCP's DNS option, DHCP relay on routers, static DNS settings on servers, LDAP binds in applications, RADIUS, backup software and monitoring.
Export-DhcpServer -File C:\Migration\dhcp-before.xml -Leases
Get-DhcpServerv4OptionValue -OptionId 6
Get-DhcpServerv4Scope | ForEach-Object { Get-DhcpServerv4OptionValue -ScopeId $_.ScopeId -OptionId 6 -ErrorAction SilentlyContinue }
Set-DhcpServerv4OptionValue -DnsServer 192.0.2.20,192.0.2.21 -WhatIf
Set-DhcpServerv4OptionValue -DnsServer 192.0.2.20,192.0.2.21
For each scope that sets its own option 6 (the read step above lists them), set it on the scope too:
Set-DhcpServerv4OptionValue -ScopeId 192.0.2.0 -DnsServer 192.0.2.20,192.0.2.21 -WhatIf
Set-DhcpServerv4OptionValue -ScopeId 192.0.2.0 -DnsServer 192.0.2.20,192.0.2.21
On routers and layer-3 switches, look for DHCP relay (helper) addresses that point at an old DC that also runs DHCP. Add the new relay address before you remove the old one, and save the configuration. The syntax depends on the vendor and OS version, so follow your platform's documentation.
Get-ChildItem -Path C:\Scripts -Recurse -Include *.ps1,*.psm1,*.config,*.ini | Select-String -SimpleMatch -Pattern "DC-OLD-01","192.0.2.10"
Get-DnsClientServerAddress -CimSession <host>
Resolve-DnsName corp.example.com -Type NS
For applications that bind to LDAP, check each one's settings for a DC name or address. Test LDAP and LDAPS reachability on each new DC (this only tests the TCP port, not the certificate):
389,636 | ForEach-Object { Test-NetConnection -ComputerName <NewDC> -Port $_ }
Get-ChildItem Cert:\LocalMachine\My | Where-Object { $_.DnsNameList.Unicode -contains "<NewDC>.corp.example.com" }
On an NPS server, Get-NpsRadiusClient lists the RADIUS clients (switches, wireless controllers, VPN) that send authentication there. NPS itself finds DCs through the domain, but check any client that was configured with an old DC's address directly.
Phase 8: Transfer the FSMO roles#
Move all five operation master roles onto new DCs while the current holders are online. That's a transfer, the safe path, as long as you don't add -Force. Moving forest-wide roles (schema master, domain naming master) needs Enterprise Admins; the domain roles need Domain Admins.
netdom query fsmo
Move-ADDirectoryServerOperationMasterRole -Identity "<NewDC>" -OperationMasterRole SchemaMaster,DomainNamingMaster,PDCEmulator,RIDMaster,InfrastructureMaster -WhatIf
Move-ADDirectoryServerOperationMasterRole -Identity "<NewDC>" -OperationMasterRole SchemaMaster,DomainNamingMaster,PDCEmulator,RIDMaster,InfrastructureMaster
netdom query fsmo
You can split the roles across new DCs if that suits your sites. If not every DC is a global catalog and the AD Recycle Bin is off, keep the infrastructure master off a global catalog server. Once the PDC emulator moves, configure the new holder's external time source, and set the old one back to the domain hierarchy.
Phase 9: Demote the old DCs, one at a time#
Demote one old DC, confirm the domain is still healthy, then do the next. Run the uninstall test first.
Before the first demotion, repoint each new DC's own DNS client. Phase 3 pointed the new DCs at the old DCs (192.0.2.10, 192.0.2.11) so they could join the domain. If they still point only there, they lose name resolution when the old DCs go. List another new DC first and the DC's own address last:
Set-DnsClientServerAddress -InterfaceAlias "Ethernet" -ServerAddresses 192.0.2.21,192.0.2.20
Get-DnsClientServerAddress -InterfaceAlias "Ethernet" -AddressFamily IPv4
Microsoft's DNS client recommendations say that after any change to a DC's DNS client settings you clear the resolver cache and register its DNS records. ipconfig /flushdns only empties this server's local resolver cache; it changes nothing on any DNS server. ipconfig /registerdns starts a dynamic registration of this server's DNS names and IP addresses, so it writes to the live zone.
ipconfig /flushdns
ipconfig /registerdns
Do the same on each new DC with its own addresses. Some admins use the loopback address (127.0.0.1) as the last entry instead of the DC's own address. Whichever you choose, test name resolution and a reboot on a test domain first: it hasn't been tested for this page.
Import-Module ADDSDeployment
Test-ADDSDomainControllerUninstallation -Credential (Get-Credential)
Uninstall-ADDSDomainController -Credential (Get-Credential)
After it reboots as a member server, remove the roles it no longer needs. If it also runs DHCP or file shares, leave those until they've moved.
Uninstall-WindowsFeature AD-Domain-Services,DNS -WhatIf
Uninstall-WindowsFeature AD-Domain-Services,DNS -Restart
Get-ADDomainController -Filter * | Select-Object Name,Site
repadmin /replsummary
If an old DC is dead and can't demote itself, don't just leave it powered off: its metadata keeps it in the replication topology. Clean it up as described in Microsoft's metadata cleanup article. Deleting the DC's computer object in Active Directory Users and Computers does the cleanup; in Sites and Services, delete the NTDS Settings object before the server object.
Phase 10: Clean up DNS and AD, then final checks#
A clean demotion removes most of what it should. Look for leftovers, and remove them only after you've confirmed what they are.
Get-DnsServerResourceRecord -ZoneName "corp.example.com" | Where-Object { $_.HostName -like "*DC-OLD-01*" -or $_.RecordData.NameServer -like "DC-OLD-01.*" -or $_.RecordData.DomainName -like "DC-OLD-01.*" -or $_.RecordData.IPv4Address.IPAddressToString -eq "192.0.2.10" }
Get-DnsServerResourceRecord -ZoneName "_msdcs.corp.example.com" | Where-Object { $_.RecordData.HostNameAlias -like "DC-OLD-01.*" -or $_.RecordData.NameServer -like "DC-OLD-01.*" -or $_.RecordData.DomainName -like "DC-OLD-01.*" }
Get-ADObject -SearchBase "CN=Sites,CN=Configuration,DC=corp,DC=example,DC=com" -Filter 'Name -eq "DC-OLD-01"'
Remove-DnsServerResourceRecord -ZoneName "corp.example.com" -Name "@" -RRType A -RecordData 192.0.2.10 -WhatIf
Remove-DnsServerResourceRecord -ZoneName "corp.example.com" -Name "@" -RRType A -RecordData 192.0.2.10
The demoted server's object under Sites and Services usually stays behind as an empty server object. Delete it in Active Directory Sites and Services once it has no NTDS Settings child.
Lingering objects are a separate problem, usually after a DC was offline longer than the tombstone lifetime. If replication logs event 1388 or 1988, see Microsoft's guidance on repadmin /removelingeringobjects, and run it with /advisory_mode first.
nltest /sc_query:corp.example.com
Resolve-DnsName corp.example.com -Type NS -Server <NewDC>
ipconfig /all
389,636,88,445 | ForEach-Object { Test-NetConnection -ComputerName <NewDC> -Port $_ }
Renew the client's DHCP lease from its own console (renewing over a remote session drops it), then check ipconfig /all shows only the new DNS servers.
Once the old DCs are gone and stable, you can raise the domain and forest functional levels. Treat that as its own planned change: Microsoft describes raises as generally irreversible.
Next steps#
Keep the dependency list: it's the start of documentation for the next migration. Put the new DCs in monitoring and backups, and schedule a test restore.
Sources and official documentation
- Microsoft Learn: Active Directory Domain Services functional levels
- Microsoft Learn: Upgrade domain controllers to a newer version of Windows Server
- Microsoft Learn: Migrate SYSVOL replication to DFS Replication
- Microsoft Learn: Windows Server version 1709 and later no longer supports FRS
- Microsoft Learn: dcdiag
- Microsoft Learn: dfsrmig
- Microsoft Learn: wbadmin start systemstatebackup
- Microsoft Learn: Install-ADDSDomainController
- Microsoft Learn: Test-ADDSDomainControllerInstallation
- Microsoft Learn: Uninstall-ADDSDomainController
- Microsoft Learn: Test-ADDSDomainControllerUninstallation
- Microsoft Learn: Transfer or seize Operation Master roles in AD DS
- Microsoft Learn: Move-ADDirectoryServerOperationMasterRole
- Microsoft Learn: Clean up Active Directory domain controller server metadata
- Microsoft Learn: Remove-DnsServerResourceRecord
- Microsoft Learn: Set-DhcpServerv4OptionValue
- Microsoft Learn: Recommendations for DNS client settings (KB 825036)
- Microsoft Learn: ipconfig
- Microsoft Learn: Test-NetConnection
- Microsoft Learn: Server Core SConfig
- RFC 5737: IPv4 address blocks reserved for documentation
Review history
- Technical review: Jeremiah Ellington,
- Editorial review: Jeremiah Ellington,
- Next scheduled review:
Spotted something out of date or wrong? Email a correction and I'll fix it. See how these guides are made.