We had an interesting request from one of my customers today where each floor of each site had a number of scopes for different services (voice, data etc) and each scope had a number of specific reservations that they needed to keep. These scopes were configured in a split scope (80/20) using two Server 2012 R2 servers and they wanted to migrate to DHCP failover, using the same servers.
Configuring DHCP failover is not so difficult. See my previous series here for more information on how to set it up. The issue is then how do you merge the split scopes into one with all the reservations, leases and options so that you can then configure failover?
One option is to export the configuration of each server then use the xml files to merge the leases and reservations then re-import back into DHCP. This really is quite cumbersome. The other option we have is to automate it with PowerShell.
Identify requirements
Migrate from 80/20 split scope (on two servers, contdc01 and contdc02) to a single scope configured with DHCP failover running on the same two servers.
Original Setup
Original DHCP pool, leases and reservations on contdc01:
Original DHCP pool, leases and reservations on contdc02:
Required steps
To do this task, we had to split the process down into its required steps then automate each one.
Here, we define what will happen to each of the DHCP servers. One will be the source and one will be the destination.
- Source server: This is the server that we will be copying the leases and reservations from
- Destination server: This server will receive the leases and reservations from the source server and merge them with its own.
These steps are below:
- Back up both servers
- Disable the scope on the source server
- Copy leases from the source server to the destination server
- Copy reservations from the source server to the destination server
- Calculate the start and end IPs for the scope on the destination server
- Remove the scope from the source server
- Set the address pool start and end IPs on the destination server
- Set the exclusion ranges on the destination server and remove the split scope exclusion ranges
- Set up a new failover relationship if it doesn’t already exist
- Configure failover for the scope
PowerShell function
Import this function into your PowerShell window.
function Migrate-DHCPFailover
{
Param(
[Parameter(Mandatory = $true)]
[string] $ScopeId = “”,
[Parameter(Mandatory = $true)]
[string] $SourceServer = “”,
[Parameter(Mandatory = $true)]
[string] $DestinationServer = “”,
[array] $ExclusionRanges = “”,
[string] $SharedSecret = “”
)
$fullBackupPath = “C:TempDHCPFull Backups”
$scopeBackupPath = “C:TempDHCPScope Backups”
$fullBackupPath,$scopeBackupPath | % {if(!(Get-Item $_ -ErrorAction SilentlyContinue)) {New-Item $_ -ItemType Directory | Out-Null}}
#Check to see if the scope exists on both servers:
Write-Host Checking if scope exists on $SourceServer and $DestinationServer -ForegroundColor Green
if ((Get-DhcpServerv4Scope -ComputerName $SourceServer -ScopeId $scopeId -ErrorAction SilentlyContinue) -and (Get-DhcpServerv4Scope -ComputerName $DestinationServer -ScopeId $scopeId -ErrorAction SilentlyContinue))
{
Write-Host Scope Exists on $SourceServer and $DestinationServer -ForegroundColor Green
Write-Host Migrating scope $scopeId -ForegroundColor Green
#Back up both DHCP servers
Write-Host Back up both DHCP servers on $sourceServer and $destinationServer -ForegroundColor Green
$date = Get-Date -Format yyyy-MM-dd-HH-mm-ss
$sourceServer,$destinationServer | % {
$path = $fullBackupPath + $date + “-” + $_ + “.xml”
Export-DhcpServer -ComputerName $_ -File $path -Force
}
#Back up scopes on both servers
Write-Host Back up scope $scopeId on $sourceServer and $destinationServer -ForegroundColor Green
$sourceServer,$destinationServer | % {
$path = $scopeBackupPath + $date + “-” + $_ + “-” + $scopeId + “.xml”
Export-DhcpServer -ComputerName $_ -ScopeId $scopeId -File $path
}
#Disable scope on source server
Write-Host Disable scope on source server -ForegroundColor Green
Set-DhcpServerv4Scope -ComputerName $sourceServer -ScopeId $scopeId -State InActive -Confirm:$false
#Copy leases
Write-Host Copy leases from $sourceServer to $destinationServer -ForegroundColor Green
Get-DhcpServerv4Lease -ComputerName $sourceServer -ScopeId $scopeId | ? {$_.AddressState -notmatch “Reservation”} | Add-DhcpServerv4Lease -ComputerName $destinationServer -ScopeId $scopeId
#Copy reservations
Write-Host Copy reservations from $sourceServer to $destinationServer -ForegroundColor Green
$SourceServerReservations = Get-DhcpServerv4Reservation -ComputerName $sourceServer -ScopeId $scopeId | Add-DhcpServerv4Reservation -ComputerName $destinationServer -ScopeId $scopeId -ErrorAction SilentlyContinue
#Calculate merge of address pool
$Ranges = (((Get-DhcpServerv4Scope -ComputerName $sourceServer -ScopeId $scopeId).StartRange.IPAddressToString -split “.”)[-1] -as [int]),`
(((Get-DhcpServerv4Scope -ComputerName $sourceServer -ScopeId $scopeId).EndRange.IPAddressToString -split “.”)[-1] -as [int]),`
(((Get-DhcpServerv4Scope -ComputerName $destinationServer -ScopeId $scopeId).StartRange.IPAddressToString -split “.”)[-1] -as [int]),`
(((Get-DhcpServerv4Scope -ComputerName $destinationServer -ScopeId $scopeId).EndRange.IPAddressToString -split “.”)[-1] -as [int])
$StartIP = $scopeId.Substring(0,($scopeId.Length-1)) + ($Ranges | sort | select -First 1)
$EndIP = $scopeId.Substring(0,($scopeId.Length-1)) + ($Ranges | sort | select -Last 1)
#Delete scope from source server
Write-Host Delete scope $scopeId from $sourceServer -ForegroundColor Green
Remove-DhcpServerv4Scope -ComputerName $sourceServer -ScopeId $scopeId -Force -Confirm:$false
#Set address pool on destination server
Set-DhcpServerv4Scope -ComputerName $DestinationServer -ScopeId $ScopeId -StartRange $StartIP -EndRange $EndIP
#Set exclusion ranges on destination server
Get-DhcpServerv4ExclusionRange -ScopeId $scopeId -ComputerName $DestinationServer | Remove-DhcpServerv4ExclusionRange -Confirm:$false
foreach($exclusionRange in $exclusionRanges)
{
$startIP = ($exclusionRange -split “-“)[0]
$endIP = ($exclusionRange -split “-“)[-1]
Add-DhcpServerv4ExclusionRange -ScopeId $scopeId -ComputerName $DestinationServer -StartRange $startIP -EndRange $endIP
}
#Add DHCP failover on the destination server to use source server as failover, 50:50 load balancing with autostate switchover set to 60mins and MCLT set to 60mins
Write-Host Add DHCP failover on the $destinationServer to use $sourceServer as partner -ForegroundColor Green
if (Get-DhcpServerv4Failover -ComputerName $destinationServer -Name $destinationServer-$sourceServer -ErrorAction SilentlyContinue)
{
Write-Host Failover relationship already exists -ForegroundColor Green
#Add DHCP failover for scope
Add-DhcpServerv4FailoverScope -ComputerName $destinationServer -Name $destinationServer-$sourceServer -ScopeId $scopeId -Verbose
}
else
{
Add-DhcpServerv4Failover -ComputerName $destinationServer -ScopeId $ScopeId -Name $destinationServer-$sourceServer -PartnerServer $sourceServer -MaxClientLeadTime 01:00:00 -AutoStateTransition $true -StateSwitchInterval 01:00:00 -SharedSecret $SharedSecret -Force
}
}
else
{
Write-Host Scope $scopeId does not exist -ForegroundColor Red -ForegroundColor Green
}
}
Run the PowerShell function
We ran the function as below:
Migrate-DHCPFailover -ScopeId 10.0.1.0 -SourceServer contdc02 -DestinationServer contdc01 -ExclusionRanges 10.0.1.1-10.0.1.1 -SharedSecret Secret1
Check settings
When done, we checked to ensure that the settings, leases and reservations were copied over.
Pool, leases and reservations on contdc01 are below. You can see that the leases and reservations were copied over from contdc02 and also that the exclusion ranges were configured:
On contdc02, the exclusion ranges, leases and reservations are the same as contdc01: