Script to perform update and synchronisation of DHCP Mac Filter List for Microsoft DHCP Server releases prior to 2008 R2

System Requirements:

  • Windows Server 2008 (R1)
  • Microsoft DHCP Server
  • Microsoft Mac Level Filter extension

The Problem:

If you are using a Microsoft DHCP Server release prior to Windows Server 2008 R2, Mac Address filtering (either allow or deny based) is not included as part of the main console. Microsoft made the feature available as an extension DLL for Microsoft DHCP during Windows Server 2008 (R1)’s early production run.

If you have installed this extension, filtering is restricted to a single server, with no replication options available to peer servers through clustering. This article offers a simple script that can be used to suspend and update a peer server’s Mac Filter list in a master/slave relationship.

The Fix

The script assumes that you have enabled file sharing through your firewall between the servers and that the MAC address filter configuration file is located at c:\windows\system32\dhcp\MACList.txt.

The format of MACList.txt is

#MACList.txt
MAC_ACTION={DENY}
#List of MAC Addresses to deny
001BB04EB711 - # -mypc6 - 192.168.1.28
002BBB831711 - # -mypc7 - 192.168.1.96

Batch script:

@echo off
set TARGET=<hostname/IP of slave server/peer>
cls echo.echo Opening Notepad
echo.
echo Make changes to the file, save and exit. The changes will be
echo replicated to %TARGET% automatically.
echo.
echo Note: This will interrupt DHCP Services for a few seconds on both servers.echo. c:\Windows\system32\notepad.exe "C:\Windows\System32\dhcp\MACList.txt"

:: Stopping DHCP Server Service on Local System
echo.
echo Applying Changes to Local DHCP Service
net.exe stop DHCPServer
echo.

echo Stopping DHCP Server Service on %TARGET%
:: Restart DHCP Server on Target
sc.exe \\%TARGET% stop "DHCPServer"

ping 127.0.0.1 > null echo.

echo Copying MAC List to %TARGET%
copy /y "C:\Windows\System32\dhcp\MACList.txt" "\\%TARGET%\C$\Windows\System32\dhcp\MACList.txt"

:: Starting DHCP Server Service on Local System
net.exe start DHCPServer

:: Starting DHCP Server Service on %TARGET%
sc.exe \\%TARGET% start "DHCPServer"

echo Operation completed. Please periodically check to ensure sync is stable.

In short, the script:

  1. Offers you a notepad session to make any needed changes
  2. When notepad closes it will restart the local servers DHCP service (thus applying the changes locally)
  3. Shutdown the peer servers DHCP service
  4. Copy the updated MAC filter list
  5. Restart the peer servers DHCP service
  6. Terminate

To add a level of safety, the following script can be run periodically to ensure that the DHCP service is in fact running

@echo off
sc interrogate DHCPServer 2>NUL | find /I /N "4 RUNNING">NUL
if "%ERRORLEVEL%"=="0" (
  echo DHCP Service is running
) else (
  echo DHCP Service is not running!!!!!
  net start DHCPServer
)

Windows Server 2012 R2 DHCP Failover services do not synchronise MAC Address Filters between partner servers

System Requirements:

  • Windows Server 2012 R2
  • Windows DHCP Server

The Problem:

If you are making use of the new failover features integrated into the Windows DHCP Server service in Windows Server 2012, should you also be using either positive or negative MAC address filtering for client leases, you may have already noticed (or may be surprised to discover) that the DHCP Filters table is not replicated as part of the failover configuration.

Barred clients will continue to be addressed from the peer server and after replication the Filters sections of the DHCP console on the secondary server will remain frustratingly empty.

More Info

The Microsoft DHCP Server team have this to say on the subject

“DHCP failover does not provide for replication of server level/wide configuration. Allow/Deny MAC filter is a server level/wide configuration. The reason this is not provided for is because a DHCP serve can participate in more than one failover relationships with different partner DHCP servers. In such scenarios, replicating server level configuration can lead to undesirable resultant server level/wide configuration. If your server has a single failover relationship or a allow/deny MAC address filter list that applies to all servers, you can setup a regular sync between the DHCP servers by writing a simple PowerShell script and integrating it with Windows Task Scheduler so that it runs on a periodic basis.”
teamdhcp (Technet, 2013)

In other words, you may be using filtering to dictate onto which DHCP server your clients will be forced to land. In which case you would not want the filters list to be replicated. For users who are simply using the filtering as a way to reduce the risk of rogue hosts, you would want the opposite behaviour.

Additionally, as replicate is per-scope, under the current replication model, your filter list would have to be duplicated for n scopes in order to work in a multi-scope environment. To that end, I can see Microsoft’s point, however the missed opportunity of a configurable option for how the system administrator wants to manage server setting replication would have made the Redmond DHCP team veritable princes.

The Fix

So, yes, Microsoft’s reply suggests that we can use PowerShell to do this (be it less ideal) and yes we can.

