Advanced General

Joining ESXi hosts to a domain and granting permissions with PowerCLI

Recently I was asked by an administrator to help him automate the process of joining ESXi Hosts or as PowerCLI refers to them “VMhosts” to a domain and granting permissions for a domain user with PowerCLI.

In this post I am going to show you how this can be done with a few lines of code and also share my lessons learned throughout this process. Let’s assume that you have list of VMhost IP addresses and all VMhosts have the same local administrator credentials, you want to join them to a domain and grant permissions for a domain user or group account assigning it a specific role. In the script I assume the role exists on the VMHost but later I will show you how to create a custom role.

The Set-VMHostAuthentication cmdlet is used for joining a VMhost to a domain. You should have in mind that the full domain name must be specified on the Domain parameter of the cmdlet.

Get-VMHostAuthentication -VMHost <VMHost>| Set-VMHostAuthentication -Domain <domain fullname> -User <domain user name for authentication> -Password <password for authentication> -JoinDomain -Confirm:$false

The New-VIPermssion cmdlet is used for creating permissions for a specified user. The user is obtained with the Get-VIAccount cmdlet which has the ability to retrieve Domain user or group accounts when the VMHost is joined to a domain. In contrast to Set-VMHostAuthentication the Domain parameter of Get-VIAccount expects the domain alias instead of domain full name.

You should also be aware that if you don’t specify an Id filter to the Get-VIAccount cmdlet it returns the maximum 5000 results and for domains with many accounts this could be a constraint. So it is recommended to use Id filter of the cmdlet itself instead of applying filtering over its results.

To obtain domain user accounts use –User switch.

Get-VIAccount -Domain <domain alias> -User -Id <user name filter>

To obtain domain group accounts use –Group switch.

Get-VIAccount -Domain <domain alias> -Group -Id <group name filter>

To grant permissions you should specify account to Principal parameter returned by the Get-VIAccount cmdlet, role which can be obtained by Get-VIRole or specified by name and entity which in our case will be the VM host.

New-VIPermission -Principal <VIAccount> -Role <VIRole> -Entity <VMHost>

Here is the entire script with a lot of input parameters needed by the used cmdlets in the script but the script itself is not complex:

param (

   [Parameter(Mandatory=$true, HelpMessage=“List of VM host IPs”)]





   [Parameter(Mandatory=$true, HelpMessage=“VM Host User Name”)]





   [Parameter(Mandatory=$true, HelpMessage=“VM Host Password”)]





   [Parameter(Mandatory=$true,HelpMessage=“Domain full name, required for joining hosts.”)]





   [Parameter(Mandatory=$true,HelpMessage=“Domain alias, required for retrieving domain accounts.”)]





   [Parameter(Mandatory=$true, HelpMessage=“User name for domain authentication”)]





   [Parameter(Mandatory=$true, HelpMessage=“Password for domain authentication”)]





   [Parameter(Mandatory=$true, HelpMessage=“Domain user name for which permissions will be granted”)]





   [Parameter(Mandatory=$true, HelpMessage=“The name of the role you will assign to the user”)]







foreach ($vmHostIPin$vmHostIPs) {

    # Establish connection to a VMHost

    $vmHostConnection= Connect-VIServer-Server $vmHostIP -User $vmHostUserName -Password $vmHostPassword

      try {

            # Get VMHost instance

            $vmHost= Get-VMHost -Server $vmHostConnection


            # Join the VMHost to a domain

            Get-VMHostAuthentication -VMHost $vmHost | Set-VMHostAuthentication -Domain $domainlFullName -User $domainUser -Password $domainPassword -JoinDomain -Confirm:$false


            # Get a domain account

            $viAccount= Get-VIAccount -Domain $domainAlias -User -Id $userNameToGrantPermissions        

            if (-not $viAccount) {

                  throw “VIAccount with Id ‘$userNameToGrantPermissions’ not found in domain ‘$domainAlias'”



            # Get role to assign

            $viRole= Get-VIRole -Name $roleName

            if (-not $viRole) {

                  throw “VIRole with name ‘ $viRole’ not found.”



            # Add permissions on VMHost

            New-VIPermission -Principal $viAccount -Role $viRole -Entity $vmHost         

      } catch {

            Write-Error (“The following error has occurred for VMHost ‘$vmHost’: rn”+$_)

      } finally {

            Disconnect-VIServer $vmHostConnection -Confirm:$false




As you can see the script opens a connection to each VMhost, joins it to the domain and creates permissions for a specific domain account. It relies on the existing role on the VMHost, but it can be easily modified to create a custom role and assign it to the obtained user.

To create a new custom role the New-VIRole cmdlet needs to be used specifying a name and list of privileges on its input. Here is an example:

New-VIRole -Name MyCustomRole -Privilege ‘Anonymous’, ‘View’, ‘Read’, ‘Power On’, ‘Power Off’

The script is calling the Get-VIAccount with a –User switch parameter which filters on domain user accounts. In order to retrieve a domain group account the –Group switch parameter should be used.

So the script looks pretty simple and straightforward but running it I’ve experienced the following problem. Sometimes Get-VIAccount failed to retrieve the domain user immediately after joining the VMhost to the domain and I received the following error “Error accessing directory: Can’t bind to LDAP server for domain: <DOMAIN>”.

It seems that synchronization with active directory needs some time after a host is joined to the domain and the problem is not 100% reproducible. So I solved it with a simple retry-wait mechanism on retrieving domain users.

# Get a domain account


$retryCount= 5

while ((-not$viAccount) -and ($retryCount-ge 0)) {

      try {

            $viAccount= Get-VIAccount-Domain$domainAlias-User-Id$userNameToGrantPermissions

      } catch {

            Write-Error “Getting VIAccount with Id ‘$userNameToGrantPermissions’ failed with the following error: rn $_”

            Write-Host “Next attempt in 5 seconds”

            Start-Sleep -Seconds 5





In conclusion here are the lessons learned from this task:

  1. Get-VIAccount requires to specify the domain alias to Domain parameter
  2. Get-VIAccount limits the results to 5000
  3. Sometimes Get-VIAccount fails to obtain domain users immediately after a VMhost is joined to a domain.

imageThis post was created by Dimitar Milov…

Dimitar joined VMware and PowerCLI team in the beginning of 2011. He is member of the quality engineering part of the team and his main role is the functional verification of the vSphere, vCloud and License PowerCLI components.

As all members of the team he is working to deliver a good and valuable product. He is also working to improve all processes and tools involved in product development and validation.


11 comments have been added so far

  1. Very useful post Dimitar !
    This question pops up quite regularly in the PowerCLI community.

    To make sure, is that 5000 objects a Get-VIAccount builtin limit or an AD limitation ?
    Any chance this would be changed in any of the future PowerCLI releases.

    And with the Domain Alias I suspect you mean the NetBIOS name ?
    Any thoughts on making the Domain parameter more consistent across cmdlets in a future PowerCLI release ?

    1. Thank You Luc!

      On your questions:
      1. The limit comes from the server. The is the default limit of query results. As far as I know it is adjustable through advanced settings. I made a note because using the built in filters will be faster than retrieving all users/groups and then performing filtering and I am not sure how many people are aware of the server limits and how they can be adjusted.
      2. Yes, this is the NetBIOS name.
      3. Definitely they should be consistent. It is good request for enhancement and I’ve already filed one for future PowerCLI releases.

      Thank You for the comments and questions!

  2. Great – I should definitely pronounce, impressed with your web site.
    I had no trouble navigating through all tabs and related information ended up
    being truly simple to do to access. I recently found what I hoped for before
    you know it in the least. Quite unusual. Is likely
    to appreciate it for those who add forums or anything, web site theme .
    a tones way for your client to communicate.
    Excellent task..

    Stop by my blog – jeopardy template for powerpoint

  3. cup of water to wash a load of laundry) and from everything
    I could determine most of these machines like to
    massage clothes as opposed to washing them.
    If you knew there was a place in San Jose, or say,more likely in Los Gatos or Palo Alto
    ( or where-ever) that offered this vending machine service:.
    This sturdy piece is constructed of heavy steel and
    features a white epoxy finish.

    Here is my site; best washing machine (

  4. I would like to thank you for the efforts you have put in writing this site.
    I am hopinng to vview the same high-grade blog posts from you in the future as well.
    In truth, your creative writing abilities has motivated me
    too get my own sijte now 😉

  5. Hey pas bête. Sinon une agence bien professionel avec des prestations référencement c’est Dream Developpement.
    A tester 🙂

  6. you have list of VMhost IP addresses and all VMhosts have the same local administrator credentials, you want to join them to a domain and grant permissions for a domain user or group account assigning it a specific role. In the script I assume the role exists on the VMHost but later I will show you how to create a custom role.

  7. It’s reallyactuallyin facttrulygenuinely very complexdifficultcomplicated in this busyfull of activityactive life to listen news on TVTelevision, sothustherefore I onlysimplyjust use internetwebworld wide webthe web for that purposereason, and takegetobtain the latestnewestmost recentmost up-to-datehottest newsinformation.

  8. Well done and wrtten my friend!
    I’ve just started writing a blog very recently and realized that lot of
    blogs simply rehash old content but add very litle of benefit.

    It’s great too read a benefidial write-up of some actual value to me, as a reader.

    It is actually going down on the list of details I
    need to replicate as a new blogger. Audience
    engagement and material value are king.
    Many wonderful suggestions; you’ve most certainly made it on my
    list of sites to follow!

    Keep uup the good work!
    All the best,

Leave a Reply

Your email address will not be published. Required fields are marked *