Nowadays, being lazy is good. Why waste energy with clicking buttons when there are a more efficient ways to perform server maintenance such as blinking your eyes when you want to migrate DHCP something? Well, Michael Shop hasn’t made it that easy yet. So, let’s improvise with our copying and pasting abilities.

Assumption: DHCP is running on Windows Server 2008-R2 or newer

# Export the current DHCP database - must be executed on Windows 2012 or newer servers
$exportFile="\\SHERVER01\SHARE01\dhcpDatabase.xml"
$oldDhcpServer="ThreeLeggedSabretooth"
Export-DhcpServer -File $exportFile -Leases -Force -ComputerName $oldDhcpServer –Verbose
# Install DHCP Service on new server
Install-WindowsFeature DHCP -IncludeManagementTools
Install-WindowsFeature RSAT-DHCP
# Uninstall DHCP Server Role
uninstall-windowsfeature dhcp -remove
Uninstall-WindowsFeature RSAT-DHCP
# Restart-Computer -Force
# Remove DHCP Failover
$dhcpFailover=Get-DhcpServerv4Failover
$dhcpFailoverName=$dhcpFailover.Name
$dhcpPartner=$dhcpFailover.PartnerServer
Remove-DhcpServerv4Failover -ComputerName $dhcpPartner -Name $dhcpFailoverName
# Import DHCP database onto new DHCP Server (Primary)
$newDHCPServer="Dumbo"
Import-DhcpServer -File $exportFile -BackupPath C:\Temp -Leases -ScopeOverwrite -Force -ComputerName $newDHCPServer –Verbose
# Export the new production DHCP database and Import into its Replication Partner
$exportFile="\\FILESHERVER\hdcp\dhcpDatabase1.xml"
$newDHCPServer="Dumbo"
$newDHCPServerReplicationPartner="Timothy"

Export-DhcpServer -File $exportFile -Leases -Force -ComputerName $newDHCPServer
Import-DhcpServer -File $exportFile -BackupPath C:\Temp -ScopeOverwrite -Force -ComputerName $newDHCPServerReplicationPartner

# Re-add DHCP Failover: $thisServer as Active with $hdcpPartner as Standby
$newDHCPServer="Dumbo"
$newDHCPServerReplicationPartner="Timothy"
$scopes=(Get-DhcpServerv4Scope).ScopeID.IPAddressToString

# Cleanup all scopes of replication partner
$scopes | % {Remove-DhcpServerv4Scope -ComputerName $newDHCPServerReplicationPartner -ScopeId $_ -Force}

# Authorize Replication Partner
Add-DhcpServerInDc -DnsName $newDHCPServerReplicationPartner

# Setup replication
$scopes | % {Add-DhcpServerv4Failover -ComputerName $newDHCPServerReplicationPartner -Name "$newDHCPServer-and-$newDHCPServerReplicationPartner" -PartnerServer $newDHCPServer -ServerRole Standby -ScopeId $_ -force}
# Reset DHCP on new server
Restart-service dhcpserver -Force
# Authorize new server
$dhcpServerIP='x.x.x.x'
Add-DhcpServerInDc -DnsName $newDHCPServer # Optional switch: -IPAddress $dhcpServerIP
# Verify that the new server DHCP service has been authorized
Get-DhcpServerInDC
# Create security groups named "DHCP Administrators" and "DHCP Users" in Local Users and Groups on the DHCP server
Add-DHCPServerSecurityGroup
# OR
netsh dhcp add securitygroups
# Suppress dhcp post installation alerts
Set-ItemProperty –Path "registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ServerManager\Roles\12" –Name ConfigurationState –Value 2
# Remove DHCP server service on the old machine (while logged into it)
$oldDHCPServername=$ENV:computername
$oldDHCPServerIP=(gwmi Win32_NetworkAdapterConfiguration | ? { $_.IPAddress -ne $null }).ipaddress
netsh dhcp delete server $oldDHCPServername $oldDHCPServerIP
Bonus Section: Enable DNS Dynamic Update via DHCP (optional)
$cred = Get-Credential #Save the service account with privileges to add, delete, and update DNS entries
$dhcpServername="Dumbo"
Set-DhcpServerDnsCredential -Credential $cred -ComputerName $dhcpServername
Set-DhcpServerv4DnsSetting -ComputerName $dhcpServername -DynamicUpdates "Always" -DeleteDnsRRonLeaseExpiry $True
Troubleshooting:
PS C:\Windows\system32> Install-WindowsFeature DHCP -IncludeManagementTools
Install-WindowsFeature : The request to add or remove features on the specified server failed.
Installation of one or more roles, role services, or features failed.
The source files could not be found.
Use the "Source" option to specify the location of the files that are required to restore the feature. For more
information on specifying a source location, see https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/configure-a-windows-repair-source?view=windows-11. Error: 0x800f081f
At line:1 char:1
+ Install-WindowsFeature DHCP -IncludeManagementTools
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (@{Vhd=; Credent...Name=localhost}:PSObject) [Install-WindowsFeature],
Exception
+ FullyQualifiedErrorId : DISMAPI_Error__Failed_To_Enable_Updates,Microsoft.Windows.ServerManager.Commands.AddWind
owsFeatureCommand
Resolution:
# Install Windows Feature Using Local Sources

# Specify ISO Path to automatically generate the rest of the other variables:
$isoPath="\\fs2\it$\Software\ISO's\SW_DVD9_Win_Server_STD_CORE_2016_64Bit_English_-4_DC_STD_MLF_X21-70526.iso"

# Autogen variables:
$isoMount=Mount-DiskImage $isoPath -PassThru
$driveLetter=($isoMount | get-volume).DriveLetter
$index="1" # see the Dism /get-wiminfo section
$wimPath="$driveLetter`:\sources\install.wim:$index"

