Script vSphere 4.1 AD Authentication

One of the new features that came with vSphere 4.1 was the ability to use Active Directory Authentication on ESX(i) servers for permissions, console access and ssh access.This is a great feature that you will probably want to activate on all your ESX(i) servers.

Unfortunately this new feature is not available in PowerCLI 4.1. That means you can’t set this up in your configuration scripts through a PowerCLI cmdlet. In most such cases you can fall back on one of the SDK APIs to bypass this lack of a cmdlet. But unfortunately the new “managers”, of which HostActiveDirectoryAuthentication is one, are not available in the VMware.Vim assembly either.

Rob raised this in a recent PowerCLI Community thread. Yasen, one of the PowerCLI Dev Team members, provided a bypass. To make this bypass a bit more accessible, I decided to roll it up in a PowerShell function.

A (little) bit of background information

The Active Directory Authentication feature has been discussed at length in several vSphere 4.1 blog posts.

A great video, that explains what it is and how you can use it, was made by David Davis. See his VIDEO: New vSphere 4.1 Windows Active Directory Authentication post.

The script

Annotations

Line 1: This function uses PowerShell v2 features and will not run with PowerShell v1

Line 3-63: The Get-VMHostAuthentication function

Line 38-60: Return information for each of the configured authentication methods.

Line 65-138: The Set-VMHostADDomain function

Line 24,108: Handles use of the function in a pipeline or with a -VMHost parameter

Line 26-34,110-118: Creates the PropertyFilterSpec object through the use of the hash table property list.

Line 119-123: The ‘bypass’ from Yasen. It uses the PropertyCollector to  ultimately get at the MoRef of the HostActiveDirectoryAuthentication manager.

Line 123: The MoRef is converted to a VIM 4.1 MoRef with the ToVim41 method of the builtin VIConvert class.

Line 125: Depending on the state of the ADJoin switch, the host is ‘joined’ or ‘removed’ from the AD domain.

Line 126-129: If the AD account is passed through a PSCredential object, the clear text account and password are extracted.

Line 135: The script waits for the completion of the called method.

Examples

To display the authentication services for an ESX(i) server that has no AD authentication configured.

This returns the following information.

To add a specific ESX(i) server to an Active Directory domain you can do

or

The Get-VMHostAuthentication function now returns.

You can also enable AD authentication on a series of ESX(i) hosts.

or like this

To remove a host, you have to set the -ADJoin switch to $false.
Like this

The previous call assumes that there were no permissions with AD principals left on the ESX(i) server or any of it’s children.
If there were, you would get an error message.

You can let the ‘unjoin’ remove any remaining permissions for you.
For that you use the -RemovePermission parameter.

