Powershell: Patching XenServer

Reading Time: 5 minutes

And now for something different…..
Last week I was tasked with the question to be able to automate applying multiple patches to a XenServer instead of admins doing the patching manually. Sure no problem, we can do this with Powershell.


I am using XE.exe from the XenCenter installer to control the XenServers. xe.exe needs to be in the path environment variabel. If you installed XenCenter to D:\Program Files (x86)\XenCenter you need to add this to the current path.

Path XenCenter

Next up is Powershell. As XenCenter needs to be on a Windows server, be sure to install Powershell if you are not running a version already. Should be in the management server by default.

Download the required patches to a location on the server. This location can be added to the script via the $UpdatePath variable for example download and set it to “E:\Patches\NEW-XEN-6.1\xen-6.1”.


Next up set your pool master ip (or IP of the server). Currently the script is set to get two values, one for the IP hard coded and one for the server you want to patch via user input. They can be the same, but the IP cannot be a slave. Xe won’t connect to a slave in a pool setup. At the environment this script was needed the hosts did not have a DNS record therefor IP and name is used. Hosts without DNS records is not advisable!
The script also needs the root user and password. At this time this is hard coded.

What does the script do?

The script takes a server name to patch as user input (with Read-Host), this is the name of the server as it is known in XenCenter. Next the script finds the uuid via the host-list command.

The patching procedure is to disable the host (aka Maintenance mode via host-disable), Evacuate running VM’s via host-evacuate. With the evacuate command there is an error checking to be sure the script can evacuate. If not the script exits here. We won’t apply patches and reboot with running VM’s. If you happen to run this on a non pooled server, you will need to power off the VM’s yourself. If the scrip exits here, you can find the reason in the evacuate txt file in the running directory. Most of the time this is a memory related error, but this has more to do with networking not available on an other host, storage, mounted iso’s or other items that fail a evacuation.

If all is well the patch directory is executed trough (Get-ChildItem of $UpdatePath), the patch is uploaded to the server. The UUID of the patch is saved and the update is installed. And on to the next one.

Last is the server reboot to finish the updates. The script sleeps for five minutes to let the host start-up, and then enables the host again. From this point you can distribute workloads back to this server and optionally run it at the next one.

Status of the patching is shown in the execution Window, and two files are saved during the execution: Hostname_evacuate.txt and Hostname_uuid.txt. The first saves the host-evacuate output (if there is nothing in the file all went okay), the second is used to save the UUID’s of the patches.

XenServer Patch script

Note: Citrix recommends rebooting the server before a patch. Currently this is not in the script as we where doing some other actions before the patch that included reboot. But this is easily fixed by copying the host-reboot line and pasting that one just after the evacuation. Be sure to check if the reboot enables the host or not.

Putting it all together

The script:

# This script connects to the Defined Pool master, Get server to patch, enters maintenance, patches the server, reboots and enables again.
# uses xe.exe from the XenCenter installation, requirement is to have this in the path of the system where this is run.
# Patches must be downloaded and placed in UpdatePath location.

# The script leaves txt files for evacuate and patch uuid’s actions. When evacuate fails script will stop, you can find the error in the text file.
# Mostly to do with networking or storage, or mounted tools on VM’s….

# Citrix Highly recommends rebooting XenServers prior to installing an update, this is not implemented in this script.

# Settings
$XenServerMst = “<pool master Ip>” # Pool Master IP and name of to update server must be filled in! XE cannot connect to slave.
$XenServer_Name = (Read-Host “XenServer Name to update”) # Server to update.

$XenServer_username = “<user>”
$XenServer_password = “<passwd>”
$UpdatePath = “E:\Patches\NEW-XEN-6.1\xen-6.1”

# nothing should be changed below this comment

