Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- :: Purpose: DHCP server Watchdog & Failover script. Read notes below
- :: Requirements: 1. Domain administrator credentials & "Logon as a batch job" rights
- :: 2. Proper firewall configuration to allow connection
- :: 3. Proper permissions on the DHCP backup directory
- :: Author: vocatus on Reddit
- :: Version: 1.1c + Added quotes around all variables that could contain paths
- :: + Added full path to SC.exe to prevent failure in the event %PATH% gets corrupted or mangled (this happened in testing)
- :: * Fixed a glitch that could occur when pinging an assumed-down primary server that would incorrectly think it was back up
- :: - Removed almost every entry of "2>&1" since it's really not needed
- :: 1.1b - Changed DATE to CUR_DATE format to be consistent with all other scripts
- :: 1.1 - Comments improvement
- :: / Tuned some parameters (ping count on checking)
- :: / Some logging tweaks
- :: / Renamed FAILOVER_DELAY to FAILOVER_RECHECK_DELAY for clarity
- :: 1.0d * Some logging tweaks
- :: 1.0c * Some logging tweaks
- :: 1.0 Initial write
- :: Notes: I wrote this script after failing to find a satisfactory method of performing
- :: watchdog/failover between two Windows Server 2008 R2 DHCP servers.
- ::
- :: Use: This script has two modes: "Watchdog" and "Failover."
- :: - Watchdog checks the status of the remote DHCP service, logs it, and then grabs the remote DHCP db backup file and imports it.
- :: - Failover mode is activated when the script cannot determine the status of the remote DHCP server. The script then activates
- :: the local DHCP server with the latest backup copy it successfully retrieved from the primary server.
- ::
- :: Instructions:
- :: 1. Tune the variables in this script to your desired backup location and frequency
- :: 2. On the primary server: set the DHCP backup interval to your desired backup frequency. The value is in minutes; I recommend 5 minutes.
- :: You do this by modifying this registry key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DHCPServer\Parameters\BackupInterval
- :: 3. On the backup server: set this script to run as a scheduled task. I recommend every 10 minutes.
- :: Notice:
- :: !! Make sure to set it only to run if it isn't already running! If there is a failover you could have
- :: Task Scheduler spawn a new instance of the script every n minutes and end up with hundreds of copies
- :: of this script running.
- :: Prep
- SETLOCAL
- @echo off
- cls
- set VERSION=1.1c
- title [DHCP Server Watchdog v%VERSION%]
- :::::::::::::::
- :: Variables :: - Set these. Do not use trailing slashes (\) in directory names (this is important!).
- :::::::::::::::
- :: Remote server is the PRIMARY DHCP server we're watching. Use a hostname or IP address.
- set REMOTE_SERVER=my-dhcp-server
- :: Location of the DHCP backup on the remote primary server
- :: Best practice is to leave as default, unless you have a custom backup location.
- :: The script builds the backup line like this: \\%REMOTE_SERVER%\c$\%REMOTE_BACKUP_PATH%
- set REMOTE_BACKUP_PATH=Windows\system32\dhcp\backup
- :: Location of the local backup. I normally copy directly to my backup server's DHCP directory.
- :: The script builds the local backup line like this: c:\windows\system32\dhcp\[backup folders]
- set LOCAL_BACKUP_PATH=%SystemRoot%\system32\dhcp
- :: When a failover is triggered, how many seconds should we wait in between each attempt to contact the primary server again?
- set FAILOVER_RECHECK_DELAY=15
- :: Log options. Don't put an extension on the log file name. (Important!) The script sets this later on.
- set LOGPATH=%SystemDrive%\Logs
- set LOGFILE=%COMPUTERNAME%_DHCP_watchdog
- :: Max log file size allowed (in bytes) before rotation and archive. I recommend setting this to 2 MB (2097152).
- :: Example: 524288 is half a megabyte (~500KB)
- set LOG_MAX_SIZE=2097152
- :: \/ Don't touch anything below this line. If you do, you will break something.
- set CUR_DATE=%DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%
- :::::::::::::::::::::::
- :: LOG FILE HANDLING :: - This section handles the log file
- :::::::::::::::::::::::
- :: Make the logfile if it doesn't exist
- if not exist %LOGPATH% mkdir %LOGPATH%
- if not exist %LOGPATH%\%LOGFILE%.log goto new_log
- :: Check log size. If it hasn't exceeded our size limit, jump straight to Watchdog mode
- for %%R in (%LOGPATH%\%LOGFILE%.log) do if %%~zR LSS %LOG_MAX_SIZE% goto newrun
- :: However, if the log was too big, go ahead and rotate it.
- pushd %LOGPATH%
- del %LOGFILE%.ancient 2>NUL
- rename %LOGFILE%.oldest %LOGFILE%.ancient 2>NUL
- rename %LOGFILE%.older %LOGFILE%.oldest 2>NUL
- rename %LOGFILE%.old %LOGFILE%.older 2>NUL
- rename %LOGFILE%.log %LOGFILE%.old 2>NUL
- popd
- :: And then create the header for the new log file
- :new_log
- echo ------------------------------------------------------------------------------------->> %LOGPATH%\%LOGFILE%.log
- echo Initializing new DHCP Server Watchdog log on %CUR_DATE% at %TIME%, max log size %LOG_MAX_SIZE% bytes>> %LOGPATH%\%LOGFILE%.log
- echo ------------------------------------------------------------------------------------->> %LOGPATH%\%LOGFILE%.log
- echo.>> %LOGPATH%\%LOGFILE%.log
- :: New run section - if we just launched the script, write a header for this run
- :newrun
- echo ------------------------------------------------------------------------------------->> %LOGPATH%\%LOGFILE%.log
- echo DHCP Server Watchdog v%VERSION%, %CUR_DATE%>> %LOGPATH%\%LOGFILE%.log
- echo Running as %USERDOMAIN%\%USERNAME% on %COMPUTERNAME%>> %LOGPATH%\%LOGFILE%.log
- echo.>> %LOGPATH%\%LOGFILE%.log
- echo Job Options>> %LOGPATH%\%LOGFILE%.log
- echo Log location: %LOGPATH%\%LOGFILE%.log>> %LOGPATH%\%LOGFILE%.log
- echo Log max size: %LOG_MAX_SIZE% bytes>> %LOGPATH%\%LOGFILE%.log
- echo Watching primary server: %REMOTE_SERVER%>> %LOGPATH%\%LOGFILE%.log
- echo Mirroring this DHCP db: %REMOTE_BACKUP_PATH%>> %LOGPATH%\%LOGFILE%.log
- echo Local backup location: %LOCAL_BACKUP_PATH%>> %LOGPATH%\%LOGFILE%.log
- echo ------------------------------------------------------------------------------------->> %LOGPATH%\%LOGFILE%.log
- echo %TIME% Starting Watchdog mode.>> %LOGPATH%\%LOGFILE%.log
- echo.
- echo DHCP Server Watchdog v%VERSION%
- echo Running as: %USERDOMAIN%\%USERNAME% on %COMPUTERNAME%
- echo Log: %LOGPATH%\%LOGFILE%.log
- :::::::::::::::::::
- :: WATCHDOG MODE ::
- :::::::::::::::::::
- :watchdog
- :: Ping the server to see if it's up
- echo.
- echo Verifying proper operation of DHCP server on %REMOTE_SERVER%, please wait...
- echo.
- echo %TIME% Pinging %REMOTE_SERVER%...>> %LOGPATH%\%LOGFILE%.log
- echo %TIME% Pinging %REMOTE_SERVER%...
- ping %REMOTE_SERVER% -n 2 >NUL
- if %ERRORLEVEL%==1 echo %TIME% WARNING %REMOTE_SERVER% failed to respond to ping. && echo %TIME% WARNING %REMOTE_SERVER% failed to respond to ping.>> %LOGPATH%\%LOGFILE%.log
- if not %ERRORLEVEL%==1 echo %TIME% SUCCESS %REMOTE_SERVER% responded to ping. && echo %TIME% SUCCESS %REMOTE_SERVER% responded to ping.>> %LOGPATH%\%LOGFILE%.log
- :: Check & Log
- echo %TIME% Checking DHCP server status on %REMOTE_SERVER%...>> %LOGPATH%\%LOGFILE%.log
- echo %TIME% Checking DHCP server status on %REMOTE_SERVER%...
- :: Reset ERRORLEVEL back to 0
- ver > NUL
- :: Use "SC" to check the status of "Dhcpserver" service, find the "RUNNING" state, and act accordingly based on the return code
- %WINDIR%\System32\sc.exe \\%REMOTE_SERVER% query Dhcpserver | find "RUNNING" >NUL
- if %ERRORLEVEL%==0 echo %TIME% SUCCESS The DHCP service is running on %REMOTE_SERVER%.>> %LOGPATH%\%LOGFILE%.log
- if %ERRORLEVEL%==0 echo %TIME% SUCCESS The DHCP service is running on %REMOTE_SERVER%.
- :: This section only executes if the test failed.
- if not %ERRORLEVEL%==0 (
- echo %TIME% FAILURE The DHCP service is not running on %REMOTE_SERVER%.>> %LOGPATH%\%LOGFILE%.log
- echo %TIME% Activating failover procedure. Local DHCP server will be initialized using most recent successful backup.>> %LOGPATH%\%LOGFILE%.log
- echo %TIME% FAILURE The DHCP service is not running on %REMOTE_SERVER%.
- echo %TIME% Activating failover procedure. Local DHCP server will be initialized using most recent successful backup.
- goto failover
- )
- :: Reset ERRORLEVEL back to 0
- ver > NUL
- :: Fetch
- echo %TIME% Fetching DHCP database backup from %REMOTE_SERVER%...>> %LOGPATH%\%LOGFILE%.log
- echo %TIME% Fetching DHCP database backup from %REMOTE_SERVER%...
- xcopy "\\%REMOTE_SERVER%\c$\%REMOTE_BACKUP_PATH%\*" "%LOCAL_BACKUP_PATH%\backup_new_pending\" /E /Y /Q >NUL
- :: If the copy SUCCEEDED, this executes
- if %ERRORLEVEL%==0 (
- echo %TIME% SUCCESS Backup fetched from %REMOTE_SERVER%.>> %LOGPATH%\%LOGFILE%.log
- echo %TIME% SUCCESS Backup fetched from %REMOTE_SERVER%.
- echo %TIME% Rotating database backups...>> %LOGPATH%\%LOGFILE%.log
- echo %TIME% Rotating database backups...
- :: Rotate backups and use newest copy
- rmdir /S /Q %LOCAL_BACKUP_PATH%\backup5
- if exist "%LOCAL_BACKUP_PATH%\backup4" move /Y "%LOCAL_BACKUP_PATH%\backup4" "%LOCAL_BACKUP_PATH%\backup5"
- if exist "%LOCAL_BACKUP_PATH%\backup3" move /Y "%LOCAL_BACKUP_PATH%\backup3" "%LOCAL_BACKUP_PATH%\backup4"
- if exist "%LOCAL_BACKUP_PATH%\backup2" move /Y "%LOCAL_BACKUP_PATH%\backup2" "%LOCAL_BACKUP_PATH%\backup3"
- if exist "%LOCAL_BACKUP_PATH%\backup" move /Y "%LOCAL_BACKUP_PATH%\backup" "%LOCAL_BACKUP_PATH%\backup2"
- move /Y "%LOCAL_BACKUP_PATH%\backup_new_pending" "%LOCAL_BACKUP_PATH%\backup" >NUL
- echo %TIME% Database backups rotated.>> %LOGPATH%\%LOGFILE%.log
- echo %TIME% Database backups rotated.
- )
- :: If the copy FAILED, this executes:
- if not %ERRORLEVEL%==0 (
- echo %TIME% WARNING There was an error copying the backup from %REMOTE_SERVER%.>> %LOGPATH%\%LOGFILE%.log
- echo %TIME% You may want to look into this since we were able to check the DHCPserver service status but the file copy failed.>> %LOGPATH%\%LOGFILE%.log
- echo %TIME% Skipping new database import due to copy failure.>> %LOGPATH%\%LOGFILE%.log
- echo %TIME% Job complete with errors.>> %LOGPATH%\%LOGFILE%.log
- echo %TIME% WARNING There was an error copying the backup from %REMOTE_SERVER%.
- echo %TIME% You may want to look into this since we were able to check the DHCPserver service status but the file copy failed.
- echo %TIME% Skipping new database import due to copy failure.
- echo %TIME% Job complete with errors.
- )
- :: Import database
- echo %TIME% Starting local DHCP server to import new database...>> %LOGPATH%\%LOGFILE%.log
- echo %TIME% Starting local DHCP server to import new database...
- net start Dhcpserver
- echo %TIME% Local DHCP server running. Performing import...>> %LOGPATH%\%LOGFILE%.log
- echo %TIME% Local DHCP server running. Performing import...
- netsh dhcp server restore "%LOCAL_BACKUP_PATH%\backup"
- echo %TIME% Import complete.>> %LOGPATH%\%LOGFILE%.log
- echo %TIME% Import complete.
- echo %TIME% Stopping local DHCP server...>> %LOGPATH%\%LOGFILE%.log
- echo %TIME% Stopping local DHCP server...
- net stop Dhcpserver
- echo %TIME% Local DHCP server stopped.>> %LOGPATH%\%LOGFILE%.log
- echo %TIME% Local DHCP server stopped.
- echo %TIME% SUCCESS Job complete, DHCP database backed up and ready for use. Exiting.>> %LOGPATH%\%LOGFILE%.log
- echo %TIME% SUCCESS Job complete, DHCP database backed up and ready for use. Exiting.
- goto EOF
- :::::::::::::::::::
- :: FAILOVER MODE ::
- :::::::::::::::::::
- :failover
- :: Log this AND display to console
- echo %TIME% WARNING Failover activated.>> %LOGPATH%\%LOGFILE%.log
- echo %TIME% Starting local DHCP server using most recent successful backup...>> %LOGPATH%\%LOGFILE%.log
- echo.
- echo %TIME% WARNING Could not contact primary DHCP server "%REMOTE_SERVER%." Failover activated.
- echo %TIME% Starting local DHCP server using most recent successful backup...
- echo.
- net start Dhcpserver
- echo %TIME% Local DHCP server started.>> %LOGPATH%\%LOGFILE%.log
- echo %TIME% Entering monitoring loop. Checking if %REMOTE_SERVER% is back up every %FAILOVER_RECHECK_DELAY% seconds...>> %LOGPATH%\%LOGFILE%.log
- echo %TIME% Local DHCP server started.
- echo %TIME% Entering monitoring loop. Checking if %REMOTE_SERVER% is back up every %FAILOVER_RECHECK_DELAY% seconds...
- :failover_loop
- :: First we ping the server
- ping %REMOTE_SERVER% -n 3 >NUL
- :: If no ping response, this section executes
- IF NOT %ERRORLEVEL%==0 (
- echo %TIME% FAILURE No ping response from %REMOTE_SERVER%. Waiting %FAILOVER_RECHECK_DELAY% seconds to check again.>> %LOGPATH%\%LOGFILE%.log
- echo %TIME% FAILURE No ping response from %REMOTE_SERVER%. Waiting %FAILOVER_RECHECK_DELAY% seconds to check again.
- ping localhost -n %FAILOVER_RECHECK_DELAY% >NUL
- goto failover_loop
- )
- :: If yes ping response, this section executes
- :: This declaration is required to get the nested IF ERRORLEVEL test to function correctly
- SETLOCAL ENABLEDELAYEDEXPANSION
- if not %ERRORLEVEL%==1 (
- echo %TIME% NOTICE %REMOTE_SERVER% is responding to pings.>> %LOGPATH%\%LOGFILE%.log
- echo %TIME% NOTICE %REMOTE_SERVER% is responding to pings.
- echo %TIME% Checking DHCP server status on %REMOTE_SERVER%...>> %LOGPATH%\%LOGFILE%.log
- echo %TIME% Checking DHCP server status on %REMOTE_SERVER%...
- :: This section checks to see if the Dhcpserver service is back up and acts accordingly
- %WINDIR%\System32\sc.exe \\%REMOTE_SERVER% query Dhcpserver | find "RUNNING" >NUL
- :: The exclamation points around ERRORLEVEL here prevent it from incorrectly being expanded using the external ERRORLEVEL results from the first IF statement
- if !ERRORLEVEL!==0 (
- echo %TIME% SUCCESS The DHCP service is running on %REMOTE_SERVER%.>> %LOGPATH%\%LOGFILE%.log
- echo %TIME% SUCCESS The DHCP service is running on %REMOTE_SERVER%.
- echo %TIME% The primary DHCP server %REMOTE_SERVER% is back up. Stopping local DHCP service...>> %LOGPATH%\%LOGFILE%.log
- echo %TIME% The primary DHCP server %REMOTE_SERVER% is back up. Stopping local DHCP service...
- net stop Dhcpserver
- echo %TIME% Recovery complete. Exiting.>> %LOGPATH%\%LOGFILE%.log
- echo %TIME% Recovery complete. Exiting.
- goto EOF
- )
- )
- ENDLOCAL
- :: If the host responds to pings but the DHCP service isn't running, this executes
- echo %TIME% FAILURE %REMOTE_SERVER% is responding to pings, but DHCP isn't responding (yet?). Will try again in %FAILOVER_RECHECK_DELAY% seconds.>> %LOGPATH%\%LOGFILE%.log
- echo %TIME% FAILURE %REMOTE_SERVER% is responding to pings, but DHCP isn't responding (yet?). Will try again in %FAILOVER_RECHECK_DELAY% seconds.
- ver >NUL
- goto failover_loop
- ENDLOCAL
- echo.>> %LOGPATH%\%LOGFILE%.log
- :EOF
Add Comment
Please, Sign In to add comment