Wednesday, February 3, 2016

In part 1 of this series I wrote about how to extract data from the Citrix Desktop Delivery Controllers through remote PowerShell. Today I want to zoom in on the data returned from the Get-BrokerDesktop command and how to create useful sensors in PRTG to monitor a Citrix XenDesktop environment. As you can see in the documentation from the Get-BrokerDesktop command, there are actually a lot of useful parameters we can use to monitor the status of our desktops in Citrix XenDesktop. Let's start with a short recap:

# Get the Citrix Desktop Delivery Controller
$citrixddc = "YourCitrixDDCServer"

# Import module
if (-not (Get-module prtgshell)) {
    Import-Module prtgshell
    }

# Create a connection to the remote computer
$session = New-PSSession -ComputerName $citrixddc

# Run the commands on the remote computer
Invoke-command -Session $session -scriptblock {

    asnp Citrix*
    $result = Get-BrokerDesktop -MaxRecordCount 10000
} 

# Count the variable $result and print it to the variable $state.
$state = Invoke-Command -Session $session -ScriptBlock {$result}

To get a total of all desktops in Citrix XenDesktop:
$total = $state.count

If you want all the desktops in Citrix XenDesktops who are connected, you can do:
$connected = ($state | Where-Object {$_.SessionState -ilike "Active"} | Measure-Object -Property sessionstate).count

To get all the desktops in a disconnected state:
$disconnected = ($state | Where-Object {$_.SessionState -ilike "Disconnected"} | Measure-Object -Property sessionstate).count

To get all the desktops in which are in Maintenaince mode and Powered On.
$DesktopsInMaintenaince = ($state | Where-Object {$_.InMaintenanceMode -ilike "True" -and $_.PowerState -eq "On"} | Measure-Object -Property InMaintenanceMode).Count

I think you will get the idea right? You can make as many combinations as you want for the things you want to monitor!

The last thing we have to do is to write the result to PRTG. Here you have two options:

1: You create one sensor with different channels: This would be the most suitable solution in most cases. The advantage is that, since you have all the data under one sensor, PRTG sets up one remote connection for each scanning interval, gathers all the data at once and updates all the values in the sensor. The disadvantage with this solution is that it is not possible to have the value of each channel on a PRTG map, since the map function in PRTG always shows the value of the primary channel. This is why I go for option 2.

2: You create different sensors with one channel for each sensor. As described above, with this option we can create a PRTG map to make an overview of the status of the desktops: number connected/disconnected/in maintenance/powered off etc. The disadvantage is that each polling interval, PRTG sets-up a remote connection to the Desktop Delivery Controller per sensor. So if we create 15 sensors to monitor different desktop statuses, PRTG creates 15 different connections to the Citrix Desktop Delivery Controller.

To limit to amount of scripts you use for PRTG, I always use the parameter setting under the advanced exe script sensor. With the parameter setting, it is possible to define a parameter for the script.



Here is the full script, to use this script, you will need the prtgshell PowerShell function as described here

# Get variables from PRTG
param (
   [parameter(Mandatory=$true,Position=0)]
   [string]$object
   )

# Import module
if (-not (Get-module prtgshell)) {
    Import-Module prtgshell
    }

# Get the Citrix Desktop Delivery Controller
$citrixddc = "YourCitrixDDCServer"
# Create a connection to the remote computer
$session = New-PSSession -ComputerName $citrixddc

# Run the commands on the remote computer
Invoke-command -Session $session -scriptblock {

    asnp Citrix*
    $result = Get-BrokerDesktop -MaxRecordCount 10000
} 


# Count the variable $result and print it to the variable $state.
$state = Invoke-Command -Session $session -ScriptBlock {$result}

# Start writing output to PRTG.
$XMLOutput = "<prtg>`n"

# Get the total number of desktops to calculate the percentage.
$TotalDesktops = $state.count

# TotalDesktops
if ($object -eq "TotalDesktops"){
$XMLOutput += Set-PrtgResult "Desktops: Totaal Aantal" $TotalDesktops "Desktops"
}

#Desktops Connected
if ($object -eq "DesktopsConnected"){
$connected = ($state | Where-Object {$_.SessionState -ilike "Connected"} | Measure-Object -Property sessionstate).count
$XMLOutput += Set-PrtgResult "Desktops: Connected / Active" $connected "Desktops"
}


