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:

get-hvmachine -machinename MACHINENAME

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)

$services1.desktop.Desktop_RemoveMachineFromManualDesktop((get-hvpool -poolname POOLNAME).id, (get-hvmachine -machinename MACHINENAME).id)

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

add-hvdesktop -poolname POOLNAME -machines labw701

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)

$username="USERNAME"
$queryService = New-Object VMware.Hv.QueryServiceService
$defn = New-Object VMware.Hv.QueryDefinition
$defn.queryEntityType = 'ADUserOrGroupSummaryView'
$defn.filter = New-Object VMware.Hv.QueryFilterEquals -property @{'memberName'='base.name'; 'value' = $userName}
try     {
        $userid=($queryService.queryservice_create($Services1, $defn)).results[0].id
        }
catch   { 
        throw "Can't find $Username, exiting" 
        }

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.

get-hvmachine -machinename MACHINENAME | set-hvmachine -key base.user -Value $userid

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.

$resultuserid=(get-hvmachine -machinename MACHINENAME).base.user
($services1.AdUserOrGroup.AduserOrGroup_Get($resultuserid)).base

This is the script you can use as a base:

$username="username"
$poolname="Poolname"
$machinename="machinename"
$connectionserver="connectionservername"

$hvserver1=connect-hvserver $connectionserver
$Services1= $hvServer1.ExtensionData

$queryService = New-Object VMware.Hv.QueryServiceService
$defn = New-Object VMware.Hv.QueryDefinition
$defn.queryEntityType = 'ADUserOrGroupSummaryView'
$defn.filter = New-Object VMware.Hv.QueryFilterEquals -property @{'memberName'='base.name'; 'value' = $userName}
try     {
        $userid=($queryService.queryservice_create($Services1, $defn)).results[0].id
        }
catch   { 
        throw "Can't find $Username, exiting" 
        }

add-hvdesktop -poolname $poolname -machines $machinename

start-sleep -s 10

get-hvmachine -machinename $machinename | set-hvmachine -key base.user -Value $userid

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

 

Bookmark the permalink.

Comments are closed.