Managing Pods in a Horizon View Cloud Pod Environment using PowerCLI & Api’s

After Pod Federations and Sites it is time to manage the actual pods. Let’s take a look at what we can do.

Looks like a short post to me since there’s onl Get, List and Update

Pod_Get

Just like with site’s the get can be used in conjunction with a podid that might be gotten from somewhere else

This selects the first podid listed when pulling all the pods from all sites and gets the information about that pod. We’ll see the same information when doing a list but just with all pod’s listed.

Pod_List

Those endpoints are the connection servers in the pod. Let’s take a short detour and get the listing for one of those (the podendpoint service only has list and get so you will not see them separately anyway).

It might look lazy to use the select -first one and yes it is a bit but doing  a foreach to explain things also doesn’t really work in my opinion.

Pod_Update

Standard by now, first we need to connect to the podservice.

Under $podhelper we can already see how to set things.

Let’s update  the easy things.

As a result we have updated the name and description of the pod. The other thing we can do is assign the pod to another site. Thankfully I already have two of those created.

Both the lists aren’t required but I added them to show that the pods are spread over both pods now.

 

Creating and managing Sites in a Horizon View Cloud Pod Environment using PowerCLI & Api’s

Intro

Like I said in my previous post about Pod Federations this is a separate post that will show how to handle Sites within a Pod Federation. There are only a couple of API calls that do not include assigning a pod to a site. This is done trough the podservice which I will post about in a next blog post.

Let’s take a look at the site service to see what it actually has in api call’s

So we have Site_create, Site_delete, site_get, site_list and site_update. To Make it myself easy I will use the order of List, create, get, update and delete.

Site_list

With site_list a list of all available site’s will be created, currently I have only one so let’s show that one.

Note a lot of information is shown so let’s take a look at the contents of base and pods.

so again not a lot of information since it only contains a name, description and the pod id’s of the member pods.

Site_Create

Since we already saw in the methods under the siteservice that the create needs a bit more information then just a name let’s take a look again at what is required.

An object is needed of the type vmware.hv.sitebase, we will need to take a look in the API explorer to see what this object should contain. Under Site_create we can click on sitebase.

The sitebase object has 2 properties of which only DisplayName is required. I have tried various ways to keep the description empty but haven’t succeeded so far and with it it the create also doesn’t work so how optional is it?

Let’s create the sitebase object

The $sitebase is not required but shows what the object contains. Now we have enough to create the new site.

Site_Get

In the overview we have seen that a site_get needs a bit more information.

We already know how to get this site id by using site_list, normally you would only use the site_get with an id received from another service like the pod service. For the example I will use the demo site I create in the site_create part of this post.

First I will need to get the siteid

And now we need to apply that to the site_get

Site_Update

As said before for an update method it is better to use the helper service for that service.

now what method’s do we see?

To see the difference between the sitebasehelper and siteinfohelper I will create both objects.

Now let’s compare them.

 

This is again one of those wtf moments, they both do exactly the same! I will use the sitebasehelper for now will update both the Displayname and description. For this I will need to use the getbasehelper 1 step deeper

and apply the update, since neither will generate a response I won’t put any screenshots in.

Now let’s see the result for a site_get for this site now

Site_Delete

We can take a look at it but to delete a site we only need the siteid so let’s remove that site we gave an update.

again no visual feedback but if we do a sitelist there’s only one left.

 

 

Initiating and managing the Podfederation in a Horizon Cloud Pod Architecture using PowerCLI & API’s

One of the new cmdlets for the vmware.hv.helper that I am currently working on is initiating the Cloud Pod Architecture (CPA) and more actions related to this. This blog post will show the basics about initiating, and joining a CPA using the API’s. Doing things with site’s within the CPA will be covered in a later blogpost.

If we look at the services available in the Horizon API’s you’ll see that podfederation is one of them, let’s take a look at that and what method’s are available.

So we can Eject, Get, Initialize, Join, Unintialize, Unjoin and update a podfederation. If we look at the brackets behind the methods than (un)initializing and unjoin don’t need any extra info so let’s get ahead and initialize the podfederation. To show you there’s nothing there yet I made a screenshot of the admin interface.

Initialize the podfederation

Now to initiate the podfederation

And if you are quick enough in switching to the admin interface will also still show it initializing

Get information about the federation

With podfederation_get() we can grab the configuration information.

Not a lot of information but there isn’t a lot more anyway in the podfederation itself.

Join a federation

I have another pod that I want to join to this federation since we’ve already seen that this needs some more input let’s check what it exactly needs.

