HOWTO: Automated DHCP Backups

I created the script below to back up the DHCP servers in our environment, set it up as a nightly scheduled task and then frankly forgot about it.  That is until a few days ago when due to a power outage, we lost a DHCP server that refused to boot once power was restored.  Thanks to this script, restoring my DHCP server was trivially easy.  Since it so greatly saved the day for me, I wanted to make it available to you as well.

 

To restore from these backups, complete the following few steps:

1) Copy the backup file to the DHCP server you wish to restore to
2) Ensure the DHCP role is installed
3) open an administrative command prompt and run the following command:
netsh dhcp server import [path to file] all

The DHCP scope, configuration and lease information should now be restored.

Oh and I almost forgot to mention the best part.  This script does not require configuration.  Just run it and it’ll automatically go out and find all of the Active Directory authorized DHCP servers in your entire Domain and back them all up automatically to a central store.  (Ok, so you have to define that).  This worked especially well when after I rebuilt my new DHCP server I was surprised to discover it had already been backed up!

 

# Automatically backs up the DHCP database of all Active Directory Integrated DHCP Servers on the Network
# DHCP; Backup; Active Directory; Psexec; netsh;

# AUTOMATED DHCP BACKUP SCRIPT v1.5#
# REQUIRES REMOTE ADMINISTRATION TOOLS TO FUNCTION #
# ALSO REQUIRES THAT THE PSEXEC EULA BE ALREADY ACCEPTED FOR THE SVCAUTOMATION SERVICE ACCOUNT (-ACCEPTEULA DIDN'T SEEM TO WORK) #

# SET THE BACKUP SERVER LOCATION TO WRITE THE BACKUPS TO#
$PSexecPath = "[PATHTOPSEXEC]\psexec.exe"
$BackupServer = "[\\[PATHTODHCPBACKUPS]"

# CREATE AN EMPTY ARRAY TO STORE THE DHCP SERVERS THAT RESPOND TO PING #
# NEEDED BECAUSE OUR AD INCLUDES A NUMBER OF OBSOLETE DHCP SERVERS #
# WILL CLEAN THOSE UP ANOTHER DAY #
$DHCPServersThatPing = @()

# CLEAR ALL USED VARIABLES #
$ActiveDHCPServers = ""
$AuthorizedDHCPServers = ""
$DHCPServerNames = ""

# GET A LIST OF AUTHORIZED DHCP SERVERS #
# NOTE THAT IF DHCP IS NOT INSTALLED LOCALLY, THIS COMMAND REQUIRES THE REMOTE SERVER ADMINISTRATION TOOLS (RSAT) AND THE DHCP TOOLS SELECTED #
$AuthorizedDHCPServers = & netsh dhcp show server

# EXTRACT THE SERVER IPS FROM THIS LIST #
# SKIP 3 REMOVES THE SPACES AND THE "## SERVERS FOUND" LINE.  THE COUNT-1 REMOVES THE COMPLETED SUCESSFULLY #
$DHCPServerNames = $AuthorizedDHCPServers | select -skip 3 | select -First ($AuthorizedDHCPServers.Count-1) |foreach {($_ -split'\s+',5)[2]}

# REMOVE THE SQUARE BRACKETS AROUND THE NAMES #
$DHCPServerNames = $DHCPServerNames -replace "\["
$DHCPServerNames = $DHCPServerNames -replace "\]"

# GET RID OF THE BLANKS THAT WERE RETURNED BY THE NETSH COMMAND #
$DHCPServerNames = $DHCPServerNames | Where-Object {$_ -ne ""}

# LOOP THROUGH EACH DHCP SERVER FOUND AND EXTRACT ONLY THOSE THAT RESPOND TO PING #
foreach ($DHCPServer in $DHCPServerNames)
    { If (Test-Connection -comp $DHCPServer -count 1 -quiet) { $DHCPServersThatPing += $DHCPServer } }

# REMOVE THE FOCUSCORP.CA SUFFIX SO WE CAN USE THE SAME VARIABLE FOR THE FOLDER NAME AND SELECT ONLY UNIQUE NAMES #
# WE HAVE TWO ENTRIES FOR FSRVCLODC1 AS IT HAD AN OLD IP AT SOME POINT.  AS WE USE HOSTNAMES, THIS ENSURES WE GET THE RIGHT ONES #
$ActiveDHCPServers = $DHCPServersThatPing -replace ".focuscorp.ca" | select -Unique 