This simplified script is designed to be run on the secondary (slave) server. It does not perform a synchronisation, instead it clears its own database and then copies the database of the partner (master) server.

# PowerShell DHCP Filter Replication Script 1.0.0
# (c) C:Amie 2014
# http://www.c-amie.co.uk/$MasterServerHostname = "MyServerHostname";# Get the LOCAL filters from localhost
$lfilters = Get-DhcpServerv4Filter

# Get the REMOTE filters from $MasterServerHostname
$rfilters = invoke-command -computername $MasterServerHostname { Get-DhcpServerv4Filter }

# Delete the local Filter Set
ForEach ($filter in $rfilters) {
Remove-DhcpServerv4Filter -MacAddress $filter.MacAddress
}

# Import the new Filter Set
ForEach ($filter in $rfilters) {
write-host $filter.List
write-host $filter.MacAddress;
write-host $filter.Description
Add-DhcpServerv4Filter -List $filter.List -MacAddress $filter.MacAddress -Description $filter.Description
}

You will need to setup remote PowerShell access using Set-Item TrustedHosts <Hostname> / WinRm in order to allow remote connectivity between your server peers.

You must also remember that as the above does not perform a synchronisation, if you make filter changes on a secondary (slave) server, they will be lost at the next execution.

Finally, schedule the script to run as required through task scheduler using the following as the Program/script name in the Basic Task setup

powershell -file "x:\path\Script.ps1"

Hardening Steps

While this works, it is simplistic at best and presents a couple of problems.

Firstly, you should be mindful that the script will create a very small window of opportunity in which the server will potentially be in a filterless state. During this time, it may be able to respond to a DORA request from a unwanted node. If this is the case, you should disable any Scopes on the server, perform the filter sync and then re-enable the scope. If you wanted to do that the necessary script modification would be

# PowerShell DHCP Filter Replication Script 1.0.1
# (c) C:Amie 2014
# http://www.c-amie.co.uk/$MasterServerHostname = "MyServerHostname";
$ScopeId = 192.168.1.0;# Stop the DHCP Scope on the LOCAL server from leasing
Set-DhcpServerv4Scope -ScopeId $ScopeId -State "Inactive"

# Get the LOCAL filters from localhost
$lfilters = Get-DhcpServerv4Filter

# Get the REMOTE filters from $MasterServerHostname
$rfilters = invoke-command -computername $MasterServerHostname { Get-DhcpServerv4Filter }

# Delete the local Filter Set
ForEach ($filter in $rfilters) {
Remove-DhcpServerv4Filter -MacAddress $filter.MacAddress
}

# Import the new Filter Set
ForEach ($filter in $rfilters) {
write-host $filter.List
write-host $filter.MacAddress;
write-host $filter.Description
Add-DhcpServerv4Filter -List $filter.List -MacAddress $filter.MacAddress -Description $filter.Description
}

# Start the DHCP Scope on the LOCAL server
Set-DhcpServerv4Scope -ScopeId $ScopeId -State "Active"

The second problem is that the script itself executes in a linear fashion. It assumes that the partner server is always going to be on-line and available for processing. The problem here is that if the server is offline or isn’t able to service the sync request, it will have deleted the local filters list before the process of connecting to the peer server fails. At which point the server will void ofany filtering what so ever.

This can be hardened by introducing two credibility checks as follows:

# PowerShell DHCP Filter Replication Script 1.0.2
# (c) C:Amie 2014
# http://www.c-amie.co.uk/$MasterServerHostname = "MyServerHostname";
$ScopeId = 192.168.1.0;if (Test-Connection $MasterServerHostname -quiet) {

# Get the LOCAL filters from localhost
$lfilters = Get-DhcpServerv4Filter

# Get the REMOTE filters from $MasterServerHostname
$rfilters = invoke-command -computername $MasterServerHostname { Get-DhcpServerv4Filter }

if ($rfilters) {

# Stop the DHCP Scope on the LOCAL server from leasing
Set-DhcpServerv4Scope -ScopeId $ScopeId -State "Inactive"

# Delete the local Filter Set
ForEach ($filter in $rfilters) {
Remove-DhcpServerv4Filter -MacAddress $filter.MacAddress
}

# Import the new Filter Set
ForEach ($filter in $rfilters) {
write-host $filter.List
write-host $filter.MacAddress;
write-host $filter.Description
Add-DhcpServerv4Filter -List $filter.List -MacAddress $filter.MacAddress -Description $filter.Description
}

}

# Start the DHCP Scope on the LOCAL server
Set-DhcpServerv4Scope -ScopeId $ScopeId -State "Active"

}

In this version we perform a ping test on the Master Server (ICMP firewall settings required for success) and we check to see whether the $rFilters variable is set before deleting the contents of the local filters database. Finally, regardless of what happens, the resultant state of the server scope should remain active.