Friday, 28 August 2015

Sender ID filtering or IP block list not working

When Exchange receives an email from the internet, it records the IP of the connecting server. This may be the sender's SMTP server or your own non-Exchange mail filter.

You need to ensure that Exchange works out the correct sending IP so that it can correctly process anti-spam measures that require the sending IP to be checked such as sender ID filtering and IP block list.

If you're finding that sender ID filtering and IP block lists are not working correctly then it's likely that your Exchange Transport configuration doesn't have a list of the internal SMTP servers. The internal SMTP servers need to include the email gateway servers/smart hosts for incoming email that should be ignored.

For example, if your email passes through the SMTP servers and before reaching your Exchange servers then you need to use the Set-TransportConfig cmdlet as below to set these as internal SMTP as well as other Exchange servers so Exchange ignores them when processing the SenderID and connection filtering transport agents:

Set-TransportConfig -InternalSMTPServers,

Now this is set, Exchange ignores these IPs and looks for the client IP in the message header when processing the anti-spam agents. You'll also not see these IPs as client IPs on the messages in the message tracking logs.

If you're not using an email gateway/smart host and you only have one Exchange server then you should set the InternalSMTPServers property to

More information here:

SPF maximum DNS lookups

To prevent DNS amplification attacks where a sender has configured an SPF record that requires a large number of DNS lookups, there is a limit set on the number of DNS lookups that can be required to process an SPF record. RFC 7208 states the below:

"SPF implementations MUST limit the total number of those terms to 10 during SPF evaluation, to avoid unreasonable load on the DNS. If this limit is exceeded, the implementation MUST return "permerror"."

DNS lookups are required each time you use the mx, a, ptr or include mechanisms in your SPF record. To reduce the number of lookups required, use the ip4 or ip6 mechanisms. If you have a large number of IPs then look at specifying subnets rather than each IP individually.

Multiple SPF records for one domain

When creating SPF records, you must only create one per domain as per RFC 7208 which states the below in section 3:

"multiple SPF records are not permitted for the same owner name"

Read RFC 7208 here:

If you have more than one server that sends email for a particular domain, you should merge the IPs into a single SPF record and not create more than one record. 

For more information on SPF records, see my two part article here.

Wednesday, 26 August 2015

ActiveSync debug logging in Exchange 2013

An issue happened the other day where we had a particular ActiveSync device where the email would occasionally remain in the outbox. To troubleshoot ActiveSync devices in detail, you need to enable ActiveSync debug logging for the user account. See below. 

Enable ActiveSync debug logging on a mailbox:

Set-CASMailbox user1 -ActiveSyncDebugLogging:$true

Confirm that debug logging is enabled:

Get-CASMailbox user1 -ActiveSyncDebugLogging | fl name,*logg*

Reproduce issue then output log file to clipboard:

Get-MobileDeviceStatistics -Mailbox user1 -GetMailboxLog:$true | clip

Recreate mailbox in Exchange 2010 and 2013

The below script can be used to recreate a mailbox in Exchange. This has been useful because we had an issue where we had to do this for an entire business as recommended by Microsoft because they moved from on premises Exchange to Office 365 then were upgraded/downgraded to a different version of on premises Exchange.
The script does the below tasks:

  • Gets the user details
  • Exports user groups
  • Gets user OU
  • Gets mailbox database
  • Exports calendar permissions
  • Exports mailbox permissions
  • Exports send as permissions
  • Gets email addresses and whether hidden from address lists
  • Gets permissions the user had on other mailboxes
  • Gets send as permissions the user had on other mailboxes
  • Gets calendars that the user had access to 
  • Exports email to PST
  • Recreates user account
  • Re-assigns all above permissions
  • Re-assigns all email addresses
  • Imports email from PST
Run the script as below. NB, you need to create a share with read/write permissions for the Exchange Trusted Subsystem to be used by the mailbox export process.

.\Recreate-Mailbox.ps1 -Mailboxes user1,user2,user3 -TempPSTLocation \\localhost\temp$ -ExchangeServer Server1

The script can be downloaded here: 

Tuesday, 25 August 2015

