Sunday, 16 August 2015

Migrate 80/20 (split scope) to DHCP Failover

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:
  1. Back up both servers
  2. Disable the scope on the source server
  3. Copy leases from the source server to the destination server
  4. Copy reservations from the source server to the destination server
  5. Calculate the start and end IPs  for the scope on the destination server
  6. Remove the scope from the source server
  7. Set the address pool start and end IPs on the destination server
  8. Set the exclusion ranges on the destination server and remove the split scope exclusion ranges
  9. Set up a new failover relationship if it doesn't already exist 
  10. 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:\Temp\DHCP\Full Backups\"
        $scopeBackupPath = "C:\Temp\DHCP\Scope 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:




4 comments:

  1. These steps are below:
    1.Back up both servers
    2.Disable the scope on the source server
    3.Copy leases from the source server to the destination server
    4.Copy reservations from the source server to the destination server
    5.Calculate the start and end IPs for the scope on the destination server
    6.Remove the scope from the source server
    7.Set the address pool start and end IPs on the destination server
    8.Set the exclusion ranges on the destination server and remove the split scope exclusion ranges
    9.Set up a new failover relationship if it doesn't already exist
    10.Configure failover for the scope


    Are the steps above mentioned steps that we can do thru GUI instead of going with your powershell steps?

    ReplyDelete
  2. Also, do I need to deauthorize or turn off dhcp services on the secondary server before reassigning it as failover or will it be clean once I delete the scopes?

    ReplyDelete
  3. Great script, but the part 'Calculate merge of address pool' doesn't work correctly. It should take the lowest/first address from both servers as the new scope's start address and the highest/last address from both server as the end ip.

    ReplyDelete
  4. Could I migrate one scope at a time? I'm going to be doing this probably in the next week or so and would prefer this method.

    ReplyDelete