Management

Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Join 772 other subscribers

Social

  • LinkedIn
  • RSS Feed for Posts
  • Twitter
  • StumbleUpon

Script to create a Windows backup using a VHD file.

Updated : 10-31-2014 => Added Version 4.0

 

This scripts can create a windows backup to a VHD file, on any location in your network.

The only thing needed is setting the correct variables in the xml file.

The script is generating a log file in the backup location, these logfiles are kept unit you reach the number of days given in the xml file.

 

STEP 1

Create a VHD file.

This can be done in Hyper-V (Available in windows 7 and Windows 8).

Be sure your VHD is large enough for your backup, and your VHD is initialized and formatted.

 

STEP 2

Set the correct variables in the XML file

 

STEP 3

Test the backup, and check the log file.

You can start the script using the Verbose optien, for testing purposes:

 

Step 4

Set your script as a daily/weekly/monthly task.

You can download the script in zip format here.

[wpdm_file id=1 title=”true” ]

 

Script:

<#
.Synopsis
    Creatign a windows backup to a VHD file.
	  
.Description
	This scripts generates a windows backup, by mounting
	a VHD file (with the same name as the device).
	Logs files are created in the destination folder.
	This script can be used both on workstations and on servers.
	Don't edit this script, only edit the corresponding XML file.

.Inputs
	No Inputs are necessary

.Outputs
	The lof file is saved in the destination folder and
	is send to the prefferred e-mail adress
			
.Notes
    Name: BackupScript-v40.ps1
    Author: John Ermen and Richard Voogt
    Version: 4.0
    Date: October 31 2014
    Tested on Windows 8 Windows 8.1 Windows 2008 R2
	Written By: Richard Voogt
	Website:	https://www.vspbreda.nl/nl/?p=1701
	Twitter:	http://twitter.com/rvoogt

.Change-Log
	V1.0 	09/04/2014 	- Initial version
	V2.0	09/17/2014 	- Change to a script with all input in XML file.
	V3.0	09/27/2014	- Created 1 script for Workstation and servers
	V4.0    10/31/2014	- Added Event logging and selection for creating VHD and/OR backup

.Link
	https://www.vspbreda.nl/nl/?p=1701
   
.EXAMPLE
	For normal execution:
	.\BackupScript-v40.ps1
	
	For testing purposes :
	.\BackupScript-v40.ps1 -verbose    
#>

[CmdletBinding()]
param ()

$myDir = Split-Path -Parent $MyInvocation.MyCommand.Path
# For testing purposes
write-Verbose "Files are taken from the folder $Mydir"
# Import email settings from the config file
$ConfigFile = Get-Content "$MyDir\backup-v40.xml"

# Setting Script Variables
$VHDName=$env:computername 
$CustomerName=$ConfigFile.Settings.Client
$EDomain=$ConfigFile.Settings.domain
$BackupDrive=$ConfigFile.Settings.Drive
$BackupDrive2=$BackupDrive + ":"
$emailserver=$ConfigFile.Settings.Server
$emailto=$ConfigFile.Settings.SendTo
$LogDays=$ConfigFile.Settings.Days
$vhdlocation=$ConfigFile.Settings.vhdlocation
$VHDDiskSizeinMB=$ConfigFile.Settings.VHDDiskSizeinMB
$IncludeDrive=$ConfigFile.Settings.IncludeDrive
$AskCreateVHD=$ConfigFile.Settings.AskCreateVHD
$EventSource=$ConfigFile.Settings.EventSource
$VHDLoc="$vhdlocation\VHD"
$VHD="$VHDLoc\$VHDName.vhd"
$LogLoc= "$vhdlocation\Log\"
$diskpartscript="$env:TEMP\diskpart.txt"
$diskpartscriptMount="$env:TEMP\diskpartMount.txt"
$diskpartscriptDismount="$env:TEMP\diskpartDismount.txt"
$diskpartscriptCreateVHD="$env:TEMP\diskpartCreateVHD.txt"
$emaildomain = $emailto.IndexOf("@")
$emailfrom=$CustomerName+"-"+$VHDName+"@"+$EDomain
$Today=get-date -f dd-MM-yyyy-hh-mm
$backuplog="$LogLoc"+"$VHDName-Backup-$Today.log"
$VHDCreated="0"