Understanding SPF Records (Part 2)


In part 1, we went through how to create a basic SPF record. In this part, we'll discuss the other options that are available when using SPF records.


The A method informs the recipient email server to check A records for your SMTP domain ( in these examples) or you can specify another domain to check for A records. For each option, you can specify whether you want to include all IPs in the subnet for each A record. Examples are below:

Include all A records for your SMTP domain:

v=spf1 a -all

Include all A records for your SMTP domain and also include all IPs in the /24 subnet for each IP that the A records reference:

v=spf1 a/24 -all

Include all A records for your SMTP domain and A records for another domain:

v=spf1 a -all

Include A records for your SMTP domain, A records for another domain and also include the IPs in the /24 subnet for each A record:

v=spf1 a/24 -all


The include method informs the receiving email server that another SPF record should be checked. This is useful in larger organizations where different teams manage the public facing SMTP servers for different regions or datacenters and you want to allow these teams to manage their own permitted sending IPs.

To do this, you can use a 'top level SPF' record and include 'sub-SPF' records. All permitted senders in all sub-SPF records will be checked when evaluating whether the email is sent from a permitted sender.

For example, you have two datacenters and your sending domain is

Datacenter A: 
Permitted senders:

Datacenter B: 
Permitted senders:

Step 1: Create the top level SPF record

Your top level SPF record will be configured as a TXT record on

v=spf1 -all

Step 2: Create DNS zones

You then need to create two public DNS zones: and 

Step 3: Configure the additional SPF records

Datacenter A: Configure this SPF record as a TXT record on zone

v=spf1 ip4: -all

Datacenter B: Configure this SPF record as a TXT record on zone

v=spf1 ip4: -all

Step 4: Confirm SPF records exist

To confirm the SPF records, you can use nslookup, specify the lookup type to be TXT and then check the SPF records for three domains:, and See below:


When specifying MX, the recipient checks the IPs of the MX records for your domain and if they match the IP of the sending SMTP server, the sender is verified and the email is allowed. To include just the MX records for your SMTP domain, use the below:

v=spf1 mx -all

You can also specify the MX records of a different SMTP domain. This is useful if you are using a domain only for sending email and don't have any MX records but you are sending email from IPs that are MX records for a different domain. 

For example, if your sending email from SMTP domain using the same IPs as the MX records for and not sending from any other IPs then you would use the below SPF record:

v=spf1 -all

You can also specify that you want to include all IPs in the /24 subnet of each MX record. In this case, you use an SPF record as below:

v=spf1 mx/24 -all

