Using PowerShell to Retrieve Citrix Monitor Data via OData
Starting with XenDesktop 7, Citrix stores the data the Desktop Director displays in a SQL database. Citrix opened up this data via a Monitor Service API that uses OData. I’m not going to go deep into the details of the API as it is fairly well documented at the eDocs site. The examples in the documentation show you how to access this data via web browser, Microsoft Excel, and LinqPad. What I want to do in this article is show you how to use PowerShell with this API.

Starting with XenDesktop 7, Citrix stores the data the Desktop Director displays in a SQL database. Citrix opened up this data via a Monitor Service API that uses OData. I’m not going to go deep into the details of the API as it is fairly well documented at the eDocs site. The examples in the documentation show you how to access this data via web browser, Microsoft Excel, and LinqPad. What I want to do in this article is show you how to use PowerShell with this API.
To start out, let’s take a look at the Citrix Monitor Service schema (click to enlarge):
Suppose we want to get all sessions as well as the all the connection/disconnections to the session. The following URL will return the data we want in XML format.
http://localhost/Citrix/Monitor/Odata/v1/Data/Sessions
The trick to get this working with PowerShell is to transform all this information into a nice hierarchical structure. In the example code below, we use the Invoke-ODataTransform
function to do this.
function Global:Invoke-ODataTransform ($records) { $propertyNames = ($records | Select -First 1).content.properties | Get-Member -MemberType Properties | Select -ExpandProperty name foreach($record in $records) { $h = @{} $h.ID = $record.ID $properties = $record.content.properties foreach($propertyName in $propertyNames) { $targetProperty = $properties.$propertyName if($targetProperty -is [System.Xml.XmlElement]) { $h.$propertyName = $targetProperty.'#text' } else { $h.$propertyName = $targetProperty } } [PSCustomObject]$h } } $connections = "" $uri = "http://localhost/Citrix/Monitor/OData/v1/Data/Sessions?`$expand=Connections" $connections = Invoke-ODataTransform(Invoke-RestMethod -Uri $uri -UseDefaultCredentials) foreach($connection in $connections) { $output = $connection | Get-Member -MemberType Properties | ForEach-Object { $key = $_.Name $value = $connection.$key '{0}="{1}"' -f $key,$value } Write-Host $output }