I saw a post on the support forum today asking for help with the XenDesktop PowerShell SDK. I came up with a quick script to help them out, which inspired me to share some XD5 script examples. If you’re not already familiar with running Powershell cmdlets and scripts in a XenDesktop environment, please refer to the Citrix Blogs ‘XenDesktop SDK Primer‘ series for help getting started.

The first example that I wanted to share is from the script I came up with to help achieve the forum poster’s desired behavior, which was to find a logged on user and restart the desktop they were logged onto:

$user = '<em>Domain\UserName</em>'
asnp citrix.b*
foreach ($desktop in Get-BrokerDesktop -SessionUserName $user -SummaryState InUse)
{
Write-Output "Found $($desktop.SessionUserName) logged on to $($desktop.MachineName) from $($desktop.ClientName). Restarting $($desktop.MachineName)."
New-BrokerHostingPowerAction -Action Restart -MachineName $desktop.MachineName
}

This script begins by assigning the desired user name to the $user variable. It then loads the Citrix.Broker.Admin.V1 snap-in, and goes into a foreach loop on the output of ‘Get-BrokerDesktop -SessionUserName $user -SummaryState InUse’. Each InUse desktop with a ‘SessionUserName’ of $user is returned, and output is written to the console indicating the match, and that a restart command (via New-BrokerHostingPowerAction) is being sent to the desktop.

Running a foreach loop on the output of a filtered ‘Get-BrokerDesktop’ output can provide a lot of control over an environment. Here’s a more advanced script that finds Unregistered/Powered-on desktops, checks the Citrix Desktop Service status via WMI, and restarts the service if it’s running or starts the service if it wasn’t running:

asnp citrix.B*
foreach ($desktop in Get-BrokerDesktop -SummaryState 'Unregistered' -PowerState On)
{
 try
 {
 $service = gwmi win32_service -filter "name='workstationagent'" -computername $desktop.DNSName -ErrorAction Stop
 Write-Output "$($desktop.MachineName) - $($service.DisplayName) is '$($service.State)'"
 if ($service.State -Match 'Running')
 { Write-Output "Restarting the $($service.DisplayName) on $($desktop.MachineName)"
 $stopstatus = $service.StopService();
 if ($stopstatus.ReturnValue -eq 0)
 { Write-Output "Stopped the $($service.DisplayName) on $($desktop.MachineName), starting it back up.."
 Start-Sleep -Second 2
 $startstatus = $service.StartService();
 if ($startstatus.ReturnValue -eq 0)
 { Write-Output "Started the $($service.DisplayName) on $($desktop.MachineName)" } } }
 if ($service.State -Match 'Stopped')
 { Write-Output "Starting the $($service.DisplayName) on $($desktop.MachineName)"
 $startstatus = $service.StartService();
 if ($startstatus.ReturnValue -eq 0)
 { Write-Output "Started the $($service.DisplayName) on $($desktop.MachineName)" } } }
 catch [Exception]
 { Write-Output "$($desktop.MachineName) - $($_.Exception.Message.ToString())" } }

Here’s another script that performs a power action on each desktop in a site based on a desktop’s power state and registration status:
asnp Citrix.Broker*
foreach ($desktop in Get-BrokerDesktop -MaxRecordCount 10000)
{
 if ($desktop.PowerState -eq 'On')
 {
 if ($desktop.SummaryState -eq 'Unregistered')
 {
 #If powered-on and unregistered, perform a forceful restart
 New-BrokerHostingPowerAction -MachineName $desktop.MachineName -Action Reset
 }
 if ($desktop.SummaryState -eq 'Disconnected')
 {
 #If powered-on and disconnected, check for sessions older than 90 minutes
 $timediff = (Get-Date) - $desktop.SessionStateChangeTime

if ($timediff.TotalMinutes -gt 90) { New-BrokerHostingPowerAction -MachineName $desktop.MachineName -Action Restart } }

if ($desktop.SummaryState -eq 'Available') { #If powered-on and ready, perform a graceful restart New-BrokerHostingPowerAction -MachineName $desktop.MachineName -Action Restart } }

if ($desktop.PowerState -eq 'Off') { #If powered-off, turn it on New-BrokerHostingPowerAction -MachineName $desktop.MachineName -Action TurnOn } }

Well, I think that’s enough for a Part 1. Let me know if  you have any questions about any of these examples, or suggestions on better/quicker ways to accomplish the same results!