Function OSSelection
{
# Server / Workstation selection
# $OS = 1 => Workstation
# $OS = 2 => Server 
$CompConfig = Get-WmiObject Win32_ComputerSystem
foreach ($ObjItem in $CompConfig) {
$Role=$ObjItem.DomainRole
write-verbose "DomainRole = $Role"
If ($Role -le 1 )
    { 
	Write-Verbose "The Workstation options is available"
	$Script:OS="1"
	}
    Else { 
	Write-Verbose "The Server options is available"
	$Script:OS="2"
	} 
	write-verbose "OS = $Script:OS"
}
}

Function StandardSettings
{
#Creating Event Source Name
New-EventLog -LogName Application -Source $EventSource

#Checking if $IncludeDrive has a value, if not the value is set to c:
If (!$IncludeDrive) {
		$IncludeDrive="c:"
		} # END IF
}

Function CreateLog
{
    if(!(Test-Path -Path $LogLoc )){
		New-Item -ItemType directory -Path $LogLoc
		Write-Verbose ("Log created in location $LogLoc")
		Write-Host -backgroundcolor green -ForegroundColor black "Log file created !"
		Write-Output ("----------- Log created in location $LogLoc - $(Get-Date -DisplayHint DateTime)") | Out-File "$backuplog" -Encoding ASCII -Force -Append
    }
	ELSE {
		Write-Output ("----------- Log already in location $LogLoc - $(Get-Date -DisplayHint DateTime)") | Out-File "$backuplog" -Encoding ASCII -Force -Append
		}
} # End Function CreateLog

# Creating log file
Function CreateVHDLoc
{
    if(!(Test-Path -Path $VHDLoc )){
		New-Item -ItemType directory -Path $VHDLoc
        Write-Verbose ("VHD Location created in location $VHDLoc")
		Write-Host -backgroundcolor green -ForegroundColor black "VHD Location created !"
		Write-Output ("----------- VHD Location created in location $VHDLoc - $(Get-Date -DisplayHint DateTime)") | Out-File "$backuplog" -Encoding ASCII -Force -Append
		
    }
	ELSE {
		Write-Output ("----------- VHD Location already in location $VHDLoc - $(Get-Date -DisplayHint DateTime)") | Out-File "$backuplog" -Encoding ASCII -Force -Append
		
		}
	Write-Output ("----------- Starting log on - $(Get-Date -DisplayHint DateTime)") | Out-File "$backuplog" -Encoding ASCII -Force
} # End Function CreateVHDLoc

# Clean out logging after number of $logDays
Function CleanLogs
{
    Write-Output ("----------- Cleaning backups logs older than $LogDays days - $(Get-Date -DisplayHint DateTime)") | Out-File "$backuplog" -Encoding ASCII -Force -Append
    $limit = (Get-Date).AddDays(-$LogDays)
    Get-ChildItem -Path $LogLoc -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force
	Write-Verbose ("Logs cleaned to $LogDays days")
}

#Creating a VHD
Function CreateVHD
{
	Write-Output "Create vdisk file=$VHD type=fixed maximum=$VHDDiskSizeinMB noerr" "select vdisk file=$VHD" "attach vdisk" "attributes disk clear readonly" "convert MBR" "create partition primary" "format FS=NTFS LABEL=backup quick" | Out-File -FilePath $diskpartscriptCreateVHD -Encoding ASCII -Force
	Write-Output ("----------- Creating VHD on - $(Get-Date -DisplayHint DateTime)") | Out-File "$backuplog" -Encoding ASCII -Force -Append
	Write-Host -backgroundcolor green -ForegroundColor black "Creating VHD, this may take a while ! Check the log file"
	DISKPART /s $diskpartscriptCreateVHD | Out-File "$backuplog" -Encoding ASCII -Force -Append
	if(!$?)  
            {
            Write-Output ("----------- VHD creation failed on - $(Get-Date -DisplayHint DateTime)") | Out-File "$backuplog" -Encoding ASCII -Force -Append
			write-eventlog -computername $VHDName -logname Application -source $EventSource -eventID 1414 -entrytype Error -message "VHD creation Failed."
            Dismount-VHD
			Write-Host -backgroundcolor green -ForegroundColor black "VHD creation Failed ! Check the log file"
            break
            }
			ELSE {
			
			Write-Output ("----------- VHD creation Succesfull on - $(Get-Date -DisplayHint DateTime)") | Out-File "$backuplog" -Encoding ASCII -Force -Append
			write-eventlog -computername $VHDName -logname Application -source $EventSource -eventID 1212 -entrytype Information -message "VHD creation Succesfull."
			Write-Verbose ("VHD created in location $VHD")
			Write-Host -backgroundcolor green -ForegroundColor black "VHD creation is Succesfull ! Check the log file"
			} # End IF VHD creation controle
}