If you want to both specify that the entire subnet can send email, use MX records from different domains ( and and their associated /24 subnets while also using your own MX records and associated /24 subnets, you'd use the below SPF record:

v=spf1 mx/24 -all


In this part, we looked at the more advanced options we can configure in the SPF record. In the next part, we'll take a look at how to troubleshoot SPF records which is useful if your email is being marked as spam or you are marking other senders as spam when doing SPF checks. 

More information is here.

Understanding SPF Records (Part 1)


In this post, we'll take a look at what SPF records are and how to create a basic SPF record that is what most messaging infrastructures require.

When people worked out they can send email from other people's email addresses (spoofing) using other SMTP servers and tools like bmail, Send-MailMessage or others, SPF was invented to prevent this. This is in addition to reverse DNS.

SPF stands for Sender Policy Framework and it is configured by the owner of the sending domain as a TXT record in DNS.

Basic SPF Record

To work out what your SPF record should include, the basics are that it should include all public IPs that are configured to send email using your domain name. For example, we are sending email from and are using the below IPs and the MX records for the domain to send email:


We also want to ensure that email from any other IP is prohibited.

Step 1: Specify your SPF version number

The first section is the SPF record version number. This should be version 1 currently. Our SPF record therefore starts with this:


Step 2: Configure permitted senders

To add the list of IPs and MX records to your SPF record as permitted senders, our SPF record now looks like this:

v=spf1 ip4: ip4: ip4: mx

If we were only sending from the same IPs as your MX records then we don't need to include any ip4 entries and can just use this:

v=spf1 mx

Step 3: Specify action

We then need to specify what the recipient does with a message that is sent from an IP that's not listed in the SPF record. We can choose from the below options:

We want to prohibit all senders that are not on our SPF record so we add -all to the end of the record. Therefore our completed SPF record is below:

v=spf1 ip4: ip4: ip4: mx -all

Step 4: Publish the SPF record

The SPF record is held in a TXT record that needs to be added to our public DNS zone. If we were using split DNS then we should add this TXT record to the DNS zones on our internal DNS servers also in case our SMTP relays are using these internal DNS servers for SPF record lookups. 

Step 5: Confirm the SPF record exists

Once this is done, we can check that it exists by using nslookup. We need to specify the query type as TXT then type in the SMTP domain:


Now we are able to create basic SPF records for our domains, we can move on to understanding advanced SPF records which is useful when troubleshooting bouncebacks. See part 2.

Saturday, 22 August 2015

DHCP Client Behaviour

In this post, we'll take a look at how DHCP clients behave when they are getting new IPs or renewing their lease or when they cannot renew their lease because the DHCP server is unavailable. 

DHCP Messages

DHCP has a number of standard messages that can be sent/received between the server and the client. These are below:

Obtaining a new lease

When a client connects to a new network or a network it was on currently where its lease has expired, it needs to get a new lease. First a DHCPDISCOVER message is sent (broadcast). The server then replies with a DHCPOFFER message which is also a broadcast message as the client doesn't yet have an IP on the same subnet as the server. From here, a DHCPREQUEST message is sent by the client which is then acknowledged by the server as a DHCPACK message. The client can then use the IP and has received a list of options to use. The process is summarised below:

  1. DHCPDISCOVER (client > server)
  2. DHCPOFFER (server > client)
  3. DHCPREQUEST (client > server)
  4. DHCPACK (server > client)

Renewing a lease

When renewing a lease, the DHCP converstation is below:

  1. DHCPREQUEST (client > server)
  2. DHCPACK or DHCPNACK (server > client)

The client sends a DHCPREQUEST which is unicast this time as the client already has a valid IP address. The server then responds with DHCPACK if the IP is still available to the client or DHCPNACK if the client is to have another IP. 

Renewing a lease is first attempted when the client has had the lease for 50% of the total lease period. It first attempts to contact the DHCP server that leased the IP. If this DHCP server is not available then it'll wait till 7/8 of the lease is up before sending a broadcast message to find any other available DHCP server. This is in fact what happens in the case of a DHCP failover where the server that assigned the IP to the client is now offline. For more information, see my three part series on DHCP failover here.

Below is a network capture using Message Analyzer showing my laptop receiving a DHCPACK message. You can see a DHCPACK message from the server which shows that the lease is 28800s and the time to renew is 14400 and the second time to renew is 25200 (28800 * 7/8). You can also see the server address and the DHCP options (DomainName, Router and DomainNameServer).

DHCP server unavailable

When the DHCP server is unavailable, the client keeps trying to access it. It does this by sending DHCPDISCOVER packets in this pattern which repeats every 5mins:

On restart, the client will usually try to get a new lease however if the DHCP server is not available, it doesn't fall back to the alternate or APIPA address (Automatic Private IP Address, if it can still ping the default gateway and there is time on the lease. It uses the default gateway to identify the network and if it can find it then it assumes it's on the same network it was on before it was restarted.

APIPA and alternate addresses

If there is no time on the lease or the default gateway is unavailable, the client uses the alternate address it was configured with or it uses an APIPA address. Before using either address, the client uses ARP to ensure that the address is not in use. 

When using either an alternate or APIPA address, the client will continue trying to contact a DHCP server every 5mins to get a lease. 


In this post, we looked at the way DHCP clients and servers communicate and what happens in the scenarios where there is no DHCP server available. For more information, see the articles below. 

Exchange 2013 system requirements and sizing

When designing an Exchange 2013 deployment, you need to ensure that it's sized correctly. Here's the blog I use to size up my deployments:

It does require you to know how many emails are sent and received per day per user.

I've created a script that will provide the number and size of each email sent for a specified period. You can use this to get the information you need. See script here.

Thursday, 20 August 2015

PowerShell Subnet Calculator

I'm often faced with situations when I need to scan entire subnets to find devices and either perform an inventory or run a remote PowerShell command on all the devices on a subnet. It's quite simple to generate the list of IPs for a /24 subnet but is a little trickier for the other subnets, e.g. a /12. Anyways, long story short. Here is a PowerShell function that will output an array of all the IPs on a particular subnet. 

You can run it as below:

Get-IPs -Subnets "",""

For example:

You can then pipe out the IPs so you can run a command on each:

Get-IPs -Subnets "","" | % {Do something on $_}

The function is below. Happy scripting.

function Get-IPs {

        [Parameter(Mandatory = $true)]
        [array] $Subnets

foreach ($subnet in $subnets)
        #Split IP and subnet
        $IP = ($Subnet -split "\/")[0]
        $SubnetBits = ($Subnet -split "\/")[1]
        #Convert IP into binary
        #Split IP into different octects and for each one, figure out the binary with leading zeros and add to the total
        $Octets = $IP -split "\."
        $IPInBinary = @()
        foreach($Octet in $Octets)
                #convert to binary
                $OctetInBinary = [convert]::ToString($Octet,2)
                #get length of binary string add leading zeros to make octet
                $OctetInBinary = ("0" * (8 - ($OctetInBinary).Length) + $OctetInBinary)

                $IPInBinary = $IPInBinary + $OctetInBinary
        $IPInBinary = $IPInBinary -join ""

        #Get network ID by subtracting subnet mask
        $HostBits = 32-$SubnetBits
        $NetworkIDInBinary = $IPInBinary.Substring(0,$SubnetBits)
        $HostIDInBinary = $IPInBinary.Substring($SubnetBits,$HostBits)

        #Work out all the host IDs in that subnet by cycling through $i from 1 up to max $HostIDInBinary (i.e. 1s stringed up to $HostBits)
        #Work out max $HostIDInBinary
        $imax = [convert]::ToInt32(("1" * $HostBits),2) -1

        $IPs = @()

        #Next ID is first network ID converted to decimal plus $i then converted to binary
        For ($i = 1 ; $i -le $imax ; $i++)
                #Convert to decimal and add $i
                $NextHostIDInDecimal = ([convert]::ToInt32($HostIDInBinary,2) + $i)
                #Convert back to binary
                $NextHostIDInBinary = [convert]::ToString($NextHostIDInDecimal,2)
                #Add leading zeros
                #Number of zeros to add 
                $NoOfZerosToAdd = $HostIDInBinary.Length - $NextHostIDInBinary.Length
                $NextHostIDInBinary = ("0" * $NoOfZerosToAdd) + $NextHostIDInBinary

                #Work out next IP
                #Add networkID to hostID
                $NextIPInBinary = $NetworkIDInBinary + $NextHostIDInBinary
                #Split into octets and separate by . then join
                $IP = @()
                For ($x = 1 ; $x -le 4 ; $x++)
                        #Work out start character position
                        $StartCharNumber = ($x-1)*8
                        #Get octet in binary
                        $IPOctetInBinary = $NextIPInBinary.Substring($StartCharNumber,8)
                        #Convert octet into decimal
                        $IPOctetInDecimal = [convert]::ToInt32($IPOctetInBinary,2)
                        #Add octet to IP 
                        $IP += $IPOctetInDecimal

                #Separate by .
                $IP = $IP -join "."
                $IPs += $IP


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 

          [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
                    Add-DhcpServerv4Failover -ComputerName $destinationServer -ScopeId $ScopeId -Name $destinationServer-$sourceServer -PartnerServer $sourceServer -MaxClientLeadTime 01:00:00 -AutoStateTransition $true -StateSwitchInterval 01:00:00 -SharedSecret $SharedSecret -Force
                Write-Host Scope $scopeId does not exist -ForegroundColor Red -ForegroundColor Green


Run the PowerShell function

We ran the function as below:

Migrate-DHCPFailover -ScopeId -SourceServer contdc02 -DestinationServer contdc01 -ExclusionRanges -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:

DHCP Failover in Server 2012 R2 (Part 3)

In Part 2, we looked at how to configure DHCP failover using the DHCP Management Console. In this part, we'll look at how to do the same task but using PowerShell.

Server infrastructure

This test lab includes the below servers:

  • Contdc01
  • Contdc02

Planned configuration

Here we’ll walk through how to configure DHCP failover. Our requirements are below:

  • Scope
  • Failover mode: Load balance mode (50:50)
  • Automatic failover


To create a failover relationship for two standalone DHCP Servers, this requires:

  • two DHCP servers
  • a unique failover relationship name
  • a DHCP scope on only one of the DHCP servers to configure failover for (this is because the scope will be created on the other DHCP server)

How to configure failover using PowerShell

To configure DHCP failover for our scope,, we use the Add-DhcpServerv4Failover cmdlet and specify the settings we would like. We are running this command on contdc01 which is where we already have a scope configured. 

  • Failover Relationship Name: contdc01-contdc02
  • Partner server: contdc02
  • Scope ID:
  • State Switchover Interval: 1hr
  • Shared Secret: Password1

Add-DhcpServerv4Failover -Name "contdc01-contdc02" -PartnerServer contdc02 -ScopeId -StateSwitchInterval 1:00:00 -SharedSecret Password1 -Force

Once done, we can confirm that DHCP failover was configured correctly by checking that the scope exists on both servers. We use Get-DhcpServerv4Scope to do this and specify each of the server names:

Get-DhcpServerv4Scope -ComputerName contdc01
Get-DhcpServerv4Scope -ComputerName contdc02

The output shows a list of scopes on each server: 

To confirm the settings, we can use Get-DhcpFailover and specify the servers in turn so we can confirm our settings are correct and that they have replicated to the other server:

Get-DhcpServerv4Failover -ComputerName contdc01
Get-DhcpServerv4Failover -ComputerName contdc02


In this post, we've looked at how to configure DHCP failover using PowerShell which is much quicker and quite easy to script.

DHCP Failover in Server 2012 R2 (Part 2)

In Part 1, we looked at how DHCP failover works and now should have a good understanding. In this article, we’ll take a look at how to configure DHCP failover between two DHCP servers. One has a scope which we want to configure failover for, using the other server for failover.

Server infrastructure

This test lab includes the below servers:

  • Contdc01
  • Contdc02

Planned configuration

Here we’ll walk through how to configure DHCP failover. Our requirements are below:

  • Scope
  • Failover mode: Load balance mode (50:50)
  • Automatic failover


To create a failover relationship for two standalone DHCP Servers, this requires:

  • two DHCP servers
  • a unique failover relationship name
  • a DHCP scope on only one of the DHCP servers to configure failover for (this is because the scope will be created on the other DHCP server)

How to configure failover using the GUI

These instructions are for the DHCP MMC snap-in.

1) Open the DHCP MMC snap-in

2) Create a DHCP scope as normal on one of the two servers and set your scope options and DHCP reservations if not done already.

3) Right click the IPv4 node and click on Configure Failover:

4) Select the DHCP scopes you would like to configure for failover then click next

5) Add the partner DHCP server and click next

6) Here we’ll create a new failover relationship. We’ll configure:

  • Relationship Name
  • Maximum Client Lead Time: 1hr (default)
  • Mode: Load balance (default)
  • Load Balance Percentage: 50:50 (default)
  • State Switchover Interval: 1hr (we set this so that the server progresses from COMMUNICATIONS INTERRUPTED to PARTNER DOWN state automatically so it doesn’t require administrator intervention before failing over)
  • Shared Secret (this is used to authenticate messages between the servers)

7) Once done, confirm the stings and click Finish:

8) On the completion window, click Close:

We can then confirm that the scope exists on the partner server. All scope options, reservations and leases should be copied over. See below.


In this post, we looked at how to configure DHCP failover for a scope using the DHCP Management Tools. In Part 3, I'll run through how to configure DHCP failover with PowerShell.