[HorizonRestAPI] Trying some of those new funky Horizon 8 REST api’s

In my last post I promised to provide some examples of those new REST api’s in Horizon 8. A couple of things that I will show:

I have changed how I run my scripts a bit in that I decided to go even lazier and store my credentials in an xml file:

$credential = Get-Credential
$credential | Export-CliXml -Path 'C:\My\Path\cred.xml'

and in my script I retrieve them

$url = "https://pod1cbr1.loft.lab"

$credentials=Import-Clixml .\creds.xml

$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($password) 
$UnsecurePassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)

function Get-HRHeader(){
    return @{
        'Authorization' = 'Bearer ' + $($accessToken.access_token)
        'Content-Type' = "application/json"
function Open-HRConnection(){
        [string] $username,
        [string] $password,
        [string] $domain,
        [string] $url

    $Credentials = New-Object psobject -Property @{
        username = $username
        password = $password
        domain = $domain

    return invoke-restmethod -Method Post -uri "$url/rest/login" -ContentType "application/json" -Body ($Credentials | ConvertTo-Json)

function Close-HRConnection(){
    return Invoke-RestMethod -Method post -uri "$url/rest/logout" -ContentType "application/json" -Body ($accessToken | ConvertTo-Json)

$accessToken = Open-HRConnection -username $username -password $UnsecurePassword -domain $Domain -url $url

Invoke-RestMethod -Method Get -uri "$url/rest/config/v1/ic-domain-accounts" -ContentType "application/json" -Headers (Get-HRHeader -accessToken $accessToken)

[sta_anchor id=”sessions” unsan=”Sessions” /]


The first call I will show is immediately one of the more important ones: session information. Currently only local sessions seem to be available so we’ll have to wait for global session information. This is the call I will use:

$sessions=Invoke-RestMethod -Method Get -uri "$url/rest/inventory/v1/sessions" -ContentType "application/json" -Headers (Get-HRHeader -accessToken $accessToken)

with this result

So s lot of data but less directly readable results than the soap api’s but we do see all of it including deeper levels. For applications we do see something new though.

Yes that’s actually the local application that the user launched. In this case it was through a Global Entitlement named Global_Notepad so it’s not showing that. According to the soap api’s this should also be shown there but they never do as far as I know.

[sta_anchor id=”messages” /]


One of the other things that we can do is send messages. For this we need to create an variable with the following information:

  "message": "Sample Info Message",
  "message_type": "INFO",
  "session_ids": [

To make it more fun I will send a message to all my desktop sessions I put those first into an variable

$desktopsessions=$sessions | where {$_.session_type -eq "DESKTOP"}

and I will create the json like this

  "message"="Wouter is sending a message";
  "session_ids"=$desktopsessions.id -as [string[]]

this I will convert to a json and use the Put method

  "message"="Wouter is sending a message";
  "session_ids"=$desktopsessions.id -as [string[]]
$body = $json | ConvertTo-Json
Invoke-RestMethod -Method Post -uri "$url/rest/inventory/v1/sessions/action/send-message" -ContentType "application/json" -Headers (Get-HRHeader -accessToken $accessToken) -body $body

As you see I get all status codes 200 back so I know it was a success and we do see that on the desktops as well.

[sta_anchor id=”machines” unsan=”Machines” /]


So getting all machines is as easy as 1,2,3 with /inventory/v1/machines.

$machines=Invoke-RestMethod -Method Get -uri "$url/rest/inventory/v1/machines" -ContentType "application/json" -Headers (Get-HRHeader -accessToken $accessToken)

Not a lot of new data, just less things we don’t need.

[sta_anchor id=”reset” unsan=”Reset” /]


If you look good you’ll see that the machine I was showing is in the already used state. In my lab this happens because often I power down the lab while I still have some sessions running. Let’s reset this machine. What do we need for this first the api method and that’s /inventory/v1/machines/action/reset for requires:

Since I am far from fluent in REST api’s and json this took me a while to find out but I did it like this

$body=((Invoke-RestMethod -Method Get -uri "$url/rest/inventory/v1/machines" -ContentType "application/json" -Headers (Get-HRHeader -accessToken $accessToken)) | where {$_.state -eq "ALREADY_USED"}).id -as [string[]] | convertto-json
Invoke-RestMethod -Method Post -uri "$url/rest/inventory/v1/machines/action/reset" -ContentType "application/json" -Headers (Get-HRHeader -accessToken $accessToken) -body $body

so I use the method to pull the machines, filter on the state being “ALREADY_USED”, take the id of this as a string and convert that to json. When select the body I need to add the quotes and straight brackets because if it is a single string the json won’t be usable json. I will show it later with multiple systems that it’s not needed with multiples.

$body=((Invoke-RestMethod -Method Get -uri "$url/rest/inventory/v1/machines" -ContentType "application/json" -Headers (Get-HRHeader -accessToken $accessToken))  | where {$_.state -eq "AVAILABLE"}).id -as [string[]] | convertto-json
Invoke-RestMethod -Method Post -uri "$url/rest/inventory/v1/machines/action/reset" -ContentType "application/json" -Headers (Get-HRHeader -accessToken $accessToken) -body $body

Bookmark the permalink.