# Backup failed
Function MailFail
{
    Write-Output ("----------- Sending e-mail notification on - $(Get-Date -DisplayHint DateTime)") | Out-File "$backuplog" -Encoding ASCII -Force -Append
    Send-MailMessage -To $emailto -From "$emailfrom" -Subject "$CustomerName / Windows Backup for $VHDName Date $Today has FAILED" -Body "The backup has failed! Please check attached log." -attachment "$backuplog" -smtpServer "$emailserver"  
	Write-Verbose ("Backup failed check the backup log $backuplog")
	}

# Backup succeeded
Function MailSuccess
{
    Write-Output ("----------- Sending e-mail notification on - $(Get-Date -DisplayHint DateTime)") | Out-File "$backuplog" -Encoding ASCII -Force -Append
	Write-Host "The selected e-mail adress is $emailto"
	Write-Host $emailfrom $CustomerName $VHDName $Today $backuplog $emailserver
    Send-MailMessage -To $emailto -From "$emailfrom" -Subject $CustomerName" / Windows Backup for "$VHDName" Date "$Today" has SUCCEEDED" -Body "The backup has succeeded!" -attachment "$backuplog" -smtpServer "$emailserver"  
	Write-Verbose ("Backup succeeded check the backup log $backuplog")
	}

# Mounting VHD to $BackupDrive
Function Mount-VHD
{
    Write-output "select vdisk file=$vhd" "attach vdisk" "select partition 1" "assign letter=$BackupDrive" "exit"  | Out-File -FilePath $diskpartscriptMount -Encoding ASCII -Force
    Write-Output ("----------- Mounting VHD on - $(Get-Date -DisplayHint DateTime)") | Out-File "$backuplog" -Encoding ASCII -Force -Append
    DISKPART /s $diskpartscriptMount | Out-File "$backuplog" -Encoding ASCII -Force -Append
	Write-Verbose ("VHD mounted check the backup log $backuplog")
}

# DisMounting VHD
Function Dismount-VHD
{
    Write-output "select vdisk file=$vhd" "detach vdisk" "exit" | Out-File -FilePath $diskpartscriptDismount -Encoding ASCII -Force
    Write-Output ("----------- Dismounting VHD on - $(Get-Date -DisplayHint DateTime)") | Out-File "$backuplog" -Encoding ASCII -Force -Append
    DISKPART /s $diskpartscriptDismount | Out-File "$backuplog" -Encoding ASCII -Force -Append
	Write-Verbose ("VHD dismounted")
}

#Start Windows backup
Function StartBackup
{   
    Write-Host -backgroundcolor green -ForegroundColor black "Backup is starting, this may take a while"
	Write-verbose ("OS version = $Script:OS" )
IF ($Script:OS -eq "1")
	{
    Write-Output ("----------- Backup started on - $(Get-Date -DisplayHint DateTime)") | Out-File "$backuplog" -Encoding ASCII -Force -Append
	cmd /c "wbadmin start backup -backuptarget:$backupdrive2 -allcritical -include:$IncludeDrive -quiet" | Out-File "$backuplog" -Encoding ASCII -Force -Append
	if(!$?)  
            {
            Write-Output ("----------- Backup failed on - $(Get-Date -DisplayHint DateTime)") | Out-File "$backuplog" -Encoding ASCII -Force -Append
			write-eventlog -computername $VHDName -logname Application -source $EventSource -eventID 1313 -entrytype Error -message "Windows backup Failed."
            Dismount-VHD
			MailFail
			Write-Host -backgroundcolor green -ForegroundColor black "Backup is Failed ! Check the log file"
            break
            }
			ELSE {
			
			Write-Output ("----------- Backup Finished on - $(Get-Date -DisplayHint DateTime)") | Out-File "$backuplog" -Encoding ASCII -Force -Append
			Write-Verbose ("Backup Finished as a workstation")
			Write-Output ("----------- Backup succeeded on - $(Get-Date -DisplayHint DateTime)") | Out-File "$backuplog" -Encoding ASCII -Force -Append
			write-eventlog -computername $VHDName -logname Application -source $EventSource -eventID 1111 -entrytype Information -message "Windows backup Succesfull."
			Write-Verbose ("Backup succeeded")
			Write-Host -backgroundcolor green -ForegroundColor black "Backup is Succesfull ! Check the log file"
			MailSuccess	
			} # End IF backup controle
	} # End IF
	ELSEIF ($Script:OS -eq "2")
	{
			Write-Output ("----------- Backup started on - $(Get-Date -DisplayHint DateTime)") | Out-File "$backuplog" -Encoding ASCII -Force -Append
			cmd /c "wbadmin start backup -backuptarget:$backupdrive2 -allcritical -systemstate -include:$IncludeDrive  -quiet"  | Out-File "$backuplog" -Encoding ASCII -Force -Append
	 if(!$?)  
            {
            Write-Output ("----------- Backup failed on - $(Get-Date -DisplayHint DateTime)") | Out-File "$backuplog" -Encoding ASCII -Force -Append
			write-eventlog -computername $VHDName -logname Application -source $EventSource -eventID 1313 -entrytype Error -message "Windows backup Failed."
            Dismount-VHD
			MailFail
			Write-Host -backgroundcolor green -ForegroundColor black "Backup is Failed ! Check the log file"
            break
            }
			ELSE {
			
			Write-Output ("----------- Backup Finished on - $(Get-Date -DisplayHint DateTime)") | Out-File "$backuplog" -Encoding ASCII -Force -Append
			Write-Verbose ("Backup Finished as a workstation")
			Write-Output ("----------- Backup succeeded on - $(Get-Date -DisplayHint DateTime)") | Out-File "$backuplog" -Encoding ASCII -Force -Append
			Write-Verbose ("Backup succeeded")
			Write-Host -backgroundcolor green -ForegroundColor black "Backup is Succesfull ! Check the log file"
			write-eventlog -computername $VHDName -logname Application -source $EventSource -eventID 1111 -entrytype Information -message "Windows backup Succesfull."
			MailSuccess	
			} # End IF backup controle
	} # End ELSE
}

