Shutting Down Unused Persistent XenDesktop VMs

When you use XenDesktop the only way it makes sense you may find that Citrix has not really put much effort into making that a smooth experience.

Persistent is a Second-Grade Citizen

XenDesktop is really designed to be used with pooled desktops – machines that are reset to a pristine state when the user logs off. Of course, stateless desktops are much better (and, importantly, cheaper) served from XenApp. This has been the topic of many a debate which I will not repeat here. But I will state that if you give a so-called knowledge worker a personal desktop, you better make sure that desktop is persistent.

Reality is merely an illusion, albeit a very persistent one. – Albert Einstein

Automatic Shutdown?

One of the many things that should be automatic but are not is power management. To be more exact: shutdown of unused private desktops (in XenDesktop 5.6). Although that capability is built into XenDesktop, it is de facto broken. Why? It only turns off machines that have been idle for a certain amount of time after a user logged off. That is all well, but what if you turn on all machines for patching and virus scanning regularly? In that case, XenDesktop power management remains inactive and machines never get shut down – turned on once, running forever.

Unlimited Disk, Limited RAM

If you have disk deduplication in place – which is practically a necessity with persistent desktops – you can create a nearly unlimited number of machines. Many more than you can run concurrently because you would run out of RAM. Why you would do that? Think test environment, where you probably only have a server or two, but everybody and his sister want a VM for the once a quarter application test they need to perform. In order for that scenario to work well, VMs that have not been used for some time need to be powered down or you will quickly run into the situation that RAM is exhausted and users complain because their VMs cannot be powered on when they try to connect.

So, what do we do when a product does not work the way we expect it to? We script our way around it!


Here is my simple script ShutdownUnusedVMs.ps1 which shuts down VMs that meet certain criteria:

  • Last connection at least 8 hours ago
  • No user currently connected
  • VMware Tools installed (otherwise the machine could only be turned off)

Configure the script to run as a scheduled task on a regular basis and the number of concurrently running machines should stay within reasonable limits. Just make sure to run it from a user account that has the appropriate permissions in XenDesktop and vSphere.

# ShutdownUnusedVMs by Helge Klein
# Variables that must be adjusted prior to use
$vCenter = "Name of your vCenter server"
$DDC = "Name of your XenDesktop DDC"
# Add the required snapins
Add-PSSnapin vmware.vimautomation.core
Add-PSSnapin citrix.*
# Connect to vCenter
Connect-VIServer $vCenter
# Define how long ago the last connection must have been for the VM to be considered for shutdown
$earliestTime = (Get-Date).AddHours(-8)
# Get the XenDesktop machine objects whose last connection time is long enough in the past and which are not in use
$xdMachinesToShutdown = Get-BrokerDesktop -AdminAddress $DDC | where {$_.LastConnectionTime -lt $earliestTime -and $_.PowerState -eq "on" -and $_.SummaryState -ne "InUse" -and $_.SummaryState -ne "Disconnected"}
# Log
$xdMachinesToShutdown | select HostedMachineName, LastConnectionTime, AssociatedUserFullNames | ft -AutoSize -Wrap | Out-File -Force .\xdMachinesToShutdown.txt
# Get the VMs to shutdown
$vmsToProcess = new-object system.collections.arraylist
foreach ($xdMachine in $xdMachinesToShutdown) {if ((Get-VM $xdMachine.HostedMachineName | get-view).summary.guest.toolsRunningStatus -eq "guestToolsRunning") {$vmsToProcess.add((Get-VM $xdMachine.HostedMachineName))}}
# Log
$vmsToProcess | select Name | ft -AutoSize -Wrap | Out-File  -Force .\vmsToShutdown.txt
# Shutdown
foreach ($vm in $vmsToProcess) {Get-VM $vm | Shutdown-VMGuest -Confirm:$false}

, ,

6 Responses to Shutting Down Unused Persistent XenDesktop VMs

  1. webster October 16, 2013 at 21:05 #


    shouldn’t adminaddress and viserver be parameters or maybe variables?


    • Helge Klein October 16, 2013 at 22:05 #

      Yes, of course, thanks for pointing that out. I guess I was a little lazy…but I have added variables now.

  2. Andrew Wood October 17, 2013 at 02:10 #

    But if the recommendation for a VM environment is to have power management disabled ( .. looking at the HP document referenced you’re looking at a saving /year of @$270/ server by shutting down the VMs on a server yes?

    • Helge Klein October 17, 2013 at 13:09 #

      If you have many VMs idling on a server, a lot of RAM is used (which draws power, too), but the CPU might not be busy at all. Shutting down unused VMs might reduce power consumption somewhat, but I am not sure how much.

  3. Ken Bell October 23, 2013 at 17:39 #

    Doesn’t do the guest tools check, but if you want something that works on any XD-supported hypervisor:
    New-BrokerHostingPowerAction -Action Shutdown -MachineName ‘XD_VDA1’

    • Helge Klein October 23, 2013 at 20:31 #

      If I remember correctly I experimented with that but found that using PowerCLI commands is more reliable. Plus it allows me to check if the VMware Tools are running (which you mentioned).

Leave a Reply