Citrix Endpoint Management Reporting API

Code samples and SDKs

The following Powershell script allows you to paginate and throttle seamlessly.

 <#
.SYNOPSIS
   Reporting script
.DESCRIPTION
   Allows to query for device, application, enrollment profiles, software inventories, users, certificates and keystore from the customer
.NOTES
    Author: Citrix Systems Inc.
    Params:
        -Server: the server uri with port included
        -Username: username of the customer admin credentials
        -SecurePassword: password of the customer admin credentials
        -ClientId: generated by CC in the portal developer
        -ClientSecret: generated by CC in the portal developer
        -QueryTemplateFile: file with the query template body
#>

param (
    [Parameter(Mandatory=$true)][string]$Server,
    [Parameter(Mandatory=$true)][string]$QueryTemplateFile,
    [Parameter(Mandatory=$false)][string]$Username,
    [Parameter(Mandatory=$false)][Security.SecureString]$SecurePassword,
    [Parameter(Mandatory=$false)][Security.SecureString]$ClientId,
    [Parameter(Mandatory=$false)][Security.SecureString]$ClientSecret
)

[string]$CONTINUATION_TOKEN_HEADER = 'Citrix-Continuation-Token'
[string]$AUTH_TOKEN_HEADER = 'auth_token'
[string]$CITRIX_CUSTOMER_ID_HEADER = 'Citrix-CustomerId'

function Get-CemAuthenticationToken {
    Param ([string]$Username, [Security.SecureString]$SecurePassword, [string]$Server)

    $LoginUriSuffix = '/api/endpoint-management/console/$login'
    $LoginUri = $server + $LoginUriSuffix

    $Payload = @{
        login = $Username
        password = ConvertFrom-SecureString $SecurePassword -AsPlainText
    }

    $Body = (ConvertTo-Json $Payload)

    Try {
        Write-Information -Message "Authenticating ..."

        $Response = Invoke-RestMethod -Uri $LoginUri -ContentType 'application/json' -Body $Body -Method Post -Verbose
        $AuthToken = $Response.authToken

        Write-Information -Message "Authentication sucessfull"

        return $AuthToken
    }
    Catch {
        Write-Error -Message "An error ocurred while authenticating. Try again ..."
        return $null
    }
}

function Get-CemAuthenticationTokenWithSecretCredentials {
    Param ([Security.SecureString]$ClientId, [Security.SecureString]$ClientSecret, [string]$Server)

    $LoginUriSuffix = '/api/endpoint-management/console/$secretCloudLogin'
    $LoginUri = $server + $LoginUriSuffix

    $Payload = @{
        clientId = ConvertFrom-SecureString $ClientId -AsPlainText
        clientSecret = ConvertFrom-SecureString $ClientSecret -AsPlainText
    }

    $Body = (ConvertTo-Json $Payload)

    Try {
        Write-Information -Message "Authenticating with CC client secret ..."

        $Response = Invoke-RestMethod -Uri $LoginUri -ContentType 'application/json' -Headers $Headers -Body $Body -Method Post -Verbose
        $NewAuthToken = $Response.authToken

        Write-Information -Message "Authentication successful"

        return $NewAuthToken
    }
    Catch {
        Write-Error -Message "An error ocurred while authenticating with CC client secret. Check CEM version, make sure LOGIN_USING_SECRET_CLOUD_CREDENTIALS feature flag is enabled and try again ..."
        return $null
    }
}

function Get-CemAuthentication {

    If ($null -ne $ClientId -and $null -ne $ClientSecret) {
        return Get-CemAuthenticationTokenWithSecretCredentials -ClientId $ClientId -ClientSecret $ClientSecret -Server $Server
    }
    ElseIf ($null -ne $Username -and $null -ne $SecurePassword) {
        return Get-CemAuthenticationToken -Username $Username -SecurePassword $SecurePassword -Server $Server
    }

    Write-Error -Message "An error ocurred. Check script input parameters."
    return $null
}

function Debug-CemException {
    Param ([Microsoft.PowerShell.Commands.HttpResponseException]$CemException, [string]$Server)

    If ($CemException.Response.StatusCode.value__ -eq '401') {
        Write-Output 'Reauthenticating ...'

        # if authentication expire while fetching segments re-authenticate
        $AuthToken = Get-CemAuthentication
        $RequestHeaders.Set_Item($AUTH_TOKEN_HEADER, $AuthToken)
    }
    ElseIf ($CemException.Response.StatusCode.value__ -eq '429') {
        $retryAfter = $CemException.Response.Headers.RetryAfter.Delta.Seconds

        Write-Output "Retrying in ($retryAfter) seconds ..."
        Start-Sleep -s $retryAfter
    }
}

function Get-CemSegmentsInformation {
    Param ([String]$Server, [String]$Username, [Security.SecureString]$SecurePassword, [Security.SecureString]$ClientId, [Security.SecureString]$ClientSecret, $RequestHeaders, [string]$QueryPayloadFilePath)

    $ReportingUriSuffix = '/api/endpoint-management/report/$search'
    $ReportingUri = $Server + $ReportingUriSuffix

    $BodyPayload = Get-Content -Path $QueryPayloadFilePath | ConvertFrom-Json

    # replace ':' for '-' since windows path does not support ':' character
    $CurrentDate = Get-Date -Format 'dddd-MM-dd-yyyy-HH:mm:ssK'
    [string]$ResultFileName = "./result-$($CurrentDate).csv" -Replace ':','-'

    Do {

        Try {
            $Response = Invoke-WebRequest -Uri $ReportingUri -Method Post -Headers $RequestHeaders -ContentType 'application/json' -Body (ConvertTo-Json $BodyPayload)
            $Response.Content | Out-File -Append -Force -NoNewline -FilePath $ResultFileName

            Write-Output $Response.Content

            [String]$ContinuationToken = ''

            if ($Response.Headers.ContainsKey($CONTINUATION_TOKEN_HEADER)) {
                [String]$ContinuationToken = $Response.Headers[$CONTINUATION_TOKEN_HEADER]
                $RequestHeaders.Set_Item($CONTINUATION_TOKEN_HEADER, $ContinuationToken)
            }
        }
        Catch [Microsoft.PowerShell.Commands.HttpResponseException] {

            Write-Output $_.Exception.Response.ReasonPhrase
            # pretty print the json body response
            Write-Output $_.ErrorDetails.Message | ConvertFrom-Json | ConvertTo-Json

            Debug-CemException -CemException $_.Exception -Server $Server
        }
        Catch {
            Write-Error $_
            Exit
        }

    }
    Until ([string]::IsNullOrEmpty($ContinuationToken))
}

$Headers = @{}
$Headers.Add($CITRIX_CUSTOMER_ID_HEADER, $Username)

$AuthToken = Get-CemAuthentication

If ($null -eq $AuthToken) {
    Exit
}

$Headers.Add($AUTH_TOKEN_HEADER, $AuthToken)

Write-Output "Getting information ..."

Measure-Command {
    Get-CemSegmentsInformation -Server $Server -Username $Username -SecurePassword $SecurePassword -ClientId $ClientId -ClientSecret $ClientSecret -RequestHeaders $Headers -QueryPayloadFilePath $QueryTemplateFile | Out-Default
}

Write-Output "Finished."
<!--NeedCopy-->

How to use the Powershell script

Install PowerShell version 7.1 or later. To invoke the script, provide the following:

  1. Username and password of the customer admin or the Client Id and secret credentials to authenticate.
  2. The template query as a file.
  3. A server URL.
Resources
Citrix Endpoint Management Reporting API OpenAPI Specification
Copy Download
Code samples and SDKs