Transferring Windows Server roles, Part III setup the new Server

9 min readFeb 12, 2022


TL;DR Migrating 2016 to 2019: demote the Server 2016 DC, install Server 2019, run setup scripts for static IPs & joining the domain, pull GPOs, promote to DC, move the FSMO roles, add the server to DFS.

Welcome to Part III of our PDC & DFS migration!

Part I: DFS

Part II: FSMO roles

Part III: Setup the new PDC


This is Part III; demoting the DC, bringing the VM up on Server 2019, and adding it’s roles. Part I covered rotating servers that host DFS target folders without disrupting file sharing. Part II covered migrating the FSMO roles and backing up GPOs.

The lab consists of three Domain Controllers (DCs) and one client workstation:

  • TestDC running Windows Server 2016, soon to be 2019
  • BackupDC running Windows Server 2016
  • BackupDC3 running Windows Server 2019
  • TestClient running Windows 10 Professional

TestDC is a VM that serves as a DC, DNS, and DFS server. As the original DC when the domain was stood up, TestDC also initially held all FSMO roles. There are of course no users in the lab, but if there were they should not notice.

Demote the old DC

First, demote the Windows Server 2016 DC so that it’s not a DC.

Uninstall-ADDSDomainController -Confirm

A password for the local admin is required as the system will be a member sever following the demotion and a restart.

Configure the new VM

Next we execute a clean install of Windows Server 2019 and run two scripts; one that handles the static IP settings and the second script joins the domain. Simply open PowerShell ISE as Admin and run

Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope CurrentUserWrite-Host “Welcome to Mishky’s networking setup script for new Windows servers”
Write-Host “Please enter the below info for IPv4 to set a static IP and the right DNS”
Write-Host “FYSA Mishky also disables IPv6 & NetBIOS, because the network isn’t using them”
$IP = read-host “Please enter the server’s IP address”
$Gateway = read-host “Please enter the gateway IP address”
$ServerName = read-host “Please enter the server’s name”
#Disable IPv6
Disable-NetAdapterBinding -InterfaceAlias “Ethernet0” -ComponentID ms_tcpip6
#Disable NetBIOS
$regkey = “HKLM:SYSTEM\CurrentControlSet\services\NetBT\Parameters\Interfaces”
Get-ChildItem $regkey |foreach { Set-ItemProperty -Path “$regkey\$($_.pschildname)” -Name NetbiosOptions -Value 2 -Verbose}
#Set IPv4 address, gateway, & DNS servers
New-NetIPAddress -InterfaceAlias “Ethernet0” -AddressFamily IPv4 -IPAddress $IP -PrefixLength 24 -DefaultGateway $Gateway
Set-DNSClientServerAddress -InterfaceAlias “Ethernet0” -ServerAddresses (“”, “”, “”, “”, “”)#Rename the server
Rename-Computer -NewName $ServerName -LocalCredential Administrator -PassThru -restart -force
Write-Host “Join the test.local domain”
$User = Read-Host “Please enter your domain admin username”
Add-Computer -DomainName test.local -Credential $User -restart -force

(There’s a footnote on IPv6.)

The system restarts automatically and upon bootup we can login to the domain. At this point it is just a member server. Of course it pulls all the GPOs for domain controllers. These allow PSSession and RDP access for Domain Admins, auto-map the I Drive containing scripts, installation packages, and backups, and tweak some other settings like showing file extensions and such.

Promote the new DC

Next promote the new server to a DC:

Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementToolsInstall-ADDSDomainController -DomainName “test.local” -InstallDns:$true

Please note that dcpromo.exe was depreciated back in Windows Server 2012.

Confirm the promotion to DC following the restart:

Get-Service adws,kdc,netlogon,dns$allDCs = (Get-ADForest).Domains | %{ Get-ADDomainController -Filter * -Server $_ } ; Write-Host $allDCs

Add the new server to DFS

The next setup task is to re-integrate TestDC into the Distributed File System (DFS) for hosting a Folder Target and DFS Replication. The first step is to create a shared folder on TestDC with the same name and permissions as the other Folder Targets on the other DFS servers.

I already had a quick & dirty script/glorified batch file for creating a folder and sharing it on the I Drive, so just change the variables and run it:

Confirm with

Get-SMBShareAccess -Name <share name>

DFS replicates the NTFS permissions to the newly created folder once it is added to the DFS namespace & replication.

Install the DFS Windows Feature, but since I can never remember what the exact name is simply ask Windows to remind me by doing ‘Get-WindowsFeature *DFS*’. Then:

Install-WindowsFeature FS-DFS-Namespace, FS-DFS-Replication –IncludeManagementTools

Then just run:

New-DfsnFolderTarget -Path “\\test.local\Mishky’s Share\Test Share” -TargetPath “\\TestDC\Test Share” -ReferralPriorityClass SiteCostNormalGet-DfsReplicationGroup -GroupName “test.local\Mishky’s Share\Test Share” | Get-DfsReplicatedFolder -FolderName “Test Share” | Add-DfsrMember -ComputerName TestDCAdd-DfsrConnection -GroupName “test.local\Mishky’s Share\Test Share” -SourceComputerName BackupDC -DestinationComputerName TestDCSet-DfsrMembership -GroupName “test.local\Mishky’s Share\Test Share” -FolderName “Test Share” -ComputerName TestDC -ContentPath “C:\Test Share”

I already had a PowerShell batch file of sorts from adding BackupDC3 to DFS, so simply change the computer name and run. Even if you suck at scripting like I do, CLIs are still nice for copy/pasting. Additionally Microsoft expects you to know some PowerShell, and then there’s Server Core.

#Prep a new folder for adding to an existing DFS namespace
$NewDirPath = “C:\Test Share”
$NewShareName = “Test Share”
try {Get-Item -Path $NewDirPath -ErrorAction Stop}
catch {Write-Host “Dir not found. Cleared hot.” -ForegroundColor Green}
New-Item $NewDirPath -ItemType directory
New-SMBShare -Name $NewShareName -Path $NewDirPath
#Install DFS tools
Add-WindowsFeature -Name FS-DFS-Namespace
Add-WindowsFeature -Name FS-DFS-Replication
Add-WindowsFeature -Name RSAT-DFS-Mgmt-Con
#Add a new server to DFS. BackupDC4 is already hosting the namespace \\test.local\Mishky’s Share\Test Share$newDFSserver = “TestDC”New-DfsnFolderTarget -Path “\\test.local\Mishky’s Share\Test Share” -TargetPath “\\$newDFSserver\Test Share” -ReferralPriorityClass SiteCostNormalGet-DfsReplicationGroup -GroupName “test.local\Mishky’s Share\Test Share” | Get-DfsReplicatedFolder -FolderName “Test Share” | Add-DfsrMember -ComputerName $newDFSserverAdd-DfsrConnection -GroupName “test.local\Mishky’s Share\Test Share” -SourceComputerName BackupDC4 -DestinationComputerName $newDFSserverSet-DfsrMembership -GroupName “test.local\Mishky’s Share\Test Share” -FolderName “Test Share” -ComputerName $newDFSserver -ContentPath “C:\Test Share”

Confirm DFS Replication is good:

Get-DfsReplicationGroup -GroupName “test.local\Mishky’s Share\Test Share” | Get-DfsReplicatedFolder -FolderName “Test Share” | Get-DfsrMembership

Confirm in the GUI by running DFS Manager:

Lastly change the PowerShell execution policy for scripts back to the safer default:

Set-ExecutionPolicy Restricted

Lastly, the FSMO roles are migrated back to their original server:

Move-ADDirectoryServerOperationMasterRole -Identity TestDC -OperationMasterRole pdcemulator, ridmaster, infrastructuremaster, schemamaster, domainnamingmaster

