Sep 20 2012

Setting VMware View Desktop State Remotely

Automation has been always the best friend of good System Administrators. Automating repetitive tasks is a key enabler in most IT environments. However, VMware View has some known limitations when talking about automation and remote management.

Besides the Graphical User Interface, local PowerCLI is the only supported management methodology. I say local PowerCLI because none of the VMware View PowerCLI cmdlets allow remote management today. I have previously demonstrated how to use VMware.View.Broker PSSnap-In to configure WinRM sessions and execute remote View PowerCLI (here). It is possible to remotely execute PowerCLI cmdlets using New-PSSession as I demonstrated in my previous post and in the example below.

The PowerShell function below will change the state of a View desktop via ADAM/LDAP database. If pae-VmState is set to READY the VM is accessible, if set to ERROR the VM is not accessible, if set to MAINTENANCE the VM goes into maintenance mode, and if set to DELETING the VM will be deleted.

pae-VmState = “READY”
pae-VmState = “ERROR”
pae-VmState = “MAINTENANCE”
pae-VmState = “DELETING”

The function uses the ADSI adapter to receive an object representation of an Active Directory object and set the new VM state in the ADAM database. This method does not require Remote PowerShell. However to update the ADAM object you will need to find the $_.machine_id via Get-DesktopVM, and this cmdlet will require the remote PowerShell session.


Function ViewVM-SetState {
    Param (
        [string]$vm,                    #VM name
        [string]$state,                    #State to set the VM to
        [string]$ViewIPAddress,            #Connection Server IP Address
        $credential                        #Connection Server Credential

    $ldapBaseURL = 'LDAP://'+$ViewIPAddress + ':389/'
    $script = [scriptblock]::Create("(Get-DesktopVM -Name $vm).machine_id")
    $session = New-PSSession -ComputerName $ViewIPAddress -Credential $credential

    $Machine_Id = Invoke-Command -Session $session -ScriptBlock $script

    $objMachine_Id = [ADSI]($ldapBaseURL + "cn=" + $Machine_Id + ",ou=Servers,dc=vdi,dc=vmware,dc=int")
    $objMachine_Id.PSBase.UserName = "administrator"
    $objMachine_Id.PSBase.Password = "password"

    switch ($state) {
        "MAINTENANCE" { 
            $objMachine_Id.put("pae-vmstate", "MAINTENANCE")
        "READY" {
            $objMachine_Id.put("pae-vmstate", "READY")
        "DELETING" {
            $objMachine_Id.put("pae-vmstate", "DELETING")
        "ERROR" {
            $objMachine_Id.put("pae-vmstate", "ERROR")
        default {

    Return ""


This article was first published by Andre Leibovici (@andreleibovici) at myvirtualcloud.net.




Skip to comment form

  1. Mike Gibson

    This information is fantastic. Programmatically placing a VM into Maintenance mode was the last step I required in automating my fornesic data aquisition process in my View environment. I couldn’t believe they didn’t have a cmdlet for this already.

  2. Andre Leibovici

    Mike, I am glad it has helped you.

  3. Nathan Manzi

    I’ve modified this function so that it works when run on a View Connection Server directly, if people don’t want to do the work to get remote View PowerCLI going. Tested against View 5.2. https://gist.github.com/nmanzi/6198708

  4. Andre Leibovici

    Nathan, good job and thanks for sharing with us.


  5. Kurt

    I was just looking into this and came across your article. Nice approach. As an alternative to doing a remote powercli command to look up the machine id, I use a directoryEntry object and set a filter on the pae-DisplayName property. For example:

    $vmName = “DESKTOP23”
    $vdiinfo = new-object DirectoryServices.DirectoryEntry( ($ldapServer + “OU=Servers,DC=vdi,DC=vmware,DC=int”), ($netCred.Domain +”\” + $netCred.Username), $netCred.password)
    $searcher = New-Object System.DirectoryServices.DirectorySearcher($vdiinfo)
    searcher.Filter = “(pae-DisplayName=$vmName)”
    $desktops = $searcher.FindAll()

  6. Andre Leibovici

    Kurt, thanks for sharing.


  7. Craig

    Hi, great post. We are looking to use this to automate putting all virtual desktops on a given ESXi host into maintenance mode.

    Could you please advise how this could be done as the GUI only allows one desktop at a time.


  8. Blake

    Andre, I am trying to write a script to monitor my pools and make sure that I am not running out of available VM’s (watching available only, not provisioned or used), but I can’t find the variable that contains status. Any thoughts?

  9. Andre Leibovici

    @Blake, I am not sure you need that. Horizon View has an option to always keep a certain number of desktops available, so it will create desktops as needed.

  10. Andre Leibovici

    @Craig, you are right, but will be easier to automated that via PowerShell scripts.

  11. Blake

    Sometimes I run into an issue where I have machines provisioned and View should power them on as available machines are used to keep that minimum number, but it just doesn’t. I have multiple environments that I monitor so I am trying to not have to keep track of each of them manually.

  12. Jason Mathew


    In the script above if I wanted to set a number of VM’s in maintenance mode where would I put that? What I am trying to do is when send a Refresh command to a number of VM’s after I refresh I want to put them in Maintenance mode so during that time my 3rd party system and install apps, setup printers, etc. When that is complete I want to set those same machines to Available status. Any ideas?


Leave a Reply