# Discover the Index Number of the OS that is compatible with the one in question
<#
Dism /get-wiminfo /wimfile:$driveLetter`:\sources\install.wim

Deployment Image Servicing and Management tool
Version: 10.0.14393.3085

Details for image : F:\sources\install.wim

Index : 1
Name : Windows Server 2016 Standard
Description : This option (recommended) reduces management and servicing by installing only what is needed to run most s
erver roles and applications. It does not include a GUI, but you can fully manage the server locally or remotely with Wi
ndows PowerShell or other tools. For more details see "Windows Server Installation Options."
Size : 9,481,916,907 bytes

Index : 2
Name : Windows Server 2016 Standard (Desktop Experience)
Description : This option is useful when a GUI is required—for example, to provide backward compatibility for an applica
tion that cannot be run on a Server Core installation. All server roles and features are supported. For more details see
"Windows Server Installation Options."
Size : 15,560,241,110 bytes

Index : 3
Name : Windows Server 2016 Datacenter
Description : This option (recommended) reduces management and servicing by installing only what is needed to run most s
erver roles and applications. It does not include a GUI, but you can fully manage the server locally or remotely with Wi
ndows PowerShell or other tools. For more details see "Windows Server Installation Options."
Size : 9,473,073,342 bytes

Index : 4
Name : Windows Server 2016 Datacenter (Desktop Experience)
Description : This option is useful when a GUI is required—for example, to provide backward compatibility for an applica
tion that cannot be run on a Server Core installation. All server roles and features are supported. For more details see
"Windows Server Installation Options."
Size : 15,559,908,316 bytes

The operation completed successfully.
#>

# Install DHCP
Install-WindowsFeature DHCP -IncludeManagementTools –Source wim:$wimPath
Install-WindowsFeature RSAT-DHCP –Source wim:$wimPath

# Dismount ISO when done
Dismount-DiskImage -ImagePath $isoPath

Error:

PS C:\Windows\system32> Import-DhcpServer -File $exportFile -BackupPath C:\Temp -ScopeOverwrite -Force -ComputerName $ne
wDHCPServerReplicationPartner –Verbose
Get-DhcpServerVersion : Failed to get version of the DHCP server.
At line:1 char:1
+ Get-DhcpServerVersion -ComputerName $computername 2> $null
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:root/Microsoft/...cpServerVersion) [Get-DhcpServer
Version], CimException
+ FullyQualifiedErrorId : WIN32 1753,Get-DhcpServerVersion

Resolution:

Restart-service dhcpserver -Force

Importing DHCP Scopes to Multiple Replication Partners:

# Notice: this is an untested script. Do Not apply to production until passing quality control

$exportFile="\\FILESHERVER\hdcp\dhcpDatabase1.xml"
$sourceDhcpServer="Genesis"
$newDHCPServerReplicationPartners="John","Luke","Timothy"

write-host "Exporting the new production DHCP database"
# This command must be executed on the RDP or console 0 of Source DHCP server or a SysAdmin localhost
# due to 2-hop security issues with WinRM sessions
$null=mkdir C:\Temp -force
Export-DhcpServer -File $exportFile -Leases -Force -ComputerName $sourceDhcpServer
Install-WindowsFeature RSAT-DHCP

foreach ($newDhcpPartner in $newDHCPServerReplicationPartners){
  if(test-path $exportFile){
    invoke-command -computername $newDhcpPartner -scriptblock{     
      if(!(get-command Import-DhcpServer)){
        write-host "Installing DHCP Server Roles"
        Install-WindowsFeature DHCP -IncludeManagementTools
        Install-WindowsFeature RSAT-DHCP
      }else{
        Restart-service dhcpserver -Force
      }
    }    
    write-host "Importing DHCP database onto $newDhcpPartner"    
    Import-DhcpServer -File $exportFile -BackupPath C:\Temp -ScopeOverwrite -Force -ComputerName $newDhcpPartner
    write-host "Cleaning up all scopes of replication partner $newDhcpPartner"    
    $scopes=(Get-DhcpServerv4Scope).ScopeID.IPAddressToString
    write-host "Cleaning up all scopes of replication partner $env:computername"
    # # Experimental
    # write-host "Purging multiple DHCP scopes on $env:computername"
    # $scopePrefix='10.'
    # $scopeSuffix='.0'
    # for ($i = 0;$i -lt 8;$i++){
    #   for ($j = 0;$j -lt 200;$j++){      
    #     for ($k = 0;$k -lt 255;$k++){      
    #       $scopeId = $scopePrefix + $i.ToString() + '.' + $j.ToString()+ $scopeSuffix+ $k.ToString()        
    #       write-host "Command: Remove-DhcpServerv4Scope -computername $env:computername -ScopeId $scopeId -Force"
    #       #Remove-DhcpServerv4Scope -computername $env:computername -ScopeId $scopeId -Force
    #     }
    #   }
    # }
    $scopes|%{Remove-DhcpServerv4Scope -ComputerName $newDhcpPartner -ScopeId $_ -Force}
    write-host "Authorizing Replication Partner"
    Add-DhcpServerInDc -DnsName $newDhcpPartner
    write-host "Setting up replication"
    $scopes|%{Add-DhcpServerv4Failover -ComputerName $newDhcpPartner \
      -Name "$sourceDhcpServer-and-$newDhcpPartner" \
      -PartnerServer $sourceDhcpServer -ServerRole Standby -ScopeId $_ -force
    }
    write-host "After adding $newDhcpPartner, here's a list of currently authorized DHCP servers:"
    Get-DhcpServerInDC
  }
}