Showing posts with label PowerShell. Show all posts
Showing posts with label PowerShell. Show all posts

Wednesday, 6 July 2011

Creating a Server Monitoring Graph in XenApp 6.0 and 6.5

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.

Citrix Server Graph

 

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
$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

# save the chart to a file
$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

Friday, 5 November 2010

Notes on PowerShell in XenApp 6

Powershell v2 comes installed by default on Windows Server 2008 R2.  Citrix have followed Microsoft’s example with products such as Exchange in providing a fairly thorough set of commands in Powershell to monitor and administer the farm.  And with the loss of MFCOM as a way of command line farm administration, its become an essential skill.  Personally I have no real need at the moment to use Powershell for actions such as publishing applications as our environment is still small enough to be faster to administer with the Delivery Services Console, but for any mass change to the farm the command line will become far faster and for monitoring, its great.
To easily be able to use PowerShell to administer XenApp 6, first you need to download and install the SDK.  And I like to have my admin tools as published apps, so this is how to create a XenApp 6 PowerShell based management application as a hosted application on your farm:
Publishing the PowerShell console with XenApp commands
  • Download the XenApp Powershell SDK : http://community.citrix.com/display/xa/XenApp+6+PowerShell+SDK
  • Extract and execute the installer
  • Agree to change the execution level to AllSigned
  • Publish an application to this server with the following location:
    C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoExit -File "c:\Program Files\Citrix\XenApp Server SDK\Citrix.XenApp.Sdk.ps1"
  • Launch your new editor
  • By default it will not be set up to recognise XenApp commands while editing, so use the command:
    Add-PSSnapin Citrix*

    image 
Publishing the PowerShell ISE Editor
You can use Notepad to edit your PowerShell scripts – but that’s not very fun so let’s publish an application “Windows PowerShell Integrated Scripting Environment (ISE)”. This is a very good editor for developing PowerShell scripts, with a nice window to run them in and some basics like automatic colouring of your code.  Of course, you can skip this if you like Notepad…
  • Login to your XenApp 6 server
  • Go to Command Prompt
  • Enter this command: 
    servermanagercmd -install PowerShell-ISE
  • It will whinge and then work anyway:
    image
  • Publish a hosted application on your farm at:
    c:\windows\sysWOW64\WindowsPowerShell\v1.0\PowerShell_ISE.exe
  • Again, you will need to run the command “Add-PSSnapin Citrix*” to preload all the commands for XenApp.  In ISE, you can enter quick commands like this in the bottom window, then build up your scripts in the tabbed top window.  The middle window displays any console output.
image 
Some useful basic commands for XenApp in PowerShell
I’m planning a much bigger post on this, but in the meantime, here’s some really basic bits of code to show you what you can do with PowerShell…
Display the farm name
$farm = Get-XAFarm   
$farm.FarmName
Display the zone name data collector for a zone (the zone of the XenApp server you run on of course)
$zone = get-XAzone
$zone.ZoneName
$zone.DataCollector
Display counts for the total number of active and disconnected sessions in the farm
Get-XASession -Farm | where-object {$_.State -eq "Active" } | Measure-object
Get-XASession -Farm | where-object {$_.State -eq "Disconnected" } | Measure-object
Display a list of all your farm servers, listed alphabetically, with the number of sessions on each:
$servers = Get-XAServer -full   
$output = "`nServers: `n"
    foreach($server in $servers | sort-object ServerName){
        $output+=$server.ServerName + "  " + $server.SessionCount + "`n"
    }
$output
Remember if you are saving any of these its best to put the command “Add-PSSnapin Citrix*” at the top to make sure it always has the Citrix commands loaded.  You should really consider signing your scripts as well – which is an art in itself!