Workspace-Guru

invoke-XenBackup

Dec 12th, 2017
17,431
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <#
  2. .SYNOPSIS
  3.     V2.0
  4.     A Scirpt to backup XenServer VM's to Windows file shares.
  5.      
  6. .DESCRIPTION
  7.     This script will take a snapshot of the selected VM's on XenServer. Then it will export the snapshot to a fileshare. You can    choose to send a log file trough email. And ZIP the backup.
  8.  
  9. .NOTES
  10.     File Name  : Invoke-XenServerBackup.ps1
  11.     Author     : Chris Twiest - [email protected]
  12.     To get PowerShell working with Citrix XenServer you need to download and install the XenServer SDK from here https://www.citrix.com/downloads/xenserver/product-software/xenserver-72-standard-edition.html under the Development Components section
  13.  
  14. .LINK
  15.     https://workspace-guru.com
  16.    
  17. .EXAMPLE
  18.     Invoke-XenBackup -ExportPath "C:\Backup" -VMnames "VM01" -username "root" -password "P@ssw0rd" -XenHost "XenHost01" -LogPath "C:\temp"
  19.  
  20.     This will backup VM01 from XenHost01 in C:\Backup. Username and Password are for XenHost01.Logfile will be written in C:\Temp
  21.  
  22. .EXAMPLE
  23.   Invoke-XenBackup -ExportPath "C:\Backup" -VMnames "VM01","VM02","VM03" -username "root" -password "P@ssw0rd" -XenHost "XenHost01" -LogPath "C:\Temp" -Email -SMTPServer "smtp.domain.com" -FromEmail "[email protected]" -ToEmail "[email protected]" -ZIP
  24.  
  25.    This will backup VM01, VM02 and VM03 from XenHost01 in C:\Backup. Username and Password are for XenHost01.
  26.    After the backup the folder will be ZIP'd and the backup logfile will be send in a email to [email protected]
  27.  
  28. #>
  29.  
  30. Function Invoke-XenBackup {
  31.     [CmdletBinding()]
  32.     param (
  33.         [Parameter(Mandatory = $True)]
  34.         [string]$ExportPath,
  35.         [array]$VMnames,
  36.         [string]$username,
  37.         [string]$password,
  38.         [string]$XenHost,
  39.         [string]$LogPath,
  40.         [Parameter(Mandatory = $false)]
  41.         [switch]$Email,
  42.         [string]$SMTPServer,
  43.         [string]$FromEmail,
  44.         [string]$ToEmail,
  45.         [switch]$Zip
  46.     )
  47.  
  48.     #### If Export or Log path is network drive ###
  49.     if ($Exportpath -like "\\*") {
  50.  
  51.         $ExportpathORG = $ExportPath
  52.  
  53.         $testnetworklocation = $Exportpath | test-path
  54.  
  55.         if (!$testnetworklocation) {
  56.  
  57.             write-host "Can't acces networkdrive make sure the script is run with the correct rights"
  58.         }
  59.         else {
  60.  
  61.             write-host "$ExportPath is Network drive, will mount drive"
  62.            
  63.             $share = "$Exportpath"
  64.             $drvlist = (Get-PSDrive -PSProvider filesystem).Name
  65.             Foreach ($drvletter in "DEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray()) {
  66.                 If ($drvlist -notcontains $drvletter) {
  67.                     New-PSDrive -PSProvider filesystem -Name $drvletter -Root $share -Persist | out-null
  68.                     break
  69.                 }
  70.             }
  71.             $Exportpath = $drvletter + ":"
  72.  
  73.         }
  74.     }
  75.  
  76.     if ($logpath -like "\\*") {
  77.  
  78.         $LogPathOrg = $LogPath
  79.  
  80.         $testnetworkloglocation = $Logpath | test-path
  81.  
  82.         if (!$testnetworkloglocation) {
  83.  
  84.             write-host "Can't acces networkdrive make sure the script is run with the correct rights"
  85.         }
  86.         else {
  87.  
  88.             write-host "$LogPath is Network drive, will mount drive"
  89.  
  90.             $logshare = "$logpath"
  91.             $logdrvlist = (Get-PSDrive -PSProvider filesystem).Name
  92.             Foreach ($logdrvletter in "DEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray()) {
  93.                 If ($logdrvlist -notcontains $logdrvletter) {
  94.                     New-PSDrive -PSProvider filesystem -Name $logdrvletter -Root $logshare -Persist | out-null
  95.                     break
  96.                 }
  97.             }
  98.             $LogPath = $logdrvletter + ":"
  99.         }
  100.     }
  101.    
  102.    
  103.     Import-Module XenServerPSModule
  104.     $env:TMP = $ExportPath
  105.     $env:TEMP = $Exportpath
  106.  
  107.     #### Create Logfile #######
  108.     $datelogfile = Get-Date -format yyyy-dd-MM-hh-mm-ss
  109.     $logfile = "$LogPath\XenBackupLog_$datelogfile.txt"
  110.    
  111.     $testlogpath = "$LogPath" | test-path
  112.    
  113.     if ($testlogpath -like "False") {
  114.         New-Item -ItemType Directory -Path "$LogPath"
  115.     }
  116.    
  117.     New-Item -ItemType File -Path "$logfile" | Out-Null
  118.    
  119.     #### Create Backup Folder ######
  120.    
  121.     $date = Get-Date -format yyyy-dd-MM-hh-mm-ss
  122.     Write-Host "$Date --- Start Backup"
  123.     Add-Content $logfile "$Date --- Start Backup for $VMNames to $Exportpath"
  124.    
  125.    
  126.     $backupdate = Get-Date -format yyyy-MM-dd
  127.     $Testexportpath = $ExportPath | Test-Path
  128.     if (!$Testexportpath) {
  129.         New-Item -ItemType Directory -Path "$ExportPath" | out-null
  130.     }
  131.    
  132.     $Testbackuppath = "$ExportPath\XenBackup-$backupdate" | Test-Path
  133.     if (!$Testbackuppath) {
  134.         New-Item -ItemType Directory -Path "$ExportPath\XenBackup-$backupdate" | out-null
  135.     }
  136.    
  137.     Import-Module XenServerPSModule
  138.    
  139.     Try {
  140.         $Session = Connect-XenServer -Url https://$Xenhost -UserName $username -Password $password -NoWarnCertificates -SetDefaultSession
  141.     }
  142.    
  143.     Catch [XenAPI.Failure] {
  144.         [string]$PoolMaster = $_.Exception.ErrorDescription[1]
  145.         Write-Host -ForegroundColor Red "$($Pools.$Pool) is slave, Master was identified as $PoolMaster, trying to connect"
  146.         $Pools.Pool = $PoolMaster
  147.         $Session = Connect-XenServer -url "http://$PoolMaster" -UserName $username -Password $password -NoWarnCertificates -SetDefaultSession
  148.     }
  149.  
  150.     #### Create Snapshot and backup folder for each VM ####
  151.    
  152.     foreach ($VMname in $VMnames) {
  153.         $date = Get-Date -format yyyy-dd-MM-hh-mm-ss
  154.         Write-Host "$Date --- Create Snapshot $VMname"
  155.         Add-Content $logfile "$Date --- Create Snapshot $VMname"
  156.        
  157.         $Testbackupvmpath = "$ExportPath\XenBackup-$backupdate\$VMName" | Test-Path
  158.         if ($testbackupvmpath -like "False") {
  159.             New-Item -ItemType Directory -Path "$ExportPath\XenBackup-$backupdate\$VMName" | out-null
  160.         }
  161.        
  162.         & {
  163.  
  164.             $VMUuid = get-XenVM -Name $VMName | Select-Object UUID
  165.        
  166.             Invoke-XenVM -Uuid $VMUUid.uuid -XenAction Snapshot -NewName "$VMName-Backup-$backupdate"
  167.  
  168.         }2>&1 | Tee-Object $logfile -append
  169.        
  170.     }
  171.    
  172.    
  173.     #### Export and Remove Snapshot #####
  174.    
  175.     foreach ($VMname in $VMnames) {
  176.         $date = Get-Date -format yyyy-dd-MM-hh-mm-ss
  177.         Write-Host "$Date --- Export Snapshot $VMname"
  178.         Add-Content $logfile "$Date --- Export Snapshot $VMname"
  179.        
  180.         $SnapshotUuid = get-XenVM -Name "$VMName-Backup-$backupdate" | select UUID
  181.        
  182.         #Set-XenVM -Uuid $SnapshotUuid.uuid -IsATemplate $false -HaAlwaysRun $false
  183.         Export-XenVm -Uuid $SnapshotUuid.uuid -XenHost "$XenHost" -path "$ExportPath\XenBackup-$backupdate\$VMName\$VMName-backup.xva"
  184.        
  185.         $pathtest = "$ExportPath\XenBackup-$backupdate\$VMName\$VMName-backup.xva" | test-path
  186.        
  187.         if ($pathtest -like "False") {
  188.             $date = Get-Date -format yyyy-dd-MM-hh-mm-ss
  189.             Write-Host "$Date --- ERROR ---- Export Snapshot $VMname failed"
  190.             Add-Content $logfile "$Date --- ERROR ---- Export Snapshot $VMname failed"
  191.         }
  192.         else {
  193.             $date = Get-Date -format yyyy-dd-MM-hh-mm-ss
  194.             Write-Host "$Date --- Export Snapshot $VMname finished"
  195.             Add-Content $logfile "$Date --- Export Snapshot $VMname finished"
  196.            
  197.         }
  198.        
  199.         $date = Get-Date -format yyyy-dd-MM-hh-mm-ss
  200.         Write-Host "$Date --- Delete Snapshot $VMname"
  201.         Add-Content $logfile "$Date --- Delete Snapshot $VMname"
  202.        
  203.         $snapshotName = "$VMName-Backup-$backupdate"
  204.         Try { $SnapShot = Get-XenVM -Name $SnapshotName | Where is_a_snapshot } Catch { "$SnapshotName was not found on $XenHost" }
  205.         Try { $SnapShot | Select -ExpandProperty VBDs | Get-XenVBD | Select -ExpandProperty VDI | where {$_ -ne "OpaqueRef:NULL"} | Remove-XenVDI } Catch { "   --> $($_.Exception.Message)"}
  206.         Try { Remove-XenVM -Uuid $SnapShot.uuid } Catch { return "   --> $($_.Exception.Message)" }
  207.  
  208.        
  209.     }
  210.    
  211.     #### ZIP Backup #####
  212.    
  213.     if ($zip) {
  214.         $date = Get-Date -format yyyy-dd-MM-hh-mm-ss
  215.         Write-Host "$Date --- Start ZIP of Backup"
  216.         Add-Content $logfile "$Date --- Start ZIP of Backup"
  217.        
  218.         $source = "$ExportPath\XenBackup-$backupdate"
  219.         $destination = "$ExportPath\XenBackup-$backupdate.zip"
  220.         If (Test-path $destination) { Remove-item $destination }
  221.         Add-Type -assembly "system.io.compression.filesystem"
  222.         [io.compression.zipfile]::CreateFromDirectory($Source, $destination)
  223.        
  224.         $date = Get-Date -format yyyy-dd-MM-hh-mm-ss
  225.         Write-Host "$Date --- Delete non ZIPd backup"
  226.         Add-Content $logfile "$Date --- Delete non ZIPd backup"
  227.        
  228.         Move-Item $destination $ExportPath
  229.         Get-ChildItem -Path $Source -Recurse | Foreach-object { Remove-item -Recurse -path $_.FullName }
  230.         Remove-item $source
  231.     }
  232.    
  233.     #### Backup Finished ###
  234.    
  235.     $date = Get-Date -format yyyy-dd-MM-hh-mm-ss
  236.     Write-Host "$Date --- Backup done"
  237.     Add-Content $logfile "$Date --- Backup done"
  238.    
  239.     #### Email Log ####
  240.    
  241.     if ($Email) {
  242.        
  243.         $MessageContent = "
  244.             <head>
  245.                <style>
  246.                    body {
  247.                        font-family: Arial;
  248.                        font-size: 12px;
  249.                    }
  250.                </style>
  251.             </head>
  252.             <BODY>
  253.             <P>To Whom It May Concern,<BR>
  254.             <BR>
  255.             XenServer Backup of $VMnames to $ExportPath has finished on $date check attached logfile for more info.
  256.             <P>
  257.             Greetings,<BR>
  258.             <BR>
  259.             XenServer Backup Script
  260.             </P>
  261.             </BODY>
  262.             "
  263.        
  264.         $messageSubject = "XenServer Backup $(Get-Date -UFormat "%A %d %B %Y") is done."
  265.         $body = $MessageContent
  266.         send-mailmessage -from $FromEmail -to $ToEmail -subject $messageSubject -body $body -BodyAsHtml -smtpServer $SMTPServer -Attachments "$Logfile"
  267.        
  268.     }
  269.  
  270.     #### If Export or Log path is network drive ###
  271.     if ($ExportpathORG -like "\\*") {
  272.  
  273.         write-host "$ExportPath is Network drive, will dismount drive"
  274.         Remove-Psdrive -Name $drvletter
  275.  
  276.     }
  277.  
  278.     if ($LogPathOrg -like "\\*") {
  279.  
  280.         write-host "$LogPath is Network drive, will dismount drive"
  281.         Remove-Psdrive -Name $logdrvletter
  282.     }
  283.  
  284. }
Advertisement
Add Comment
Please, Sign In to add comment