Overview of Script Samples using PowerCLI for Horizon

Automation for VMware Horizon has never been as accessible as it is today. Between your choice of the Horizon REST API and PowerCLI, you can leverage the scripting language or platform of your choice to invoke the underlying APIs. Today I’ll share a few samples of code that I use on a regular basis, along with a couple of tips. The examples below will be provided in PowerShell, but many of them that utilize the REST API are portable to most other languages.
First off, be sure to check up on Automating VMware Horizon 7 with VMware PowerCLI to get a primer on using PowerCLI for Horizon. That will provide you with a baseline to use the following examples, as well as setting you up with the Advanced Functions provided in the VMware.Hv.Helper module.
Connect to the API
Start by connecting to the API, and optionally declare an object to store the session in:
$HVServer = Connect-HVServer -Server connectionserver.domain.tld
Pro Tip: If you’re running PowerCLI from within a Horizon session, and want to connect to the Connection Server, use this code snippet:
$HVServer = Connect-HVServer -Server $env:ViewClient_Broker_DNS_Name
Enumerating The API with ConvertTo-JSON
If you’ve ever wanted to explore the API, then certainly the documentation is a good start. However, there’s another way that involves never having to leave your shell. This is helpful for those times that a certain API call doesn’t return helpful or human-readable information.
$HVServer.ExtensionData.ConnectionServer.ConnectionServer_List()
will give you a list of Connection Servers in the connected Horizon Pod, but it’s difficult to do anything with this information, as you can see below:
Figure 1: The output of the ConnectionServer_List() method, though not that useful
However, if you pipe that into ConvertTo-JSON, then suddenly you get some more useful information:
$HVServer.ExtensionData.ConnectionServer.ConnectionServer_List() | ConvertTo-JSON
Figure 2: A more useful and informative display, piping ConnectionServer_List() into ConvertTo-JSON
Using Get-HVEvent
I’ll admit that using Get-HVEvent was not that intuitive for me at first. Here’s a primer for how it works.
- First, instantiate an object for the Events Database. This will query the pod for the configured Events Database and store it in our new object.
$HVDB = Get-HVEventDatabase
- Build an object for the password needed to connect to the Events Database. Note that this will use the password for the SQL Server account that’s already in use for the Events Database.
$HvDbPassword = Read-Host "Please input the password for account $($HVDb.UserName)" -AsSecureString
- Third, we’ll use that to make the connection to the Events Database. The naming here doesn't matter, but I try to match parameter names where possible:
$HvDbServer = Connect-HVEvent -DbUserName $HVDb.UserName -DbPassword $HvDbPassword
Now that we’re connected, we can make queries against the database. For example, let’s find all events related to a user connecting to a desktop agent:
Get-HVEvent -HvDbServer $HvDbServer -TimePeriod all -ModuleFilter Agent -MessageFilter "mfrey has logged in to a new session on machine"
We could also list all events with a Severity of Error:
Get-HVEvent -HvDbServer -TimePeriod all -SeverityFilter Error
Perhaps you want to list all events related to administrators:
Get-HVEvent -HvDbServer -TimePeriod all -ModuleFilter Admin
Query Information About Sessions
Session information is another tricky one because there is no single method which will return all sessions for a given Pod. Instead, we must turn to the QueryService. The QueryService can be used for returning information about entities that do not have their own _List() or _Get() methods. Let's walk through that process now.
- Create the QueryService object, which may have an odd name, but nonetheless this is no typo:
$QueryService = New-Object VMware.Hv.QueryServiceService
- Next up, let's create an object for the QueryDefinition.
$QueryDefinition = New-Object VMware.Hv.QueryDefinition
- Now that we have the QueryDefinition object, we need to set the QueryEntityType, which is to say, "what type of object are we querying for?" In this case, we want to query the SessionLocalSummaryView data type.
$QueryDefinition.queryEntityType = 'SessionLocalSummaryView'
- Now we're ready to list all of the sessions on the local pod.
$QueryResults = $QueryService.QueryService_Create($HVServer.ExtensionData,$QueryDefinition).Results
If we were to view the results now, you can see that it's not very human-readable:
$QueryResults | Format-Table
Figure 3: A table of Horizon Sessions, though not in a readable format
Our previous tip to use ConvertTo-JSON
is a bit messy as well, since there's more information than we need. This is where the property NamesData comes in handy. Most query-able entities will return the NamesData property. This property contains mostly human-readable data related to the sessions, so it is good for reporting.
$QueryResults.NamesData | Format-Table -AutoSize
Figure 4: Improve readability of the NamesData property
If you want to filter based on a certain username, you can use a query filter of QueryFilterEquals. We could also use a query filter of QueryFilterContains, though that can be a bit slower in large environments.
$QueryFilterEquals = New-Object VMware.Hv.QueryFilterEquals
$QueryFilterEquals.memberName = 'namesData.userName'
$QueryFilterEquals.value = 'domain\username'
$QueryDefinition.Filter = $QueryFilterEquals
$QueryResults = $QueryService.QueryService_Create($HVServer.ExtensionData,$QueryDefinition).Results
$QueryResults.NamesData
Figure 5: Querying sessions for a specific user
To learn more about the Query Service, visit the ViewAPI Documentation, then look for the Query Service page.
Summary
Thanks for reading through my code samples. My hope is that this will help spur ideas for how to improve your scripting of Horizon with PowerCLI.
Be sure to subscribe to the Digital Workspace Tech Zone Blog RSS or check back on this blog post daily to see what we release. We'll add each day's topic to agenda on this page with a link to keep you organized. By the end of this month, we hope that you are comfortable leveraging code samples, VMware Flings, scripting/coding, and leveraging the EUC APIs to automate your workspace!
You can also follow us on Twitter @EUCTechZone to stay updated on the latest EUC content!
Agenda
Make sure to check out the other blog posts in our 28-day series:
- Day 1: Let's Git Commit(ted) to Dev Resources
- Day 2: Getting Started with the Workspace ONE UEM REST APIs
- Day 3: Getting Started with the Workspace ONE Access APIs
- Day 4: Getting Started with the VMware Workspace ONE Intelligence APIs
- Day 5: Getting Started with the VMware Horizon REST APIs and VMware PowerCLI
- Day 6: Getting Started with Automating the Unified Access Gateway Deployment
- Day 7: Podcast: Day 0 Onboarding Automation with Scot Curry
- Day 8: Video: Anatomy of the Workspace ONE UEM API
- Day 9: Introduction to using Postman - Part 1
- Day 10: Introduction to using Postman - Part 2
- Day 11: Pro Tips and Tricks - How to be an API Boss
- Day 12: What is OAuth - Learning the Basics
- Day 13: Getting Started with Intelligent Hub Notifications
- Day 14: Git Basics: Getting Git Going
- Day 15: Podcast: Git Commit(ted) to Resources: Customer Spotlight with The Home Depot
- Day 16: Git VMware {code} Samples and Flings
- Day 17: Using paginated requests with Workspace ONE UEM REST APIs
- Day 18: Event Notifications
- Day 19: Overview of Script Samples using PowerCLI for Horizon
- Day 20: Uploading Windows apps using REST APIs
- Day 21: Uploading macOS apps using REST APIs and Admin Assistant
- Day 22: API-based user lifecycle and SCIM
- Day 23: Video: Community Expert Roundtable on Leveraging APIs and Scripting
- Day 24: Video: Exploring the Workspace ONE GitHub Samples Repository
- Day 25: Featured Fling: Forklift for Workspace ONE UEM
- Day 26: Featured VMware {code} Samples for Horizon
- Day 27: Featured Flings for VMware Horizon
- Day 28: Continuing to Focus on </Dev> Resources Page