So we need a remotepod address, presumable one of the connection servers in that pod will be enough, a username where domain\username will do just like in the admin console and a password of the type vmware.hv.securestring. The last one was new for me but thankfully it was described in one of the examples in the api explorer (https://code.vmware.com/apis/75/view and click on Data Object Types).

With this it’s easy to add the local pod to the podfederation

And again if you are fast enough this is also visible in the admin console

And now a get will also show that it has been enabled

Unjoining a Podfederation

If you are braking down a pod because of whatever reason the best way to do this is to unjoin the pod from the federation. As we saw before there’s no extra information need so you just need to connect to a connection server in that pod and do an unjoin.

this is really fast so over several tries I did not succeed in making a screenshot of the admin console.

Ejecting a pod

This is the only podfederation function not available through the admin console as far as I could see. Ejecting a pod for is for me a last option if a datacenter burned down, everything is gone and you want to get rid of the pod. I did it in my lab against an alive pod and had to uninitialize the (now unlinked) podfederation from that pod to be able to rejoin it to the correct pod. This method also requires some input so let’s see what that is.

So we need the podid of the pod to eject, this information can be get trough the pod service

I want to eject the pod from pod2cbr1

and with $pod I can check if I have the correct one

So let’s serve the eviction notice to the pod.

No feedback, nothing but if we check the pod list it’s gone.

I will show how to remove the remnants in the uninitialize chapter.

Updating a Pod Federation

This one sounds bigger then it is since there’s only one thing that we can update in a federation. To do this it is better to use the helper service then to use the podfederation_update method since that can get complicated very fast sometimes. To use the helper service we will need to create some variables first

and when we do a get method on it

After some trial and error I know we need to getdatahelper method to continue

This only show the updates that are currently in the queue to be applied with a get method it’s possible to see what can be set.

What we need to look for is a set so the only options here are setdisplayname that needs a string value and setupdates that needs a load of information and that probably might also be a way to do it but I will use the setdisplayname.

This will give no feedback and nothing will be changed yet, what needs to be done is to apply this update in the helper service to the service.

and if you now do a get on the podfederation it will show the changed name.

Uninitializing a Podfederation

To show the pod uninitialization step I will use the pod that I have ejected from the podfederation pod2cbr1. It is clear that it is a bit wonky if we look at the pod list from that connection server.

So it knows about the pod federation but doesn’t see itself in it anymore.

This is again a fast one so I couldn’t get it visible in the admin console but when checking the data from a get it shows it has been disabled.

Looking from the other pod it still shows the Podfederation as enabled.

No github scripts this time since I will be adding this functionality into the vmware.hv.helper module.

New vmware.hv.helper cmdlets (also looking for ideas!)

It’s already a couple of weeks ago that the pull request was merged but I managed to build a couple of new functions for the vmware.hv.helper module. Besides these I am also always looking for new functions to add and since I keep forgetting them I create a project on my own fork of the PowerCLI-Example-Scripts. That can be found here: https://github.com/Magneet/PowerCLI-Example-Scripts/projects/1 so if you have any requests or good ideas for functions please send them my way or add them yourself off course 🙂

This was recently done after my pr’s or is still open to be merged:

New functions

  • reset-hvmachine
    • Resets machines
  • get-hvlocalsession
    • Gets all sessions for the local pod
  • get-hvglobalsession
    • Gets all global sessions + the sessions directly to the local pod

Changed functions

  • get-hventitlement
    • had some issues with groups
  • add-hvdesktop & add-hvrdsserver
    • removed the displaying of the vcentervm id that was added to the pool
      • PR done, not yet merged!

Removed Functions

  • get-hvpodsession
    • this only got a sessioncount so hardly any usefull data

Multi vlan Network for Horizon View using PowerCLI & API’s

One of the things I wanted to do for a while is to write an API version on how to use multiple dvSwitch portgroups with Horizon View linked clones. With instant clones there’s a gui way to select multiple portgroups but for instant clones the only was to do this was to use the View PowerCLI. This gets installed with the connection server and can only be used from there. What you do is create a file, edit and apply it. Johan has described this process very well on his blog. I decided there had to be a way to do this as well with ‘regular’ PowerCLI & the api’s.

The api explorer shows a property named networklabel for both desktop pools and rds farms. This entry showed me what data I needed to configure. I spent most of my time in gathering all the data for this. As you can see in the script I had to dig rather deep to get all information like hostorclusterid and snapshotid. This information then needs to be put into an object called nics.

The script I made is a working prove of concept and doesn’t contain logic about what portgroups to apply. It just grabs all portgroups that comply with a simple filter. It then grabs the id’s for those and configures them to use for the pool. The script grabs information using the snapshotid but in my testing it’s 100% safe to change snapshots or golden images after that, is just uses that information to know where to configure things.

Something I found during testing is that the maximum amount of labels is respected and spread over all port groups as long as there are labels available. If the system runs out of labels it will continue using only the last configured label! I have tested this on View 6.2 and 7.3.2 with vSphere 6.5 on both methods of configuring the portgroups.

This is the script, it asks for some required information at first. This way you don’t have to put a password in plain text in the script. You can see I have the maxlabeltype and enabled properties pre-configured as LIMITED and $true. If the maxlabeltype is UNLIMITED the composer would stop using any other labels configured after that one and if enabled would be $false that label wouldn’t be used at all..

I used a lot of variables and arrays with the names as they are pulled from the data, that explains their long names. Afterwards it doesn’t give any feedback. For this I created a separate script so you can separately check what is configured before or after you change the configuration:

And the result:

In the end the script looks and is way more complex than the ‘old’ way to assign multiple vlans. On the other hand it is way more flexible to use in any scripting you are already using for the automation of your Horizon environment.

As always both scripts can be found on Github here and here.

Finding Horizon View local entitlements using PowerCLI

Intro

In a previous post i mentioned that finding the entitlements for a user from the Horizon side of things can be a bit of a hassle. If only active directory groups are used its dead easy: just use the Active directory commands for those groups. If the groups are used for multiple pools and if you have assigned desktops things get a bit more complicated. For now I will only concentrate on the local pod without global entitlements.

getting that info

To get started the vmware.hv.helper module has the get-hventitlement command. As almost always a very useful one but it has some flaws. First it requires full domainname\username or username@fulldomainname.

For example

or

Both work but

gives this message: Get-HVEntitlement: No entitlements found with given search parameters.

At least

If you add the -type group to this command you get all group entitlements

gives an error message that the -user argument does not match the “^.+?[@\\].+?$” pattern. With this last one you at least get an error so you know where to look but not displaying any entitlements is an issue for me.

So, back to the results of these commands, I have assigned the user user1 the following rights

  • Pool04 directly and by using a group
  • directly on a single desktop in pool04.
  • Pool01 only by group.
  • Paint rds app by group
  • Calculator rds app direct
  • Wordpad rds app by both group & directly

When using the get-hventitlement without anything else it doesn’t seem to show a lot of usable things

If you put this between brackets followed by a period and one of the properties a bit more info is shown.

Some information about the user, not very usable the session data property gives some information about current sessions (none at the moment)

With the localdata property it looks like we hit the motherload jackpot thingy

Very good, a lot of id’s so what can we do with those? For now I will put this into $entitledids.

I read something about get-hvinternalname when checking out the module, sounds usable.

Ah, so this needs an entityid as input, a machine is an entity so let’s try it. This might need a foreach though because the output gave machines and not machine.

Damn, that’s not usable, let’s double-check with the other id types

The ones we need are readable, couple of them not but I don’t those will be missed.

The missing machine name is actually easy to solve by doing an api call:

Conclusion

Because this is rather easy to use and since I didn’t have a direct use case for that I decided not to create a complete script. With get-hventitlement, get-hvinternalname and maybe an api call here or there it’s very easy to pull the information about which account or groups have what rights. To see if a user belongs to a group can easily be done with any of the multitude of scripts for that here’s a good example of those.

 

Adding manual desktops in Horizon View and assigning them using Powercli

A while ago I received a question from Geoffrey O’Brien if I knew how to add a desktop and assign it using PowerCLI. I started building this using the api’s and after a lot of hours, cussing, swearing running into weird problems I actually got it working. When I was busy writing that blog post and wanting to add this to the vmware.hv.helper module I found out that both functions had already been added back in July! I just ignored, or better, forgot about the module for a while because at first it lacked a lot of options.

Key ingredients to do this are add-hvdesktop and set-hvmachine commands. For this post I will assume that the user is already entitled to the pool. This is something that can be checked but because of some ‘things’ it will be a separate post. Please be aware that if you combine these commands in a single script that there needs to be some time for the connectionserver to actually add the desktop.

First check if the system isn’t already registered with this this pod:

If the desktop is already added somewhere and you know the pool it can be removed with the api (issue logged to create remove-hvmachine here)

Since the desktop can’t be found yet it can be added by:

Did you notice the extra S in the -machines part in the command? Multiple machines can be added by separating them with a comma.

To assign the user to the machine things get a it more complicated. We need to set an advanced option for that with set-hvmachine. Why an advanced option? It seems like assigning a single machine isn’t considered an entitlement! The module has no option to grab the horizon userid for you so we need to use the api’s for that (request to add it has been made here)

the username has to be exact samaccountname from your active directory otherwise it will not be able to find the user.

so now we do have the userid the base.user needs to be updated.

before:

the command:

After:

And since the user has been assigned something now it has it’s own userorgroupid as you can see and that can again be check with the api’s. First put the userorgroupid into a variable and then use that against the aduserorgroup service.

This is the script you can use as a base:

As always the most up to date version of the script can be found on Github.