I am writing a script to automate the creation of a VDI and entitlement. The one issue i am having is how do i assign a VM to an existing pool? I can use add-poolentitlement to entitle the user to a pool and i can use update-userownership to add a user to the VM however i can't find the syntax necessary for adding a newly created VM to an existing pool.
Aren't Update-ManualPool and/or Update-ManualUnmangedPool doing that?
Btw, which Horizon version are we talking about?
And which PowerCLI version are you using?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I am running Horizon 7.0.3 and i installed the version of view powercli that came with that install.
the update-manualpool commandlets do not allow you to add a VM to that pool. Based on the help screen it allows me to change settings about the pool.
The PSSnapin that comes with Horizon 7.* is not the most recent one afaik.
In PowerCLI 6.5.* there is a new module and a HVHelper module, these give you access to the View API.
See Alan's GETTING STARTED WITH POWERCLI 6.5 AND HORIZON VIEW to start.
With access to the API you should be able to access all functionality.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
ok thanks this helps. I am taking a look at it now to see how to modify pools.
Let me know if you get stuck.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
This helped tremendously. I am able to add a machine to the pool and entitle the user to the pool. with the commands below. The one last step is entitling the user to the machine in the pool.
THIS WORKS
add-hvdesktop -pool $vmviewpool -machines $vm -users $username = add machine to pool
New-HVEntitlement -User $username -ResourceName $vmviewPool = add user to pool
THIS DOES NOT WORK
new-hventitlement -resourcetype 'Desktop' -ResourceName 'win7x64entpool' -resource 'vmNameHere'
New-HVEntitlement : Parameter set cannot be resolved using the specified named
parameters.
At line:1 char:1
+ new-hventitlement -resourcetype 'Desktop' -ResourceName
'win7x64entpool ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~
+ CategoryInfo : InvalidArgument: (:) [New-HVEntitlement], Parame
terBindingException
+ FullyQualifiedErrorId : AmbiguousParameterSet,New-HVEntitlement
what am i doing wrong here? When i look at the source of those powershell modules i have the syntax correct. THis is the last step for me. Any help you can provide would be appreciated.
thanks in advance
You can't use Resource and ResourceName together.
They belong to two different parametersets.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Seeing the issue below when i tweak it. I will work through these errors. Seems like specifying the VM name isn't good i need to query the VM another way. I tried get-hvmachine didnt work so i am looking into other methods. Making progress though
PowerCLI C:\Users\a-jaldrich\Desktop> new-hventitlement -User "username" -Resource 'VMName-01' -resourcetype 'Desktop'
new-hventitlement : In pipeline didn't received object(s) of expected type
DesktopSummaryView/DesktopInfo
At line:1 char:1
+ new-hventitlement -User "username" -Resource 'VMName-01'
-resourcetype ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorExceptio
n,New-HVEntitlement
Create a module with the following functions, for example you can name it addvmtopool.psm1:
<# .SYNOPSIS Get a View Pool object for a manual VC-managed pool. .DESCRIPTION Returns a manual Pool object or throws an exception, use for input validation .PARAMETER pool The pool's ID string to use, alternatively can accept an existing Pool object to validate it's a manual VC-managed type. #>
function Get-ManualPool
{
param ($pool = $(Read-Host -prompt "Pool ID"))
if ($pool.GetType().Name -eq "String") {
# treat a string as a pool_id, get Pool object
$pool = Get-Pool -pool_id $pool
if ($pool -eq $null) {
Throw "Pool not found"
}
}
if ($pool.GetType().Name -ne "Pool") {
Throw "Pool is of unknown type: " + $pool.GetType()
}
if ($pool.deliveryModel -ne "Manual") {
Throw "Pool must be manual"
}
if ($pool.vcServerName -eq $null) {
Throw "Pool must be VC managed"
}
return $pool
}
<# .SYNOPSIS Get a View DesktopVM object for use in a manual VC-managed pool. .DESCRIPTION Return a DesktopVM instance for the specified VM .PARAMETER vm The VM's ID string to use, alternatively can accept an existing DesktopVM object to validate it's of the correct type. .PARAMETER vc_id The GUID representing the vCenter instance to filter by. .PARAMETER in_pool Whether the VM is expected to be in an existing pool or not. #>
function Get-ManualPoolVm
{
param ( $vm = $(Read-Host -prompt "VM name"),
[String] $vc_id = $(Read-Host -prompt "VC guid"),
[Boolean] $in_pool = $false)
# need VC guid only
if ($vc_id.GetType().Name -eq "ViewVC") {
$vc_id = $vc_id.vc_id
}
# make sure we have a valid VM
if ($vm.GetType().Name -eq "String") {
# treat string as VM name, we can filter by VC matching $pool
$vm = Get-DesktopVM -vc_id $vc_id -name $vm
if ($vm -eq $null) {
Throw "VM not found"
}
}
if ($vm.GetType().Name -ne "DesktopVM") {
Throw "VM is of unknown type: " + $vm.GetType()
}
if ($vm.isInPool -ne $in_pool) {
Throw "VM has invalid isInPool value"
}
if ($vm.vc_id -ne $vc_id) {
Throw "VM is not in the correct vCenter instance"
}
return $vm
}
<# .SYNOPSIS Get the associated ADSI object for VM/pool. .DESCRIPTION Return an ADSI object for the specified DN on localhost. .PARAMETER pool Either a Pool object or its ID. .PARAMETER vm Either a DesktopVM object or its ID. .PARAMETER dn The DN string. Alternatively, can pass in a Pool or DesktopVM object. #>
function Get-ViewAdsiObj
{
param ([String]$dn = $null,
$pool = $null,
$vm = $null)
# allow overloaded param as pool or vm
if ($pool -ne $null) {
if ($pool.GetType().Name -eq "Pool") {
$pool = $pool.pool_id
}
$dn = ("cn=" + $pool + ",ou=server groups,dc=vdi,dc=vmware,dc=int")
}
if ($vm -ne $null) {
if ($vm.GetType().Name -eq "DesktopVM") {
$vm = $vm.machine_id
}
$dn = ("cn=" + $vm + ",ou=servers,dc=vdi,dc=vmware,dc=int")
}
if ($dn -eq $null) {
Throw "Need to specify a DN"
}
# return ADSI object
return [ADSI]("LDAP://localhost:389/" + $dn)
}
<# .SYNOPSIS Add a new VM to an existing manual pool .DESCRIPTION Adds the specified DesktopVM object and adds it to the existing manual pool. This is done by first creating a new temporary pool with the VM in, moving the VM to the existing pool, and finally deleting the temporary pool. .PARAMETER pool Either a Pool object or its ID. .PARAMETER vm Either an existing DesktopVM object or its ID. #>
function Add-ManualPoolVm
{
param ($pool = $(Read-Host -prompt "Pool ID"),
$vm = $(Read-Host -prompt "VM name"))
$pool = Get-ManualPool $pool
$vm = Get-ManualPoolVm -vm $vm -vc_id $pool.vc_id -in_pool $false
# do the add
$guid = "TMPPOOLADD-" + [Guid]::NewGuid()
$tmppool = Add-ManualPool -pool_id $guid -vc_id $vm.vc_id -vm_id_list $vm.id
try {
# need an updated entry
$vm = Get-ManualPoolVm -vm $vm.name -vc_id $vm.vc_id -in_pool $true
$vm = Move-ManualPoolVm -vm $vm -pool $pool
} finally {
Remove-Pool -pool_id $guid -DeleteFromDisk $false
}
return $vm
}
<# .SYNOPSIS Move a VM from one manual pool to another .DESCRIPTION Removes the specified DesktopVM from its existing manual pool and adds it to the specified one. .PARAMETER pool Either a Pool object or its ID. .PARAMETER vm Either an existing DesktopVM object or its ID. #>
function Move-ManualPoolVm
{
param ($pool = $(Read-Host -prompt "Pool ID"),
$vm = $(Read-Host -prompt "VM name"))
$pool = Get-ManualPool $pool
$vm = Get-ManualPoolVm -vm $vm -vc_id $pool.vc_id -in_pool $true
$oldPool = Get-ManualPool $vm.pool_id
$vmAdam = Get-ViewAdsiObj -vm $vm
$oldPoolAdam = Get-ViewAdsiObj -pool $oldPool
$newPoolAdam = Get-ViewAdsiObj -pool $pool
$vmDn = [String]($vmAdam.distinguishedName)
# remove VM from the old pool
$oldPoolAdam."pae-MemberDn".Remove($vmDn)
$oldPoolAdam.SetInfo()
# add VM to the new pool
$newPoolAdam."pae-MemberDn".Add($vmDn)
$newPoolAdam.SetInfo()
$vm.pool_id = $pool.pool_id
return $vm
}
<# .SYNOPSIS Removes a DesktopVM from a manual pool .DESCRIPTION Removes the DesktopVM from the specified pool, by removing its entry from ADAM and then clearing its View configuration information from the machine.id field. The pool parameter is used as a safety check. .PARAMETER pool Either a Pool object or its ID. .PARAMETER vm Either an existing DesktopVM object or its ID. .PARAMETER clearMid Clean the machine.id field for the VM, this is needed if you are not planning to delete it, but does require the vSphere PowerCLI cmdlets to be loaded. #>
function Remove-ManualPoolVm
{
param ($pool = $(Read-Host -prompt "Pool ID"),
$vm = $(Read-Host -prompt "VM name"),
[Boolean]$clearMid = $true)
$pool = Get-ManualPool $pool
$vm = Get-ManualPoolVm -vm $vm -vc_id $pool.vc_id -in_pool $true
if ($pool.pool_id -ne $vm.pool_id) {
Throw "VM is not in the correct pool"
}
# remove from ADAM
$serverOu = Get-ViewAdsiObj -dn "ou=servers,dc=vdi,dc=vmware,dc=int"
$serverOu.Delete("pae-VM", "cn=" + $vm.machine_id)
$serverOu.SetInfo()
# set machine.id field
if ($clearMid -eq $true) {
Clear-ViewMachineIdConfig -vm $vm.name
}
}
Then use to add a VM to existing pool:
Invoke-Command -ScriptBlock {Add-ManualPoolVm -pool "MyExistingPool" -vm "$using:vmname"} -Session $session
forgot to mention that i'm running Horizon 6.2.0
Thanks i will look how to adapt this for horizon 7.
Here is the solution:
get-hvmachine -machinename $yourcomputer | set-hvmachine -key base.user -Value $userObjId
$userObjId has to be of a specific VMware type - see link above or check the module VMware.Hv.Helper
you could do something like this:
function Get-HVMyUserObject
{
param(
$HvServer,
[string]$username # in form of just the basename without domain
)
$hvqdef = New-Object VMware.Hv.QueryDefinition
$hvqdef.QueryEntityType = 'ADUserOrGroupSummaryView'
[VMware.Hv.QueryFilter[]]$filters = $null
$userNameFilter = New-Object VMware.Hv.QueryFilterEquals -Property @{'memberName' = 'base.name'; 'value' = $username }
$hvqdef.Filter = $userNameFilter
$queryservice_helper = New-Object VMware.Hv.QueryServiceService
$result =$queryservice_helper.QueryService_Query($hvserver.ExtensionData,$hvqdef)
return $result.Results
}
$myUserObj = Get-HVMyUserObject -hvserver $myHvServer -username $myBaseUserName
get-hvmachine -machinename $yourComputerName | set-hvmachine -key base.user -Value $myUserObj.Id