# GET THE DAY OF THE WEEK #
$DayofWeek = Get-Date -Format ddd

# SET THE BACKUP PATH #
foreach ($DHCPServer in $ActiveDHCPServers)
{ 
	# DEFINE THE BACKUP DIRECTORY BY INCLUDING THE SERVER NAME SO EACH SET OF BACKUPS ARE IN THEIR OWN FOLDER #
	$BackupDirectory = "$BackupServer\DHCP-Backup-$DHCPServer"

  if (Test-Path $BackupDirectory) { } # FOLDER ALREADY EXISTS SO DO NOTHING #
	#if (Test-Path $BackupDirectory) { } # FOLDER ALREADY EXISTS SO DO NOTHING #
	else { New-Item -path $BackupServer -name "DHCP-Backup-$DHCPServer" -type directory }
	
	#USE PSEXEC TO EXPORT THE ENTIRE BACKUP INCLUDING LEASES -- NOTE THIS WILL TEMPORARILY STOP THE DHCP SERVER
	&$PSexecPath \\$DHCPServer netsh dhcp server export $BackupDirectory\$DayofWeek-$dhcpserver.bak all
}		

2 comments

    • sandeep on June 22, 2018 at 6:11 am
    • Reply

    I am getting below error can you please please help

    Test-Path : Cannot retrieve the dynamic parameters for the cmdlet. The specified wildcard pattern is not valid: [
    At C:\\San1.ps1:54 char:16
    + if (Test-Path <<<< $BackupDirectory) { } # FOLDER ALREADY EXISTS SO DO NOTHING #
    + CategoryInfo : InvalidArgument: (:) [Test-Path], ParameterBindingException
    + FullyQualifiedErrorId : GetDynamicParametersException,Microsoft.PowerShell.Commands.TestPathCommand

    The term '[C:\PSTOOL\psexec.exe]' is not recognized as the name of a cmdlet, function, script file, or operable prog
    . Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
    At C:\San1.ps1:59 char:3
    + & <<<< $PSexecPath \\$DHCPServer netsh dhcp server export $BackupDirectory\$DayofWeek-$dhcpserver.bak all
    + CategoryInfo : ObjectNotFound: ([C:\PSTOOL\psexec.exe]:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

    Test-Path : Cannot retrieve the dynamic parameters for the cmdlet. The specified wildcard pattern is not valid: [
    At C:\desktop\San1.ps1:54 char:16
    + if (Test-Path <<<< $BackupDirectory) { } # FOLDER ALREADY EXISTS SO DO NOTHING #
    + CategoryInfo : InvalidArgument: (:) [Test-Path], ParameterBindingException
    + FullyQualifiedErrorId : GetDynamicParametersException,Microsoft.PowerShell.Commands.TestPathCommand

    The term '[C:\PSTOOL\psexec.exe]' is not recognized as the name of a cmdlet, function, script file, or operable prog
    . Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
    At C:\San1.ps1:59 char:3
    + & <<<< $PSexecPath \\$DHCPServer netsh dhcp server export $BackupDirectory\$DayofWeek-$dhcpserver.bak all
    + CategoryInfo : ObjectNotFound: ([C:\PSTOOL\psexec.exe]:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

    Test-Path : Cannot retrieve the dynamic parameters for the cmdlet. The specified wildcard pattern is not valid: [
    At C:\Users\San1.ps1:54 char:16
    + if (Test-Path <<<< $BackupDirectory) { } # FOLDER ALREADY EXISTS SO DO NOTHING #
    + CategoryInfo : InvalidArgument: (:) [Test-Path], ParameterBindingException
    + FullyQualifiedErrorId : GetDynamicParametersException,Microsoft.PowerShell.Commands.TestPathCommand

    The term '[C:\PSTOOL\psexec.exe]' is not recognized as the name of a cmdlet, function, script file, or operable prog
    . Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
    At C:\desktop\San1.ps1:59 char:3
    + & <<<< $PSexecPath \\$DHCPServer netsh dhcp server export $BackupDirectory\$DayofWeek-$dhcpserver.bak all
    + CategoryInfo : ObjectNotFound: ([C:\PSTOOL\psexec.exe]:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

    • Ryan on April 29, 2024 at 4:00 pm
    • Reply

    Sandeep, ensure you run and accept the EULA for the PSEXEC executable before scheduling and remove the [] around your backup path.

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.