Skip to content

Instantly share code, notes, and snippets.

@justincjahn
Created April 4, 2012 07:44
Show Gist options
  • Save justincjahn/2299549 to your computer and use it in GitHub Desktop.
Save justincjahn/2299549 to your computer and use it in GitHub Desktop.
Poor man's DHCP sync.
<#
.SYNOPSIS
Safely restores DHCP Server scopes using the specified directory.
.DESCRIPTION
Performs a backup of the currently running DHCP Server to the given
directory. Pulls a reference backup from another location locally
and performs a restore operation.
Version: 0.0.1
Author: Justin "4sak3n 0ne" Jahn
Company: Yuma Educational Technology Consortium
License: GNU Lesser General Public License <http://www.gnu.org/copyleft/lesser.html>
.INPUTS
This script requires no inputs from the pipeline.
.OUTPUTS
This script sends no outputs to the pipeline.
.NOTES
There are a few different return codes available for use:
0: Everything has run successfully.
1: There was an error with the filesystem paths and/or restore.
2: The current user does not have sufficient priveledges to perform this operation.
3: An unknown error has occurred.
.PARAMETER Parent
The location in which to pull down the DHCP Backup to by syncronized.
.PARAMETER Sync
The location in which to store the parent DHCP Backup locally.
The default is "C:\dhcp\sync".
.PARAMETER Backup
The location in which to store the backup of the local DHCP server.
The default is "C:\dhcp\backup".
#>
param(
[parameter(Mandatory=$true)][string]$Parent,
[parameter(Mandatory=$false)][string]$Sync = $env:SystemDrive + "\dhcp\sync",
[parameter(Mandatory=$false)][string]$Backup = $env:SystemDrive + "\dhcp\backup"
);
#
# Administrator Check
#
$oUser = [System.Security.Principal.WindowsIdentity]::GetCurrent();
$oSecure = New-Object Security.Principal.WindowsPrincipal $oUser;
$bAdmin = $oSecure.IsInRole([Security.Principal.WindowsBuiltInRole]::"Administrator");
$bSystem = $oUser.IsSystem;
If (-NOT $bAdmin -AND -NOT $bSystem) {
Write-Error "You do not have Administrator rights to run this script.";
exit 2;
}
#
# Check for DHCPServer
#
$oService = Get-Service | where {$_.Name -match "dhcpserver"};
if ($oService -eq $null) {
Write-Warning "DHCP Server is not installed.";
exit 0;
}
#
# Sanity checks
#
try {
# Make sure the paths are not files. This will cause
## obvious issues.
if ((Test-Path $Backup -PathType Leaf)) { Throw $Backup; }
if ((Test-Path $Sync -PathType Leaf)) { Throw $Sync; }
# Create the ACL object that may be used later on.
$oUser = New-Object System.Security.AccessControl.FileSystemAccessRule(
"NT SERVICE\DHCPServer",
@("FullControl"),
@("ObjectInherit","ContainerInherit"),
"None",
"Allow"
);
# Test to see if the backup directory exists.
if (!(Test-Path $Backup)) {
# Create the new directory
New-Item -type directory -path $Backup;
# Fetch the ACLs on the newly created directory
$oACL = Get-Acl $Backup;
$oACL.SetAccessRuleProtection($false, $false);
$oACL.AddAccessRule($oUser);
# Reapply the ACL to the directory
Set-Acl $Sync -AclObject $oACL;
}
# Test to see if the sync directory exists.
if (!(Test-Path $Sync)) {
# Create the new directory
New-Item -type directory -path $Sync;
# Fetch the ACLs on the newly created directory
$oACL = Get-Acl $Sync;
$oACL.SetAccessRuleProtection($false, $false);
$oACL.AddAccessRule($oUser);
# Reapply the ACL to the directory
Set-Acl $Sync -AclObject $oACL;
}
} catch [system.string] {
$sError = "The path {0} is a file, not a directory.";
$sError = $sError -f $Error[0];
Write-Error $sError;
exit 1;
} catch {
Write-Error $Error[0];
exit 3;
}
#
# Backup the DHCP server
#
try {
netsh dhcp server backup $Backup;
# Sanity check
if ($lastexitcode -gt 0) {
$sError = "Unable to backup to directory: {0}";
$sError = $sError -f $Backup;
throw $sError;
}
} catch {
# If this has failed, then we shouldn't continue
## with the sync.
Write-Error $Error[0];
exit 1;
}
#
# Perform the restore.
#
try {
# Remove the old sync items
$sPath = $Sync + "\*";
Remove-Item $sPath -recurse;
# Try to copy the files and folders from the parent server
$sPath = $parent + "\*"
Copy-Item $sPath -dest $Sync -recurse -force;
# Perform the restore on the file
netsh dhcp server restore $Sync;
# Sanity check
if ($lastexitcode -gt 0) {
$sError = "Unable to restore from directory: {0}";
$sError = $sError -f $Sync;
throw $sError;
}
} catch {
# Tell them there was an error
Write-Error $Error[0];
# Perform the restore
Write-Warning "Performing rollback operation..."
netsh dhcp server restore $Backup;
Restart-Service DHCPServer -Force;
# Throw an error code
exit 1;
} finally {
Restart-Service DHCPServer -Force;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment