During my more than 20 years of consulting, automation has always been one of my priorities.

The key to automation is, for the most part, scripting. Luckily, these days, our products have public APIs and can be handled through a wealth of programming and script languages. This post provides a “quick-start” to XenMobile’s REST API. This will lead to my next article, which will be mostly examples of PowerShell scripts for interacting with the REST API. The documentation for XenMobile REST API can be found here: https://docs.citrix.com/en-us/xenmobile/server/rest-apis.html.

For XenMobile, this automation could be something like creating scheduled tasks to create certain reports, creating your own self-service portals, automating application updates to XenMobile, or similar.

John Pigeret, a former Citrix employee, wrote a three-part series of blog posts about using XenMobile’s SOAP API (which was the predecessor to today’s XenMobile REST API) to generate invitations and extract data from the XenMobile environment. With SOAP, programming proved somewhat cumbersome, and some tricks had to be employed in order to make authentication work, as authentication was time-based, and you had to convert between time zones to get it working. With the REST API of today, authentication is a breeze, and the rest can be handled through simple web requests. I will be providing examples in this article, written in PHP, and MS PowerShell, as I believe those are two very feasible platforms for people to use. The methodology, however, can be used in any scripting language. You could even use a simple Linux shell, with CURL, to perform the tasks.

Ward van Besien has also written a PowerShell module, which can be found here. The module is well-written, but I choose not to use it in this blog series, as I would rather show how to use the API directly.

So, first off, in order to “see” what you are doing, I truly recommend using Advanced REST Client, which is a plugin for Chrome. I have also used another Chrome plugin, Postman, for performing uploads of files like certificates and binary data (ipa, apk, mdx) to the XenMobile services. You will be seeing examples of how to use this software through this blog.

I have also had cases, especially with file uploads, where I was able to upload the file through Postman, but unable to do so through PowerShell. Since XenMobile REST API is encrypted, and only available on port 4443, it is hard to debug this traffic directly. In order to do so, I used my favorite Swiss Army Knife, NetScaler, to create an HTTP-based load-balanced vServer, pointing to XenMobile’s SSL/4443 port. This enabled me to send unencrypted traffic to NetScaler, so I could create Wireshark traces of the request going from Postman, and the subsequent request I try to send from my script. Comparing the POST requests in these traces, I could find the difference, and modify the script to have it working.

The first thing you need to do, is to authenticate to XenMobile. This is done by sending an HTTP POST request to https://<yourxenmobileserver>:4443/xenmobile/api/v1/authentication/login, with JSON payload in the form of ‘{“login:” “username”, “password”: “password”}’. What you receive in return, is an authentication token as seen below. This token needs to be added to the HTTP Headers for all subsequent requests. The token is valid until you have not been using it for the “idle period” set in XenMobile server configuration.

advancedrestclient-login

Now we have an authentication token to use, and can move on to actually talking to XenMobile. For our next request, we use this auth_token as a header value, as shown below:

device-filter

In this picture, I also use a slightly different JSON body, saying I want to start with device number 0, and use an ascending sort order.

At the bottom of the picture, is the resultant JSON set. When I collapse the arrays, I can see that the JSON I get in my environment consists of the following nodes:

{
status“: 0
message“: Success
currentFilter“: {…}
filteredDevicesDataList“: 
 “totalCount“: 0
matchedRecords“: 4
}
Here, it can be useful to notice the two arrays, “currentFilter”, and “filteredDevicesDataList”. The “currentFilter” entry lists out all the filters used for performing this search. -Meaning that you can use this part of the data not only to see which filters are being used, but also which filters are supported. Incidentally, the filters are an exact copy of the ones you find inside the XenMobile admin console.
The next part, “filteredDevicesDataList”, is the array of the actual devices. Be aware that the actual number of devices returned, is by default 50 (if I recall correctly), so for large environments, it would make sense to add the “limit” keyword to the JSON body of the request. I have typically run this with “limit” set to 200, and then increasing “Start” by 200 for each iteration.
So, finally, to show how this works in “real code”, here are two pieces of code, both naturally working examples, showing how you can list devices in PowerShell and PHP, respectively (Note, this are samples, in real life, you should avoid hard-coding username, password, and which server to use):
PowerShell sample:
$headers=@{“Content-Type” = “application/json”}
$json=Invoke-RestMethod -Uri https://xenmobileserver.lab.local:4443/xenmobile/api/v1/authentication/login -Body ‘{“login”:”username”,”password”:”password”}’ -ContentType application/json -Headers $headers -Method POST
$headers.add(“auth_token”,$json.auth_token)
$devices=Invoke-RestMethod -Uri https://xenmobileserver.lab.local:4443/xenmobile/api/v1/device/filter -Body ‘{}’ -ContentType application/json -Headers $headers -Method Post
foreach($device in $devices.filteredDevicesDataList)
{
$output=$device.platform + “: ” + $device.userName
Write-Output $output
}
PHP Sample:
<?php
$json='{“login”:”username”,”password”:”password”}’;
$ch = curl_init(‘https://xenmobileserver.lab.local:4443/xenmobile/api/v1/authentication/login’);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, “POST”);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
‘Content-Type: application/json’,
‘Content-Length: ‘ . strlen($json))
);
$result = curl_exec($ch);
$data=json_decode($result,true);foreach ($data as $name => $value)
{
if( “$name” == “auth_token”)
{
$token=$value;
}
else
{
die;
}
}$json=”{}”;
$ch = curl_init(‘https://xenmobileserver.lab.local:4443/xenmobile/api/v1/device/filter’);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, “POST”);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
‘Content-Type: application/json’,
‘Content-Length: ‘ . strlen($json),
‘Auth_token: ‘ . $token)
);
$result = curl_exec($ch);
$data=json_decode($result,true);foreach ($data[‘filteredDevicesDataList’] as $device)
{
echo $device[‘platform’] . “: ” . $device[‘userName’] . “\n”;
}
?>
So, now it is time to just sit back, and wait for my follow-up blog posts on this subject. In the next edition, I will share more real-life scripts, creating CSV files based on database queries, and showing how to upload files to XenMobile. These scripts will also accept input-parameters, and optionally ask for your password in a secure way.
Disclaimer: Although these scripts have been tested and found to work well on current XenMobile releases, all testing should always be performed in proper test environments. The REST API and scripts work equally well for XenMobile Service, as for on-premise installations. For XenMobile Service, you should normally limit which IP addresses are allowed to use the administration communication ports for XenMobile (4443). If this is set up in your environment, you have to make sure the scripts are run from a computer with an approved IP address.

EMM banner