15 Comments

    Loren Gordon

    Luc, Not sure if there’s a better way of doing this now, but I merged your script with Alex’s. Hopefully this will be helpful to someone else.

    function Set-VMHostADDomain{
    Get-VMHost | Set-VMHostADDomain -ADJoin:$true -Domain $domain -User $user -Password $pswd
    .EXAMPLE
    PS> Set-VMHostADDomain -VMHost (Get-VMHost) -ADJoin:$true -Credential $cred
    .EXAMPLE
    PS> Set-VMHostADDomain -VMHost (Get-VMHost) -ADJoin:$false -RemovePermission:$true
    #>
    param(
    [parameter(ValueFromPipeline = $true,Position=1,Mandatory = $true)]
    [VMware.VimAutomation.ViCore.Impl.V1.Inventory.VMHostImpl[]]$VMHost,
    [string]$Domain,
    [string]$User,
    [string]$Password,
    [System.Management.Automation.PSCredential]$Credential,
    [switch]$ADJoin,
    [switch]$RemovePermission = $false
    )

    process{
    if(!$VMHost){$VMHost = $_}
    foreach($esx in $VMHost){
    $collector = Get-View -id $esx.ID
    $authenticationManagerView = Get-View $vmhostView.ConfigManager.AuthenticationManager
    $hostActiveDirectoryAuthenticationMoRef = $authenticationManagerView.SupportedStore | where { $_.Type -eq ‘HostActiveDirectoryAuthentication’ }
    $hostActiveDirectoryAuthentication = Get-View $hostActiveDirectoryAuthenticationMoRef

    if($ADJoin){
    if($Credential){
    $User = $Credential.GetNetworkCredential().UserName
    $Password = $Credential.GetNetworkCredential().Password
    }
    $taskMoRef = $hostActiveDirectoryAuthentication.JoinDomain_Task($Domain,$User,$Password)
    }
    else{
    $taskMoRef = $hostActiveDirectoryAuthentication.LeaveCurrentDomain_Task($RemovePermission)
    }
    $esx.ExtensionData.WaitForTask([VMware.Vim.VIConvert]::ToVim($taskMoRef))
    }
    }
    }
    @LucD

    Alex Mittell

    Hey Luc,

    This code below worked for me and seems quite a lot simpler to use, obviously you probably want to use a securestring or Get-Credentials to get the password instead of plain text, the below is just an example, but it got my ESXi hosts joined to the Domain just fine without loading anything but the standard PowerCLI modules. What do you think?

    Regards,

    Alex

    function JoinDomainWithAD ($vmhost, $addomain, $aduser, $adpass) {
    $vmhostView = Get-View -id $vmhost.ID
    $authenticationManagerView = Get-View $vmhostView.ConfigManager.AuthenticationManager
    $hostActiveDirectoryAuthenticationMoRef = $authenticationManagerView.SupportedStore | where { $_.Type -eq ‘HostActiveDirectoryAuthentication’ }
    $hostActiveDirectoryAuthentication = Get-View $hostActiveDirectoryAuthenticationMoRef
    $hostActiveDirectoryAuthentication.JoinDomain($addomain, $aduser, $adpass)
    }

    Write-Host
    Write-Host ” Joining ESXi server to Active Directory domain…”

    $esxihost = Read-Host “Enter ESXi host FQDN to join to Domain”
    $ADDOMAIN = Read-Host “Enter Domain to join ESXi host to”
    $ADUSER = Read-Host “Enter Username with permission to join to Domain: $ADDOMAIN”
    $ADPASS = Read-Host “Enter password for username”

    JoinDomainWithAD -vmhost $esxihost -addomain $ADDOMAIN -aduser $ADUSER -adpass $ADPASS

      LucD

      @Alex, the reason why I used the PropertyCollector was because the PowerCLI version at that time was missing the AuthenticationManager in the assembly. See also Yasen’s entry in the Community thread the article points to.
      But you are absolutely right, the later PowerCLI builds did have the AuthenticationManager in the assembly, and your function is using that and is indeed a lot simpler.

    sandeep

    it’s not detaling more concept

      LucD

      @Sandeep, can you include the code you are trying to run or the eventual error messages you are seeing ?

    maldini

    could you elaborate how to get the logs populating???

    maldini

    Hi jeff,
    I am facing the excet same problems trying to join my ESXi host to domain. Could you eleborate how to get the logs populating?

    Jeff Couch

    @Jeff Couch

    I jumped the gun. Found in the logs that my $domain was not populating. This fixed the issue.

    Thanks for an awesome function set!

      LucD

      Thanks Jeff.
      I kept the comment in, it can be a pointer when someone else encounters the same problem.

    Jeff Couch

    Luc,

    I am having trouble with this function. I am getting:

    Exception calling “WaitForTask” with “1” argument(s): “Errors in Active Directory operations.”
    $esx.ExtensionData.WaitForTask <<<< ([VMware.Vim.VIConvert]::ToVim($taskMoRef))

    It works fine from the VI client. Any thoughts?

    Thanks,
    Jeff

    John Cousens

    @John Cousens
    Never mind. The problem was between the keyboard and my chair 🙂 I tried to add the host from vCenter and got the same error. My host profile hadn’t applied the host name which was still set to “localhost”.

    John Cousens

    hey Luc,
    this is an awesome script and works for us 90% of the time. However, I occasionally get the following error at line 135 in your script and don’t know why. Any help would be greatly appreciated. This is happening with ESXi 4.1.

    Exception calling “WaitForTask” with “1” argument(s): “The host does not have a suitable FQDN.”
    $esx.ExtensionData.WaitForTask <<<<([VMware.Vim.VIConvert]::ToVim($taskMoRef))

      LucD

      @John, thanks.
      Could it be that you are un-joining an AD domain while you have a Connect-VIServer with an AD account active ?

    Yev Berman

    Hey Luc,
    I wonder, is there any PowerCLI script you know that can Join\Change domain to VM?
    P.S. Without RemoteCLI.

    Thank you for your attention.

      LucD

      Hi Yev, you can do that with the Set-OSCustomizationSpec cmdlet.
      Use the -Domain parameter.

Leave a Reply

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

*
*

This site uses Akismet to reduce spam. Learn how your comment data is processed.