Knowing what is going on in your Citrix farm is always difficult when there are more than a few users and servers involved. Edgesight is very useful for this in XenApp, but it does lack a decent Dashboard function so you can tell at a glance what the load is like on your servers.
In previous versions of Citrix I’ve seen people write applications which use MFCOM to find out how many sessions are on each server and write them out to a nice graph – you can then see at a glance whether for instance everyone is on one server, or if a server appears to have rebooted or been left disabled.
The way I do this currently is using a PowerShell script, running as a scheduled task. This then creates image files which I can display in a webpage.
In this earlier article I showed how you could download and install the Citrix components into PowerShell and use it to control the farm. Its worth doing this, and also using the PowerShell ISE Editor to write your PowerShell scripts.
You should also download something that will let you create graphs from PowerShell. An easy and free way of doing this is the MS Chart Controls for .NET 3.5 download. You can download this from here:
http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=14422
The first step is to use Powershell to get a list of the server names that you are interested in, and a list of the active sessions on the farm. Install the XenApp Powershell SDK from here and run the following from a farm serer. The first line is required to load the Citrix add-ons you just installed to PowerShell:
Add-PSSnapin Citrix*
$filter = 'xen'
$servernames = Get-XAServer | where-object {$_.ServerName -match $filter} | select-object ServerName
$sessionsactive = Get-XASession -Farm | where-object {$_.State -eq "Active" -and $_.ServerName -match $filter}
The value of $filter can be edited to filter on server name – only server names including that string will be measured. If you set it to just be ‘’, all servers will be used.
This should give you a pair of arrays, $Servernames and $sessionsactive, containing all the names and session details. Now we can iterate through the server names, finding out the number of active sessions for each on and writing it to another array, then finally sorting that array into alphabetical order by server name:
$servercounts = @{}
foreach ($servername in $servernames)
{
$countActive = @($sessionsactive | where-object {$_.ServerName -eq $servername.ServerName }| Select-Object SessionId -unique)
$servercounts.add($servername.ServerName, $countActive.Count)
}
$servercounts = $servercounts.GetEnumerator() | sort Name
You now have an array called $servercounts. If you ran it and exported its contents it would look something like this:
Name Value
---- -----
XEN01 28
XEN02 30
XEN03 31
XEN04 28
XEN05 28
XEN06 29
XEN07 28
XEN08 29
XEN09 27
Finally, time to generate the chart, if that is what you want. To use the MS Chart Controls (which will need to be installed on the XenApp server too) add these lines to the top of the script:
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms.DataVisualization")
Then add these lines to the end of the script to create the graph and save it to the c: drive as a PNG file. Note the lines to create a title for it as well, so you know whether the image is out of date:
# create chart object
$Chart = New-object System.Windows.Forms.DataVisualization.Charting.Chart
$Chart.Width = 900
$Chart.Height = 330
$Chart.Left = 10
$Chart.Top = 10# create a chartarea to draw on and add to chart
$ChartArea = New-Object System.Windows.Forms.DataVisualization.Charting.ChartArea
$Chart.ChartAreas.Add($ChartArea)
[void]$Chart.Series.Add("Data")
foreach ($server in $servercounts)
{
$dp1 = new-object System.Windows.Forms.DataVisualization.Charting.DataPoint(0, $server.Value)
$dp1.AxisLabel = $server.Name
$Chart.Series["Data"].Points.Add($dp1)
}$title = new-object System.Windows.Forms.DataVisualization.Charting.Title
$Chart.Titles.Add( $title )
$Chart.Titles[0].Text = date
$Chart.SaveImage("c:\Graph\XenAppFarm.png","png")
The script is best being signed (or remove the need for signing in PowerShell scripts) and then needs to be scheduled. I do this with a scheduled task on a XenApp server, which calls a batch file with contents of:
call powershell -command "& {C:\Graph\Generate.ps1}"
Finally you need a way of viewing the image – I just use a HTML file with an automated refresh, such as this:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>XenApp Farm</title>
<meta http-equiv="refresh" content="60">
</head>
<body>
<img src="c:\Graph\XenAppFarm.png">
</body>
</html>
Just to recap, here’s the whole sample script:
# load the appropriate assemblies
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms.DataVisualization")
Add-PSSnapin Citrix*
# get the server names and sessions
$filter = ''
$servernames = Get-XAServer | where-object {$_.ServerName -match $filter} | select-object ServerName
$sessionsactive = Get-XASession -Farm | where-object {$_.State -eq "Active" -and $_.ServerName -match $filter}$servercounts = @{}
# count active sessions for each server name
foreach ($servername in $servernames)
{
$countActive = @($sessionsactive | where-object {$_.ServerName -eq $servername.ServerName }| Select-Object SessionId -unique)
$servercounts.add($servername.ServerName, $countActive.Count)
}
$servercounts = $servercounts.GetEnumerator() | sort Name# create chart object
$Chart = New-object System.Windows.Forms.DataVisualization.Charting.Chart
$Chart.Width = 900
$Chart.Height = 330
$Chart.Left = 10
$Chart.Top = 10# create a chartarea to draw on and add to chart
# save the chart to a file
$ChartArea = New-Object System.Windows.Forms.DataVisualization.Charting.ChartArea
$Chart.ChartAreas.Add($ChartArea)
[void]$Chart.Series.Add("Data")
# add a data point for each server
foreach ($server in $servercounts)
{
$dp1 = new-object System.Windows.Forms.DataVisualization.Charting.DataPoint(0, $server.Value)
$dp1.AxisLabel = $server.Name
$Chart.Series["Data"].Points.Add($dp1)
}
# set the title to the date and time
$title = new-object System.Windows.Forms.DataVisualization.Charting.Title
$Chart.Titles.Add( $title )
$Chart.Titles[0].Text = date
$Chart.SaveImage("c:\Graph\XenAppFarm.png","png")
Resources used to write the above include:
http://blogs.technet.com/b/richard_macdonald/archive/2009/04/28/3231887.aspx
http://msdn.microsoft.com/en-us/library/system.windows.forms.datavisualization.charting.seriescharttype.aspx