# Clean out logging after number of $logDays
Function Ask2CreateVHD
{
    Write-Output ("----------- Ask to create VHD - $(Get-Date -DisplayHint DateTime)") | Out-File "$backuplog" -Encoding ASCII -Force -Append
	Write-Verbose ("AskCreateVHD = $AskCreateVHD in functie AskCreateVHD")
		IF ($AskCreateVHD -gt "2"){
			Write-warning "Only select 0, 1 or 2"
			AskCreateVHD
			}
		ELSEIF ($AskCreateVHD -eq "0")
			{
			Write-Output ("----------- Only creating a VHD disk. - $(Get-Date -DisplayHint DateTime)") | Out-File "$backuplog" -Encoding ASCII -Force -Append
			Write-verbose "You have selected : $AskCreateVHD Creating a VHD file"
			CreateVHD
			Mount-VHD
			}
		ELSEIF ($AskCreateVHD -eq "1")
			{
			Write-Output ("----------- Only creating a Backup. - $(Get-Date -DisplayHint DateTime)") | Out-File "$backuplog" -Encoding ASCII -Force -Append
			Write-verbose "You have selected : $AskCreateVHD Creating a backup"
			Mount-VHD
			StartBackup
			}
		ELSEIF ($AskCreateVHD -eq "2")
			{
			Write-Output ("----------- Creating a VHD disk and a backup. - $(Get-Date -DisplayHint DateTime)") | Out-File "$backuplog" -Encoding ASCII -Force -Append
			Write-verbose "You have selected : $AskCreateVHD Creating a VHD file and a backup"
			CreateVHD
			DisMount-VHD
			Mount-VHD
			StartBackup
			}	
}

# Running Backup Script
# Variables for testing purposes
Write-verbose "VHDName = $VHDName"
Write-verbose "Backupdrive = $BackupDrive2"
Write-verbose "BackupLog = $backuplog"
Write-verbose "Customer Name = $CustomerName"
Write-verbose "Email Server = $emailserver"
Write-verbose "Email To = $emailto"
Write-verbose "Email From = $emailfrom"
Write-verbose "EmailDomain = $emaildomain"
Write-verbose "Log Days = $LogDays"
Write-verbose "VHDLocation = $VHDLoc"
Write-verbose "VHD Name = $VHD"
Write-verbose "DiskpartSript = $diskpartscript"
Write-verbose "diskpartscriptMount = $diskpartscriptMount"
Write-verbose "diskpartscriptDismount = $diskpartscriptDismount"
Write-verbose "diskpartscriptCreateVHD = $diskpartscriptCreateVHD"
Write-verbose "VHDDiskSizeinMB = $VHDDiskSizeinMB"
Write-verbose "AskCreateVHD = $AskCreateVHD"
Write-verbose "EventSource = $EventSource"

#start the script
OSSelection
StandardSettings
CreateLog
CreateVHDLoc
CleanLogs
Ask2CreateVHD
Dismount-VHD