This can be confirmed via various PowerShell commands, but the output never wants to display properly. I am partial to the oldie but goodie ‘netdom query fsmo’ as a result.

As noted in Part II, migrating the FSMO roles in the GUI involves three different management tools. By contrast this task can be performed in one simple PowerShell command.

Additionally, as noted in Part II, the term ‘FSMO’ is depreciated. I still use it because it’s easier to type, and the netdom command uses it.

Random housekeeping, logon banners, etc

Lastly I finally got around to setting a logon message via GPO. This is the standard message that displays on domain workstations after the user clicks but before they are presented with the username/password boxes. This is simple to do by right clicking the OU in the Group Policy Management Console (GPMC) and hitting ‘Create a GPO in this domain and link it here’, then navigating to

Computer Configuration\Windows Settings\Security Settings\Local Policies\Security Options

And modifying ‘Interactive logon: Message text’ and ‘Interactive logon: Message title’

Now the server is back up and running the services it hosted before the migration: AD DS, DNS, and DFS.


In summary, it is rather straightforward to migrate a DC from Windows Server 2016 to 2019. Part I was on how to remove one server from a DFS namespace & replication and add a different server without the end users suffering an interruption. Part II was on migrating the FSMO roles and backing up GPOs. This part walked through setting the original server back up. There aren’t any users in the lab of course, but if there were they would not have noticed this process.

Footnote on dual stack IPv6/IPv4 clients in a network that’s only using IPv4:

NOTE: I wrote this almost 2 years ago. The steps below are only for a lab and only concerned with security. The conventional wisdom in production favors setting policy to prefer IPv4 over IPv6, not disabling IPv6 entirely.

The conventional wisdom is that if you’re not using IPv6 then just disable it. An attacker can setup an IPv6 RTR in a network that’s only using IPv4 but has IPv6 enabled on clients. The clients will happily send IPv6 traffic to the attacker if the attacker sends out RTR advertisements since the clients prefer IPv6 by default. The attacker can then direct them to his/her IPv6 DHCP, give them an IPv6 DNS server, and use that to send them a WPAD file. The clients will then use the attacker as their proxy. It gets worse from there, as the attacker can set their proxy to send authentication required messages to the client’s browser and potentially grab NTLM challenge/responses.

Like most things in a Windows domain, this can be centrally managed for workstations via a GPO, located under Computer Configuration\Preferences\Windows Settings\Registry. Then simply create a value named ‘DisabledComponents’ under HKLM\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters, with type REG_DWORD and hex value of 0x20 to prefer IPv4 over IPv6. (Set hex value to 0xFF to disable IPv6.)

Footnote on lab setup:

I ended up giving ESXi 1 TB of HD and 36 GB of RAM. Eventually I’ll have to spring for a dedicated server, but for now everything in this lab is free, given that I already had the hardware it is currently running on. I gave the DC a more logical IP at upgrade to Server 2019, so now the DCs are *.101, 102, and 103. In the current setup ESXi is using 386 GB to host one domain with 3 DCs & 1 client, another domain with 1 DC & 1 client, and a standalone Slingshot Linux VM. The trick is to thin provision all VMs. The free version of ESXi supports snapshots, supports managing VMs through the web browser, and of course Windows VMs can be easily managed via RDP and PSSession.

The initial lab domain was setup a bit haphazardly without planning it out on paper first. This caused all sorts of weird issues later after the primary DC’s upgrade & IP change, such as DFS Manager’s inability to find the namespace, GPOs not quite functioning properly, etc.

Everything works properly now, but I had to go back and re-verify the DNS settings on all DCs.

Hence it is wise to plan the computer names and IPs on a whiteboard before beginning. Admittedly I did not do this at first. It is best to learn these practices in the lab though.





I work various IT jobs & like Windows domain security as a hobby. Most of what’s here is my notes from auditing or the lab.