While watching the VMworld US 2019 video of Sean Massey presenting about getting started with the Horizon API’s I decided to check if the API explorer has been updated. To my surprise it was and it is good to see that several queries have been added besides the method’s that I previously found.
The new queries that I found are:
DesktopAssignmentView
Description:
Desktop id + Desktop assignment data which will include desktop pool information, operation system, global entitlement.
DesktopHealthInfo
Description:
Desktop health Information. This data will be populated only for the desktops which support application remoting.
GlobalEntitlementSummaryView
Description:
Summary information about Global Entitlements.
MachineSummaryView
Description:
This View includes summary data of all entities related to this Machine
So the DesktopAssignmentView seems to give a lot of similar data to what the DesktopSummaryData query already gives. They both give global entitlement data plus user assignment data. The big difference is that it gives way more detailed information about the desktop pool itself like vGPU settings. The names should have been DesktopInfo in my opinion.
Desktophealthinfo is created for the new Windows 10 App remoting and the monitoring for that. The globalentitlementsummaryview and machinesummaryview are linked to GlobalEntitlementInfo and MachineDetailsView from which they give a subset of data.
I hope to have a new blog post soon with more detailed information of what the new method’s and queries will bring but I wanted to update you with the fact that the api explorer has been updated as soon as possible.
So today PowerCLI 11.4 was released with the following updates:
Add support for Horizon View 7.9
Added new cmdlets to the Storage module
Updated Storage module cmdlets
Updated HCX module cmdlets
As usual we need to wait for API explorer to be updated before we get the exact changes to the api’s but I already grabbed s short list by comparing the methods. Later I will create a more elaborate blog post about the changes if I have an overview. What I do see are some new additions that might be added to the vCheck for Horizon.
Also: even though the updates are for Horizon 7.9 there’s a good chance that a lot of this also works for previous versions, the examples below where done with 7.8.
Datacenter
DesktopHealth
Gateway
GatewayHealth
MessageClient
Monitoring
PersistentDiskQueryService
Privilege
SecondaryCredentials
SessionStatistics
StorageAccelerator
UsageStatistics
Validator
VirtualCenterStatistics
Sadly it’s late so I can only show a couple of examples:
One of the things that annoy me about the Horizon admin interface is the fact that if you give a session the logoff command that this only works if the user is active aka when the desktop is not locked. With the api’s though (and Andrew implemented this in the helpdesk fling) it is possible to force a logoff. Let’s look at the available method’s first.
So we have a logoff and logoffForced. But there are also the logoffsessions and LofoffSessionsForced, I guess those let you logoff multiple sessions. this is what the extensiondata says about them.
So for the singular method’s we need a single id and for the sessions we need an array of ids. At first I will use get-hvglobalsession (yes, this works against sessions in other pod’s in a cloud pod architecture as well!) to get the id’s to show how it works. I have 5 sessions running from my desktop
As you can see one of my users was a but slow in logging off (nested esxi with only a couple vcpu’s for that one) I have also created a script that asks for the user whom you want to logoff and which session you want to logoff in case they have multiple. It’s not the cleanest code that I have written but it works 🙂
$hvserver1=connect-hvserver servername -user user -domain domain -password passwords
$Services1= $hvServer1.ExtensionData
$username= Read-Host "Which user do you want to logoff? (no wildcards needed, part of the name is enough)"
$queryService = New-Object VMware.Hv.QueryServiceService
$userdefn = New-Object VMware.Hv.QueryDefinition
$userdefn.queryEntityType = 'ADUserOrGroupSummaryView'
$userfilter1= New-Object VMware.Hv.QueryFilterContains
$userfilter1.membername='base.name'
$userfilter1.value=$username
$userfilter2= New-Object VMware.Hv.QueryFilterEquals
$userfilter2.membername='base.group'
$userfilter2.value=$False
$userfilter=new-object vmware.hv.QueryFilterAnd
$userfilter.filters=@($userfilter1, $userfilter2)
$userdefn.filter=$userfilter
$users=($queryService.QueryService_Create($Services1, $userdefn)).results
$menu = @{}
for ($i=1;$i -le $users.count; $i++){
Write-Host "$i. $($users[$i-1].base.name)"
$menu.Add($i,($users[$i-1].id))
}
[int]$ans = read-host "Please select the correct user"
$user=$menu.Item($ans)
$GlobalSessionQueryService = new-object VMware.Hv.GlobalSessionQueryServiceService
$sessionfilterspec=new-object vmware.hv.GlobalSessionQueryServiceQuerySpec
$sessionfilterspec.user=$user
$sessions=($GlobalSessionQueryService.GlobalSessionQueryService_QueryWithSpec($services1, $sessionfilterspec)).results
$menu = @{}
for ($i=1;$i -le $sessions.count; $i++){
Write-Host "$i. $($sessions[$i-1].namesdata.basenames.MachineOrRDSServerName)"
$menu.Add($i,($sessions[$i-1].id))
}
[int]$ans = read-host "Please select the correct VDI Desktop"
$session=$menu.Item($ans)
$Services1.Session.Session_Logoffforced($session)
$queryService.QueryService_DeleteAll($services1)
This script forces the logoff for the sessions since I haven’t been able yet to find where the desktop status (locked or not) is visible.
One of my customers asked the question if it is possible to get a quick sessioncount for a script that they can run very often for a correct logging of license usage. While this could easily be done by grabbing all the sessions I thought this could be a slow process. I remembered though that the first release of the vmware.hv.helper module had a function called get-podsessions that only returned a sessioncount. I decided to see what was used for this. By going back in time at github I found that the GlobalSessionQueryService was still used but with the GlobalSessionQueryService_GetCountWithSpec method. It needs the service and a spec of the type VMware.Hv.GlobalSessionQueryServiceCountSpec.
the spec itself can hold one of the many options to get a count for
As you can see there is a globalentitlement property that needs to be set using the id so let’s grab that one first.
As you can see we actually get a count per pod so to get all the counts from all pods from all globalentitlements I have created a script with a couple foreach’s.
The W10_MGMT global entitlement only has a pool in pod1 so even though the pod doesn’t have a pool inside the global entitlement it will still return a sessioncount.
Performance
I also decided to time it but in my small environment it took 3 seconds and 3 of those where for connecting to the connection server. If I removed the connecting part it was 0.7 seconds.
Back at the customer I decided to compare this against dumping all global sessions, this will give some better data since it has a couple more sessions in it (around 3500 at the moment of testing)
The script I used for getting all global sessions is the code that I used for the get-hvglobalsession in the vmware.hv.helper module
so the getcountwithspec method is about 2.5 seconds faster but the data in the globalsession is way more extensive and usable for all kinds of management overviews.
This is the first post in a series of shorts that I will be posting about various methods that you can use with the VMware Horizon API’s. This time it will be about resetting desktops. When looking at the API Explorer you’ll see that there are two ways do do this from the machine service.
So the first is for a single VDI desktop and the latter for multiple.
First we need to get a list of vm’s I will be using the machines in pod1pool02 as victims for this post.
If you have used the VMware.hv.helper the title of this blog post might sound strange since the set-hvmachine already has a way to set maintenance mode. When Ryan Butler asked me the question this week though I didn’t think of that and dived into the api’s immediately. The machines.Machine_EnterMaintenanceMode method looked good to me and than I though of the vmware.hv.helper and noticed that with
Set-HVMachine -Maintenance ENTER_MAINTENANCE_MODE
it was also possible so set maintenance mode. The usage though made me think immediately that this was not actually using a proper api call but the update function. A quick look at the function itself confirmed this. It sets that status of the virtual machine by directly setting the status.
If you are below version 7.5 of Horizon view it’s probably of no use to continue with the rest of this blog post. The api explorer only mentions the relevant functions since 7.5! They have been tried against 7.0.3 and 6.2 and there they don’t work.
So back to the drawing board it was and I needed to look at the API explorer, there are 4 relevant methods for maintenance mode.
As usual there are methods for multiple machines that use an array of id’s (with machines in the name) and methods for single machines id’s (without the machines in the name).
Since I usually use instant clones these days I created a small pool with three linked clones. With get-hvmachine I can show you their names and state.
Okay so we now know how this works but I don’t want to use to vmware.hv.helper module for this at all because I want to be able to use a list of machines or based on part of the name. That can be done using a query. The query entitytype to use is MachineSummaryView and if you use queryfiltercontains it’s also possible to use only a part of the name for a kind of wildcard selection. Combine several of these in with queryfilteror and it gives the opportunity to select them from a list.
I got the question today from Fabian Lenz if it is possible to send messages to end users using the Horizon API. I knew I had seen it somewhere already and here’s a quick explanation.
There are two method’s to do this, one for a single session and the other for a group of sessions. Both fall under the session service.
$services1.session | gm
You can see both the methods called session_sendmessage and session_sendmessages if we look at what’s required for both we see that the difference is a single sessionid or an array of session id’s.
Let’s see what the API explorer says what’s needed.
So the msgtype is a string that can have three values and the message is just a string, let’s test this.
I am lazy and will use get-hvlocalsession for the sessionid.
$session=get-HVlocalsession | select -first 1
I do the -first 1 so it isn’t an array but a single session.
Now let’s send a message.
$services1.session.Session_SendMessage($session.id,"INFO","This is a test message for retouw.nl at 30-10-2018 19:13h")
And the result:
Now let’s do the same for multiple sessions.
$sessions=get-HVlocalsession
$services1.session.Session_SendMessages($sessions.id,"ERROR","This is a test message with multiple recipients for retouw.nl at 30-10-2018 19:25h")
And to show that this also works for global sessions (both where connected to pod2cbr1)
$sessions=get-HVglobalsession
$services2.session.Session_SendMessages($globalsessions.id,"WARNING","This is a test message with multiple global recipients for retouw.nl at 30-10-2018 19:30h")
If you want to filter the sessions on user or machine name you can filter the $globalsessions on $globalsessions.namesdata.basenames
So this is the second post in this series about the Horizon View API basics. While functions logically would be part 2 I have decided on doing queries first since you might need the result for a query before you can use some of the functions. Some if it will seem double from my recent post about pulling event information but not everyone might be looking into that. This post will not have as much gifs as the first post but that’s because only the end results count for this one.
Looking at the API Explorer these are the services that we can actually query:
There are some examples in the API explorer but will show you some different examples with the aduserorgroupsummaryview since that one has a lot of documented filters and I can easily add some extra accounts to show different queries.
The first thing that we always need to do with queries is to declare the queryservice object
If you do a get-method on this object it will show several possible methods to use.
The next thing to do is to create a definition object in which we will declare the things the query looks for.
$defn = New-Object VMware.Hv.QueryDefinition
When getting this object and its get-method it shows the definitions we can set, as you can see all method’s are already visible from just viewing the object so we don’t need to use the get-method anymore.
Now we need to set a QueryEntityType these can be found in the API explorer under the Queryable Entity Types. They have to be used between quotation marks.
$defn.queryentitytype='ADUserOrGroupSummaryView'
Now we’re already set to create some results by putting the query into an object.
As you can see below this will create an object where the results property contains all the data. This Results property has 2 other properties of it’s own that actually contain all the data.
And if we expand the base property it gives us one of the build-in Active Directory groups.
$queryresults.results | select-object -first 1 | select -expandproperty Base
Since this can go several layers deep it is smarter to use the round brackets to get this information. (Select -expandproperty following select – expandproperty is just ugly and takes too long)
This way it’s also easy to count the amount of returned objects. This is very useful if you have a bigger environment and want to take counts of sessions with their status (i.e. Connected, disconnected, error etc)
($queryresults.results).count
Next up is adding a filter, so we only get user accounts but we need to do some maintenance first. If you do too many queries it is possible that you will get some errors about too many filters or something (of course I am not getting them while writing this post) so, it might be needed to remove the old stored queries is possible with the queryservice_deleteall method.
This does not give any feedback on the results so let’s continue with the old query and put a filter on it. First you need to know what kind of filter you need and the options are listed in the API explorer.
The first one I will use is queryfilterequals since I use that the most. I start by defining a filter object consisting of a property with a value.
Now I will show you the results + the fact that you don’t necessarily need to define an object for the results. I have selected the first result to show you that it contains the domain administrator account
It is also possible to combine several filters into one query, while the ad service might not be the most useful for this it can still be used as an example. The thing to do is to first create a couple of filters.
Please be aware that these membernames are case sensitive!
That’s it for the basics of doing queries using the Horizon View API’s. There are some more things that we can do with these like sorting them, but I think you can find that on your own in the API explorer examples.
UPDATE 12-10: The new API explorer page also has been published, it just needs to be added to the main page. Check this link: https://code.vmware.com/apis/445
Update 15-10: I have received an overview from VMware about the other changes:
New API Endpoints:
ConnectionServer_GetTags
GlobalSettings_GetEnvironmentSettings
QueryService_DeleteByIds
Datastore_GetDatastoreRequirements
Datastore_ListDatastoresByDesktopOrFarm
RemoteApplication_EndApplication
There also have been some changes to some objects (MachineBase,AccessGroup etc) to include more properties
Original Article:
Today the latest version of PowerCLI was released with version 11.0.0. When you look at the release notes it’s obvious that some extra things have been added for the Horizon VIew API’s.
PowerCLI has been moving at quite the rapid pace over the last 2 years. In 2018, we’ve been releasing roughly every other month to make sure we get the latest features, performance improvements, and updates available as quickly as possible. Well, it’s been two months and we’re not going to break this trend. Today, we are releasing PowerCLI 11.0.0!
PowerCLI 11.0.0 comes with the following updates:
Added a new Security module
Added new cmdlets for Host Profiles
Added a new cmdlet to interact with NSX-T in VMware Cloud on AWS
Support for vSphere 6.7 Update 1
Support for NSX-T 2.3
Support for Horizon View 7.6
Support for vCloud Director 9.5
Multiplatform support for the Cloud module
Updated the Get-ErrorReport cmdlet
Removed the PCloud module
Removed the HA module
Even though Jake Robinson already gave me a heads up that this version was coming it’s always the question what has been added for Horizon View. According to the API explorer page no new querydefinitions have been added. Like last time I decided to compare the services against the old list and there are two new additions:
CategoryFolder
ResourceSettings
I have tried both against a Horizon 7.5 setup and they failed so these are only exposed from Horizon View 7.6 and up.
The first one called Categoryfolder is linked to the possibility to put rdsh applications into folders.
It currently has only one function:
I have also investigated if there was a way to change things using the helper function but sadly it has no .update api call so that’s a no-go. I currently have no rdsh on my lab so I can do the list but it doesn’t show anything.
The other new service is the .ResourceSettings just like categoryfolder it also only has one function:
For this one I can actually show what it’s used for:
It shows the general settings for forced logoffs.
Sadly this service also doesn’t show a way to change things.
Sadly I have no found no way yet to see what queryservice entity’s have been added so hopefully we will have a new API explorer soon (maybe with release notes this time, pretty please VMware?) that shows us all the new goods.
I have done a lot of deep dives but just like the VMware{Code} session I did at VMworld I think it’s time to go back to the basics on how to work with the Horizon api’s from PowerCLI. First up is connecting to a Connection server and disconnecting. I will be showing various ways to do but the new and secure one is the best for me since that’s also usable when you want to schedule scripts.
The easy way
The easiest wat to connect is by using the connect-hvserver SERVERNAME
connect-hvserver pod1cbr1
This will give you a nice credentials popup.
The Unsecure way
The previous way that I used was by using the -user, -pass and maybe the -domain parameters.
Since one of the latest updates it is also possible to use a credential object. We found this out during the Hackathon @VMworld US that it is possible. It will use the good old credentials function from Powershell like in this post from 2008. First you’ll need to make a file with the encrypted password. Big thanks to Ariel & Edgar 🙂 check this for the vDocumentation script.
There’s a little bit more to it so you can actually use the api’s. First we need to put the session into a variable. I always use a number so it’s easy to separate my various pods.
Privacy & Cookies: This site uses cookies. By continuing to use this website, you agree to their use.
To find out more, including how to control cookies, see here:
Cookie Policy
You must be logged in to post a comment.