How to Backup AD forest with Powershell

Inside a disaster recovery plan for our AD a wrote a script that lunch the winbackup on each DCs:

Param(
  [string]$DomainController,
  [String]$BackupPath
      )

#read-host -assecurestring | convertfrom-securestring | out-file ADTest_securestring.txt
$username = "backupserviceaccount@myad.test"
$password = cat D:\scripts\ADTest_Backup\ADTest_securestring.txt | convertto-securestring
$testCred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $password
      
Function Adbackup($BackupPath){
      
    Import-Module servermanager
    #Check if Windows feature is installed- if not attempts to install Windows backup and tools features
    $FeatureStatus=(Get-WindowsFeature backup).Installed
    If($FeatureStatus -eq $False){
        Add-windowsfeature backup -OutVariable results
        Add-WindowsFeature backup-tools
        #Confirm sucessful feature installation
        foreach($result in $results){
            If($result.success){
                Write-Host "Windows Backup and tools installed successfully on $env:Computername" -ForegroundColor "Green" }
            Else{ Write-Host "Windows Backup and tools installation failed on $env:Computername" -ForegroundColor "Red"}
        }
    }
        #Add powershell Windows Backup snap in into PowerShell environment 
    add-pssnapin windows.serverbackup -ea silentlycontinue
    
    #Create a new policy backup 
    $policy = New-WBPolicy 
    #Add system state into the policy 
    #Add-WBSystemState -Policy $policy 
    Add-WBBareMetalRecovery -Policy $policy
    #Declare backup location based on folder name 
    #$backupLocation = New-WBBackupTarget -network $BackupPath -credential $cred  
    $backupLocation = New-WBBackupTarget -VolumePath $BackupPath
    #Add backup location into the policy 
    Add-WBBackupTarget -Policy $policy -Target $backupLocation -force
    
    #Start the Backup
    Start-WBBackup -Policy $policy
}

#list of servers to query
$servers = (Get-ADForest -Server myad.test -Credential $testCred).Domains | %{ Get-ADDomainController -Credential $testCred -Filter * -Server $_ }  | select-object -expand Name

#query the servers in the list
foreach ($server in $servers){
      $DomainController = $server
      Write-Host "Preparing backup of $DomainController...." -ForegroundColor Green
      invoke-command -Credential $testCred -ComputerName $domaincontroller -ScriptBlock ${Function:Adbackup} -ArgumentList $backupPath
}

First store the password of the account you will use for backup (in my case “backupserviceaccount@myad.test”) with this command:

read-host -assecurestring | convertfrom-securestring | out-file ADTest_securestring.txt

Then configure the script changing:

‘$username = “backupserviceaccount@myad.test“‘ with the account to use for backup

‘$password = cat D:\scripts\ADTest_Backup\ADTest_securestring.txt‘ with the path where you store the encrypted password for backup account

‘$servers = (Get-ADForest -Server myad.test -Credential $testCred).Domains’ with the AD forest DNS name (in my case myad.test)

Then schedule this script on you management server with the same user you used for encrypt backup account password.

Note: winrm is necessary and well configured on all DCs for running this script.


For check the backup status on each DCs, here you find a script that publish a report on sharepoint or send an email:

#read-host-assecurestring |convertfrom-securestring | out-file ADTest_securestring.txt
$username = "backupserviceaccount@myad.test"
$password = cat D:\scripts\ADTest_Backup\ADTest_securestring.txt | convertto-securestring
$testCred = new-object-typename System.Management.Automation.PSCredential -argumentlist $username, $password

#mail settings
$from = "mgmserver@myad.test"
$to = "me@myad.test"
$emailsubject = "Backup Status - myad.test"
$mailbody = ""

function Publish-File {
	param (
		[parameter( Mandatory = $true, HelpMessage="URL pointing to aSharePoint document library (omit the '/forms/default.aspx' portion)." )]
		[System.Uri]$Url,
		[parameter( Mandatory = $true,ValueFromPipeline = $true, HelpMessage="One or more files to publish. Use 'dir' to produce correct object type." )]
		[System.IO.FileInfo[]]$FileName,
		[system.Management.Automation.PSCredential]$Credential
	)
	$wc = new-object System.Net.WebClient
	if ( $Credential ) { $wc.Credentials = $Credential }
	else { $wc.UseDefaultCredentials = $true }
	$FileName |ForEach-Object {
		$DestUrl = "{0}{1}{2}"-f $Url.ToString().TrimEnd("/"), "/", $_.Name
		Write-Verbose "$( get-date-f s ): Uploading file: $_"
		$wc.UploadFile( $DestUrl , "PUT", $_.FullName )
		Write-Verbose "$( get-date -f s ): Upload completed"
	}
	
}

$a = "<style>"
$a = $a + "BODY{background-color:white;}"
$a = $a + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"
$a = $a + "TH{border-width: 1px;padding: 5px;border-style: solid;border-color: lightgray;background-color:white}"
$a = $a + "TD{border-width: 1px;padding: 5px;border-style: solid;border-color: lightgray;background-color:white}"
$a = $a + "</style>"

$dateRun = get-date

#list of servers to query
 $servers = (Get-ADForest -Server myad.test -Credential $testCred).Domains | %{ Get-ADDomainController -Credential $testCred -Filter * -Server $_ }  | select-object -expand Name
 $report = @()

#query the servers in the list
foreach ($server in $servers){
    $props=@{
        ComputerName=$server
        LastBackupTime=$null
        LastBackupResultDetailedHR=$null
        IsAlive=$false
    }

    if($result=Invoke-Command -Credential $testCred -computername $server -ScriptBlock {add-pssnapin windows.serverbackup; get-wbsummary} -Ea 0){
        $props.LastBackupTime=$result.LastBackupTime
        $props.LastBackupResultDetailedHR=$result.LastBackupResultDetailedHR
        $props.IsAlive=$true
    }
    $report += New-Object PsObject -Property $props
}

#send the email
#Send-MailMessage -From $from -To $to -Subject $emailsubject -SmtpServer "smtp.myad.test" -Body $report

#Sharepoint publication
$b = $report | Sort-Object ComputerName
$outfile = $b | ConvertTo-HTML -head $a -body "<H2>$emailsubject</H2><P>This page was generated by a Script at $dateRun</P>" -PreContent " " -PostContent " "
$outfile | Out-File D:\scripts\ADTest_Backup\WorkingFolder\Test_Environment_Backup.html
Dir D:\scripts\ADTest_Backup\WorkingFolder\Test_Environment_Backup.html | Publish-File -Url "https://teams01.myad.test/ced/000001/AD Wiki/Pages/"

The configuration is quite identical of backup script:

Configure the ‘#Mail Setting” at the beginning of script

Configure the AD forest DNS name in ‘$servers = (Get-ADForest -Server myad.test -Credential $testCred).Domains’

Configure the temporary path and sharepoint URL at the end of script.

Update: new release at https://241931348f64b1d1.wordpress.com/2016/01/12/how-to-backup-ad-forest-with-powershell-2/

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s