DHCP Backups in PowerShell

Backing up a DHCP server is simple using the cmdlets Backup-DhcpServer and Restore-DhcpServer. There are a couple gotchas and while it is not as directory specific as the DNS Backups are I chose to use the same directories out of convenience.

Note

ACLs must be set to give "DHCP Server" full control over the restoration files otherwise the import fails.

The service must be restarted prior to removing the restoration files, otherwise you get errors and no restoration occurs.

Code

Backup

$log = 'C:\dhcp_backup.log'
Start-Transcript $log      

#Requires -RunAsAdministrator

# --- Initializations --- #
If (Test-Path '.\send-mail\send-mail.ps1') {
    . .\send-mail\send-mail.ps1
    } Else {
    Throw "send-mail is missing"
}

# --- Declarations --- #
#user vars, change these
$backupLocation = "\\dsk7\backups-smb\dhcp\"
$archive = "C:\$(Get-Date -UFormat %Y-%m-%d)-$env:COMPUTERNAME.dhcp.zip"

#system vars, you likely don't change these
$dhcpRoot = 'C:\Windows\System32\dhcp\'
$dhcpBak = "$dhcpRoot\backupTask"

# use an array to catch bad things and put it in our email
$failureArray = @()

# --- Functions --- #
Function mail {
    # stop must be here so that the file can be unlocked whenever we want to mail
    Stop-Transcript
    If ($failureArray.Count -gt 0) {
        $result = 'failure'
    } Else {
        $result = 'success'
    }
    send-mail -to 'user@contoso.com' -subject "DHCP Backup on $env:COMPUTERNAME $result" -body "Failures: $failureArray" -attachment $log
}

# --- Execution --- #
Write-Host "Running the backup..." -ForegroundColor Green
Try {
    Backup-DhcpServer -Path "$dhcpBak"
} Catch {
    $failureArray += "DHCP Backup Failure"
    Write-Host $_
    mail
    Throw "DHCP backup failure"
}

# zip-em and move-em
$zipFiles = "$dhcpBak"

Write-Host "Compressing archive $archive" -ForegroundColor Green
Compress-Archive -Path $zipFiles -DestinationPath $archive

Write-Host "Moving $archive to $backupLocation" -ForegroundColor Green
Try {
    Move-Item -Path $archive -Destination $backupLocation
} Catch {
    Write-Warning "Move failure"
    $failureArray = "move failure"
    Write-Host $_
}

Try {
    Remove-Item -Path $dhcpBak -Recurse
} Catch {
    Write-Warning "failed to remove backup dir"
    $failureArray += 'backup dir failed to remove'
    Write-Host $_
}

# --- Ending Tasks --- #
mail
Note

This script utilizes my email script submodule.

Recovery

Start-Transcript 'C:\dhcp_recovery.log'

#Requires -RunAsAdministrator

Function dhcp_recovery {
    param (
        [Parameter(Mandatory=$True)]
        [Object]$archive
    )
    
    # this cannot be changed, the commands will only load files from this dir
    $dhcpRoot = "C:\Windows\System32\dhcp"
    $dhcpBak = "$dhcpRoot\backupTask\"

    If (!(Test-Path $archive)) {
        Throw "$archive does not exist, check the path and try again"
    }
    
    If (Test-Path $dhcpBak) { 
        Throw "$dhcpBak exists, verify your goal and remove it" 
    }
    Write-Host "Expanding $archive at $dhcpRoot, it will be $dhcpBak" -ForegroundColor Green
    Expand-Archive -Path $archive -DestinationPath $dhcpRoot

    # Set permissions for 'DHCP Server' to Full Control
    $dhcpAcl = Get-ACL $dhcpRoot
    Get-ChildItem -Recurse -Path $dhcpBak | Set-ACL -AclObject $dhcpAcl

    Restore-DhcpServer -Path $dhcpBak

    # restart the server before removing our files, otherwise this whole thing fails
    Write-Host "Restarting DHCP Server..." -ForegroundColor Green
    Restart-Service -Name DHCPServer

    Write-Host "Removing files from $dhcpBak"
    Remove-Item -Path $dhcpBak -Recurse
 
}
dhcp_recovery

Stop-Transcript

Notes

A DHCP server runs a backup of itself every 60 min by default, using probably Backup-DHCPServer cmdlet. This automatic backup is located, always by default in %SystemRoot%\System32\DHCP\backup

References

Official docs

Backup-DhcpServer vs Export-DhcpServer