Search code examples
powershellautomationvmwarevspherepowercli

Grabbing assigned VM names by entering username in Vmware Horizon (PowerCLI)


I've been working on a PowerShell code to grab VM names from all desktop pools.

I'm using PowerCLI with PowerShell 7 installed.

I have managed to get an output of all the users and their assigned machines. But, I'm having difficulties in optimizing the code in a way that I can input a single user name and it will only show me that user's assigned VM.

Here is the code I've got so far

#Import-Module VMware.VimAutomation.Core
#Import-Module Activedirectory

Connect-VIServer -server servername123 -Force
Connect-HVServer -server server.name.123

$uname = Read-Host -Prompt 'Input the user name you wish to find:' #User-Input

$Global:DefaultHVServers

$query = New-Object "Vmware.Hv.QueryDefinition"
$query.queryEntityType = 'SessionLocalSummaryView'
$qSrv = New-Object "Vmware.Hv.QueryServiceService"


$PCs = ($qSRv.QueryService_Query($global:DefaultHVServers[0].ExtensionData,$query) | 
Select -ExpandProperty Results |
Select -ExpandProperty NamesData |
Select-Object -Property UserName,MachineOrRDSServerName)


$PCs | % {"$($_.UserName.Split("\")[1]) `t`t $($_.MachineOrRDSServerName) "}

In the last line of the code, I am formatting the table to remove unnecessary content.

$PCs | % {"$($_.UserName.Split("\")[1]) `t`t $($_.MachineOrRDSServerName) "}

Can someone help me in grabbing username from console and only displaying the VMs that they are assigned to?

I have tried googling for a solution but couldn't find anything relevant.

Thanks!!

Note: I have declared a variable uname but haven't used it yet. I'm unsure how can I use it in this usecase.


Solution

  • After digging around more in the deepest subreddits, I found a post that solved my question.

    https://www.reddit.com/r/vmware/comments/d547nt/horizon_view_powercli_help/

    Below is the code which utilizes QueryFilterEquals from VMware.Hv.Equals class to grab usernames and their properties.

    I'm skipping the connections portion of the code, it is the same mentioned in the question.

    #Get User Input for UserName
    $UserName = Read-Host -Prompt 'Input the user name you wish to find:'
    
    #Create Horizon Services object
    $HorizonServerServices = $global:DefaultHVServers[0].ExtensionData
    
    #Create Query Definition object with EntityType SessionLocalSummaryView
    $HorizonQuery = New-Object VMware.Hv.QueryDefinition
    $HorizonQuery.QueryEntityType = 'SessionLocalSummaryView'
    
    #Create Query Filter Object
    $QueryFilterEquals = New-Object VMware.Hv.QueryFilterEquals
    $QueryFilterEquals.MemberName = 'namesData.userName'
    $QueryFilterEquals.value = "domain.loc\$UserName"
    
    
    $HorizonQuery.Filter = $QueryFilterEquals
    
    $HorizonQueryService = New-Object VMware.Hv.QueryServiceService
    $SearchResult = $HorizonQueryService.QueryService_Query($HorizonServerServices, $HorizonQuery)
    
    if ($SearchResult.Results)
    {
        $SearchResult.Results.Namesdata
    }
    

    We do not have to delete the query at the end as it doesn't consume any server-side resources. It is a virtual query. Refer to the link given below for detailed info on how QueryService works.

    Refer to: https://vdc-download.vmware.com/vmwb-repository/dcr-public/e2e25628-4ed2-43fc-8bad-54fb86f3bb0f/8e4d2491-c740-4778-ac43-ba8fc0ec8175/doc/queries-landing.html