#Desktops Disconnected
if ($object -eq "DesktopsDisconnected"){
$disconnected = ($state | Where-Object {$_.SessionState -ilike "Disconnected"} | Measure-Object -Property sessionstate).count
$XMLOutput += Set-PrtgResult "Desktops: Disconnected / Active" $disconnected "Desktops"
}


# Desktops in Maintenaince mode
if ($object -eq "DesktopsInMaintenaince"){
$DesktopsInMaintenaince = ($state | Where-Object {$_.InMaintenanceMode -ilike "True" -and $_.PowerState -eq "On"} | Measure-Object -Property InMaintenanceMode).Count
$XMLOutput += Set-PrtgResult "Desktops: In Maintenance mode" $DesktopsInMaintenaince "Desktops"
}

# Disconnect the session
Remove-PSSession $session

#Finish writing to PRTG
$XMLOutput += "</prtg>"
write-host $XMLOutput

And the result

How to monitor Citrix XenDesktop with PRTG (Part 2)

Tuesday, February 2, 2016

A few weeks ago I wrote a post about the exe script advanced sensor and how to use this sensor in PRTG together with the prtgshell PowerShell module. One of the things that I use the exe script advanced sensor for is to monitor our VDI environment (Citrix XenDesktop), in particular the Citrix Desktop Delivery Controllers (Citrix DDC's) which deliver the virtual desktops to the end users. The Citrix Desktop Delivery controllers hold the status of all desktops in the VDI environment, so it is very useful to monitor the status of all the virtual desktops in PRTG. Let me go through the implementation step-by-step.

1. Create a new PowerShell script on the PRTG Core Server or Probe Server (depending where the DDC's are located) and call it "Citrix - Desktops statistics.ps1"

2. By design, PRTG doesn't have the capability to execute a PowerShell script on a remote server, even if you create the sensor under a device in PRTG which refers to that server. Therefore, we need to create a way to remotely connect to another server, gather the data we need and write this data to PRTG. I prefer to use Remote PowerShell for this. To use remote PowerShell, we have to enable this first on the DDC server. Login on the Citrix DDC server, open a PowerShell window (as administrator) and enter the following command:
Enable-psremoting -force
3. Next we can create a remote session to the Citrix Desktop Delivery Controller in the PowerShell script:

# Create a connection to the remote computer
$session = New-PSSession -ComputerName $citrixddc

# Run the commands on the remote computer
Invoke-command -Session $session -scriptblock {  

    asnp Citrix*
    $result = Get-BrokerDesktop -MaxRecordCount 10000
} 

# Count the variable $result and print it to the variable $state.
$state = Invoke-Command -Session $session -ScriptBlock {$result}

Please check the Citrix support page Get-BrokerDesktop for more information.

4. As a result, we have the output of all desktops in the variable $state. To get the total of all desktop registrered in Citrix:
$total = $state.count




In this (small) environment we have a total of 311 desktops registered with the Desktop Delivery Controller.

5. Write this result to PRTG:
# Start writing output to PRTG.
$XMLOutput = "<prtg>`n"
$XMLOutput += Set-PrtgResult "Desktops: Total" $total "Desktops" 
$XMLOutput += "</prtg>"
write-host $XMLOutput

6. Result:
















The final script would be:

# Get the Citrix Desktop Delivery Controller
$citrixddc = "YourCitrixDDCServer"

# Import module
if (-not (Get-module prtgshell)) {
    Import-Module prtgshell
    }

# Create a connection to the remote computer
$session = New-PSSession -ComputerName $citrixddc

# Run the commands on the remote computer
Invoke-command -Session $session -scriptblock {

    asnp Citrix*
    $result = Get-BrokerDesktop -MaxRecordCount 10000
} 

# Count the variable $result and print it to the variable $state.
$state = Invoke-Command -Session $session -ScriptBlock {$result}

# Count all the desktops. 
$TotalDesktops = $state.count

# Start writing output to PRTG.
$XMLOutput = "<prtg>`n"
$XMLOutput += Set-PrtgResult "Desktops: Total" $TotalDesktops "Desktops" 
$XMLOutput += "</prtg>"
write-host $XMLOutput

Now we have one sensor with one channel showing all the desktops registered. In part 2 of this series I'll give some more examples of fun things that we can do to monitor the status of the desktops in Citrix XenDesktop.

Continue with part 2 of this series!

How to monitor Citrix XenDesktop with PRTG (Part 1)