Posted in : Citrix, Hypervisor, Windows Server

2 years ago

Working with backups of your virtual machines is obviously essential. Working with exports in XenServer can some times be time consuming, particularly with bigger virtual disks attached to your virtual machine. In this scenario I will show you an alternative to manually export via XenCenter, by doing it with Powershell to an remote server using XenServer Powershell module.

XenServer Powershell module

In case you don’t have XenServer Powershell module installed, which is the only prerequisite for connection to XenServer API via Powershell, you can download the XenServer Software Develop Kit from this link (requires an Citrix.com account). The package download also contains a ”readme” file with instructions for configuring the XenServer PowerShell module. Assuming you now have XenServer Powershell Module installed, let’s gets started.
In this scenario, I want to store the virtual machine exports on a separate Windows Server dedicated for backups. I will show you how this can be done for both running and non-running virtual machines.

Create an encrypted password file

Let’s start off with creating an encrypted a password file. This only serves a purpose of not having clear-text password in your script. Clear-text variables containing your username and password works fine as well. Creating a encrypted password file only has to be done once and the password file can be reused for you next script.
Note: The password file can only be read and used by the account who created it, so whether you plan to use the script as a scheduled task in Windows for automated exports, you can for an example create the password file as a service-account.

"YourPassword" | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString | Out-File "C:\Xenit\Password.txt"

Connect to your XenServer

We are now going to get a connection established with your XenServer host.

Import-Module XenServerPSModule
$XenServerHost = "10.0.0.1"
$Username = "root"
$PasswordFile = "C:\Xenit\Password.txt"
$MyCredential=New-Object -TypeName System.Management.Automation.PSCredential `
 -ArgumentList $User, (Get-Content $PasswordFile | ConvertTo-SecureString)
#Connect to the XenServer Pool (In case you have a pool, works fine for stand-alone XenServer hosts as well)
  Try{
        $ConnectSession = Connect-XenServer -Url https://$XenServerHost -Creds $MyCredential -NoWarnCertificates -SetDefaultSession
 }      Catch [XenAPI.Failure] {
        [string]$IdentifiedNewPoolMaster = $_.Exception.ErrorDescription[1]
        Write-Host "$($Pools.$Pool) given XenServer host was identified as Pool slave, Master was identified as $IdentifiedNewPoolMaster, trying to connect"
        $Pools.Pool = $IdentifiedNewPoolMaster
        $ConnectSession = Connect-XenServer -url "https://$IdentifiedNewPoolMaster" -Creds $MyCredential -NoWarnCertificates -SetDefaultSession
        $XenServerHost = $IdentifiedNewPoolMaster
                               }
# In case you are unsure whether you're connected or not, verify with below
# Get-XenVM -Name "VM1"

Export a running virtual machine

When performing ”hot-backup” we will need a temporary snapshot. Below can be used for exporting a running virtual machine:

$vmName = "VM1"
$exportPath = "D:\XenServerExportRepository"
$vmPath = "$ExportPath\$SnapshotName.xva"
#Function for adding todays date and keeping track of your backups
function Get-TimeStamp {
return "{0:yyyy/MM/dd}" -f (Get-Date)
}
#By default Windows exports to Temp folder on C:. If you do not for example have enough free space on C: to hold the VM, the export will fail.
#By changing the TEMP environment variable the export will be done on the same volume as I'm going to store the exported VM on.
$env:TMP  = $exportPath
$env:TEMP = $exportPath
#For exporting currently running virtual machines we need a temporary snapshot.
$VM = Get-XenVM -Name $vmName
$snapshotName = "$VMName - $(Get-TimeStamp)"
Invoke-XenVM -Name $vmName -XenAction Snapshot -NewName $snapshotName
$Snapshot = Get-XenVM -Name $snapshotName
#Configure "is-a-template" and "ha-always-run" to false
Set-XenVM -Uuid $Snapshot.uuid -IsATemplate $False -HaAlwaysRun $False
#Export virtual machine snapshot
New-Item -ItemType Directory -Path "$exportPath"
Export-XenVM -Uuid $Snapshot.uuid -XenHost $XenServerHost -Path ($exportPath + "\$vmName.xva")
#Verify that the file exists under the path you've created
if(Test-Path -Path $vmPath)
            {
            #This does not remove disk snapshots
            Remove-XenVM -Uuid $Snapshot.uuid
            Write-Output "$(Get-TimeStamp) - Virtual machine $vmName exported sucessfully to $exportPath " | Out-file C:\Xenit\XenServerExport.log -Append
            Write-Host "Disconnecting from XenServer host"
            Disconnect-XenServer -Session $connectSession
            Remove-PSSnapin XenServerPSSnapIn
            }
else
            {
            Write-Output "$(Get-TimeStamp) - Error exporting virtual machine $vmName to $exportPath " | Out-file C:\Xenit\XenServerExport.log -Append
            Write-Host "Disconnecting from XenServer host"
            Disconnect-XenServer -Session $connectSession
            Remove-PSSnapin XenServerPSSnapIn
            }

Export a non-running virtual machine

When exporting a shut down virtual machine, we don’t need a snapshot as XenServer handles that itself. Below can be used for exporting a shut down virtual machine:

$vmName = "VM1"
$exportPath = "D:\XenServerExportRepository"
$vmPath = "$ExportPath\$SnapshotName.xva"
#Function for adding todays date and keeping track of your backups
function Get-TimeStamp {
return "{0:yyyy/MM/dd}" -f (Get-Date)
}
#By default Windows exports to Temp folder on C:. If you do not for example have enough free space on C: to hold the VM, the export will fail.
#By changing the TEMP environment variable the export will be done on the same volume as I'm going to store the exported VM on.
$env:TMP  = $exportPath
$env:TEMP = $exportPath
#Export virtual machine
New-Item -ItemType Directory -Path "$ExportPath"
$VM = Get-XenVM -Name $VMName
Export-XenVm -Uuid $VM.uuid -XenHost $XenServerHost -Path ($ExportPath + "\$VMName.xva")
#Verify that the file exists under the path you've created
if(Test-Path -Path $vmPath)
            {
            Write-Output "$(Get-TimeStamp) - Virtual machine $vmName exported sucessfully to $exportPath " | Out-file C:\Xenit\XenServerExport.log -Append
            Write-Host "Disconnecting from XenServer host"
            Disconnect-XenServer -Session $connectSession
            Remove-PSSnapin XenServerPSSnapIn
            }
else
            {
            Write-Output "$(Get-TimeStamp) - Error exporting virtual machine $vmName to $exportPath " | Out-file C:\Xenit\XenServerExport.log -Append
            Write-Host "Disconnecting from XenServer host"
            Disconnect-XenServer -Session $connectSession
            Remove-PSSnapin XenServerPSSnapIn
            }

You can see progress done in your export by connecting to your XenServer via SSH and type the command xe task-list.
Progress of a VM export done with XenServer Powershell Module.
As your XenServer export procedure now is done with a Powershell script, it comes in handy for automation. You can for example use Windows Task Scheduler for automation of your newly built Powershell script.
If you have any questions, feel free to email me at robert.skyllberg@xenit.se

Tags : PowerShell, Windows Server, XenServer

Add comment

Your comment will be revised by the site if needed.