Tuesday, August 09, 2022

Hyper-V VM Backup using Powershell (VM-Export)


One of the many things I've been working on is an automated script to do VM backups.  I've been doing a lot of work automating processes with PowerShell recently so I thought I would just sit down and finish hammering out this little script I was working on.

This PowerShell script exports Hyper-V VM's to a directory; and sends an email notification when the export completes or if there is an error.  I am not 100% there with the backup as there are still a few bugs like sending an email when the entire script finished but I am confident enough of this working that I am going to pass this along for anyone to use if they wish.


##########BACKUP VM SCRIPT##########
#Set Variables for count, date and VM's you want to backup
$BackupNum = 0;
$TimeStart = Get-Date;
#Set the names of the computers you want to backup
$ComputerNameArray = '$VM1','$VM2','$VM3','$VM4','$VM5','$VM6','$VM7','$VM8','$VM9';
#Get the Number of Computers you want to backup
$BackupTotal = ($ComputerNameArray.count -1);
#Set the Path to save the backups
$SavePath = "$PATH TO FOLDER";

#Run the backup while the backup number is less then the backup total
while($BackupNum -le $BackupTotal){
#Set the first computer to be backed up
$ComputerName = $ComputerNameArray[$BackupNum];

#Check to see if there are previous backups
if (Test-Path -Path $SavePath\$ComputerName) {
#if the computer name is not blank remove the previous backup
if ($ComputerName -ne ""){
Remove-Item -Path "$SavePath\$ComputerName" -Force -Recurse
}
}

#Get the start time of the backup
$TimeStart = Get-Date;

#Export Backup
$ExportJob = Export-VM -Name $ComputerName -Path $SavePath;

#After the export runs get the time finished and send an email notification
$TimeFinished = Get-Date;
Send-MailMessage -From '$MAILFROM' -To '$EMAIL' -Subject "VM Backup for $ComputerName was Successful" -Body "The VM $ComputerName was successfully backed up. It started at $TimeStart and Finished at $TimeFinished" -smtpserver '$SMTP_SERVER'
#Auto Increment the export so we can get the next computer name
$BackupNum++
}

#While the jobstate is running or not started; get the progress
while( $ExportJob.State -eq "Running" -or $ExportJob.State -eq "NotStarted"){ 
$progress = $ExportJob.Progress.PercentComplete;
Write-Output ("[Export] " + $($ExportJob.Progress.PercentComplete) + "% complete"); 

#If the backup state is not Completed and errors out
if($ExportJob.State -ne "Completed") { 
#Get the time finished
$TimeFinished = Get-Date;
#Send an email that the export did not finish
Send-MailMessage -From '$MAILFROM' -To '$MAILTO' -Subject "Backup For $ComputerName Failed at $progress % complete" -smtpserver '$SMTPSERVER'
Write-Error ("Export Job did not complete: " +$ExportJob.State);
throw $ExportJob.Error;
}
##########END SCRIPT###########

Resources

RDP Periodically Freezes in Windows 10 and Windows Server

I work with windows a lot and have found I had been having connection issues with Remote Desktop on most of my Windows Servers and some Wind...