# Loop through Updates
# Every Patch should be applied in the same procedure.
# Maintenance, reboot, upload, patch, reboot, end maintenance
# Evacuation of VM’s that are running.
Write-Host “Getting host uuid” -foreground green
$SrvUUID=(xe.exe -s $XenServerMst -u $XenServer_username -pw $XenServer_password host-list name-label=$XenServer_Name –minimal).split(‘,’) | % {$_.trim()}

# Maintenance, reboot, upload, patch, reboot, end maintenance
# Evacuation of VM’s that are running.
Write-Host “$SrvUUID will be disabled….” -foregroundcolor green
xe.exe -s $XenServerMst -u $XenServer_username -pw $XenServer_password host-disable host=$SrvUUID

Write-Host “$SrvUUID will be evacuated…(will take a long time)” -foregroundcolor green
xe.exe -s $XenServerMst -u $XenServer_username -pw $XenServer_password host-evacuate host=$SrvUUID | out-file $XenServer_Name”_evacuate.txt”

# We should exit the script when this fails
# $?
# Contains the execution status of the last operation. It contains
# TRUE if the last operation succeeded and FALSE if it failed.
Write-Host “Migrated. Continuing with update” -foregroundcolor green
Write-Host “Error with migration. Exit script at this point. Updates are not installed” -foregroundcolor red

Foreach ($Update in Get-ChildItem $UpdatePath){
# Loop through Updates
# Every Patch should be applied in the same procedure.

Write-Host “$SrvUUID will be pathed with $Update. Preparing to upload….” -foregroundcolor green

Write-Host “$Update will be uploaded” -foregroundcolor “green”
xe.exe -s $XenServerMst -u $XenServer_username -pw $XenServer_password patch-upload file-name=$Updatepath\$Update\$Update.xsupdate | out-file $XenServer_Name”_uuid.txt”

$uuid_patch = (xe.exe -s $XenServerMst -u $XenServer_username -pw $XenServer_password patch-list name-label=$Update –minimal)

Write-Host “$Update will be installed to this server” -foregroundcolor green
xe.exe -s $XenServerMst -u $XenServer_username -pw $XenServer_password patch-apply uuid=$uuid_patch host-uuid=$SrvUUID

Write-Host “After Patching, remove patch files to protect against running out of disk space” -foregroundcolor green
xe.exe -s $XenServerMst -u $XenServer_username -pw $XenServer_password patch-clean uuid=$uuid_patch

Write-Host “=======================================================” -foregroundcolor green
# End Update Loop

Write-Host “Post Patch reboot” -foregroundcolor green
xe.exe -s $XenServerMst -u $XenServer_username -pw $XenServer_password host-reboot host=$SrvUUID

# Wait for reboot seconds 300 (5 minutes)
Write-Host “Waiting five minutes for reboot to continue” -foregroundcolor green
start-sleep -s 300

Write-Host “Enable $SrvUUID again” -foregroundcolor green
xe.exe -s $XenServerMst -u $XenServer_username -pw $XenServer_password host-enable host=$SrvUUID

Write-Host “=======================================================” -foregroundcolor green

# Need to redistribute VM’s yourself


– Happy patching



2 thoughts to “Powershell: Patching XenServer”

    1. Depends on what is not working for you, and where/how it fails.
      You don’t need Powershell SDK for XenServer. The script uses xe.exe from the XenCenter installation. Just have this installed on the Powershell host and direct the path environment variable to the install location (if you installed XenCenter on D: then it can be D:Program Files(x86)CitrixXenCenter), or change the xe.exe commands within the script to include the full path location.
      Change the $XenServerMst to the IP of your master, along with the right user/password, patch locations, and as it runs input the name of the server as it appears in the inventory. You can check with xe host-list to see how your XenServers are named, and test xe host-list name-label=hostnametoupdate and see if a uuid is returned.
      I have also seen copy and paste from browsers that change some special characters, be sure the right characters are in the script when using copy + paste from browsers especially for the quote and double quote’s.

      Hope this helps.

Leave a Reply

Your email address will not be published.