WilliamLam.com

  • About
    • About
    • Privacy
  • VMware Cloud Foundation
  • VKS
  • Homelab
    • Resources
    • Nested Virtualization
  • VMware Nostalgia
  • Apple
You are here: Home / Uncategorized / Automating Active Directory Domain Join in ESX(i) Kickstart

Automating Active Directory Domain Join in ESX(i) Kickstart

02.23.2011 by William Lam // 10 Comments

I recently received an email asking if it was possible to automate the joining of an ESXi 4.1 host to Active Directory within a kickstart installation. The simple answer is yes; you can easily do so using the same trick found in tip #7 in Automating ESXi 4.1 Kickstart Tips & Tricks post which connects locally to the vSphere MOB using python.

Having said that, there is a small caveat to this solution in which the credentials used to join the ESX(i) host must be exposed in clear-text, this may or may not be acceptable. A potential way of getting this to work is to create a dedicated windows service account with limited privileges to add only ESXi hosts to your domain.

The reason for the use of clear-text password is the vSphere API method that is used to join an ESX(i) host to AD domain, joinDomain(), only supports plain text.

Ideally, the password parameter should accept either an encrypted hash or some type of certificate which can be validated by Active Directory server. The actual solution is pretty straight forward, by crafting the appropriate call to vSphere MOB, we are able to generate a python script during the %firstboot section of ESX(i) kickstart installation which will execute upon the initial boot up of the host.

Update (03/26/11):  Thanks to VMTN user klich who has found a solution to embed the password of the Active Directory user in a base64 encoding so that it is not visible in plain text for anyone who has access to the kickstart configuration file. To create the encoded hash, you will need access to either a ESX(i) or UNIX/Linux system which has python interpreter installed.

You will need to run the following command and substitute the password you wish to encode.

python -c "import base64;
print base64.b64encode('MySuperSecurePasswordYo')"

The output will be your encoded hash:

Note: Make sure your ESX(i) hostname is configured with a FQDN (Fully Qualified Domain Name), else you will get an error when trying to join to AD domain.

The following snippet should be added to your %firstboot section of your kickstart. Remember to replace the variables: domainname, ad_username and encodedpassword with your configurations and make sure to leave the password variable blank.

ESX(i) 4.1
cat > /tmp/joinActiveDirectory.py << __JOIN_AD__

import sys,re,os,urllib,urllib2

# MOB url
url = "https://localhost/mob/?moid=ha-ad-auth&method=joinDomain"

# mob login credentials -- use password = "" for build scripting
username = "root"
password = ""

# which domain to join, and associated OU
# e.g.
#       "primp-industries.com"
#       "primp-industries.com/VMware Server OU"
domainname = "primp-industries.com"

# active directory credentials using encoded base64 password
ad_username = "*protected email*"
encodedpassword = "TXlTdXBlclNlY3VyZVBhc3N3b3JkWW8"
ad_password = base64.b64decode(encodedpassword)

#auth
passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
passman.add_password(None,url,username,password)
authhandler = urllib2.HTTPBasicAuthHandler(passman)
opener = urllib2.build_opener(authhandler)
urllib2.install_opener(opener)

#execute method
params = {'domainName':domainname,'userName':ad_username,'password':ad_password}
e_params = urllib.urlencode(params)
req = urllib2.Request(url,e_params)
page = urllib2.urlopen(req).read()
__JOIN_AD__

#execute python script to Join AD
python /tmp/joinActiveDirectory.py

If you are using ESX(i) 4.1 Update 1 or if you run into the "urllib2.HTTPError: HTTP Error 403: Forbidden: Possible Cross-Site Request Forgery" you will need to use the following snippet below which includes the session cookie as part of the request to the vSphere MOB due to a recent CSRF patch from VMware identified by VMTN user klitch.

ESX(i) 4.1 Update 1

cat > /tmp/joinActiveDirectory.py << __JOIN_AD__

import sys,re,os,urllib,urllib2,base64

# mob url
url = "https://localhost/mob/?moid=ha-ad-auth&method=joinDomain"

# mob login credentials -- use password = "" for build scripting
username = "root"
password = ""

# which domain to join, and associated OU
# e.g.
#       "primp-industries.com"
#       "primp-industries.com/VMware Server OU"
domainname = "primp-industries.com"

# active directory credentials using encoded base64 password
ad_username = "*protected email*"
encodedpassword = "TXlTdXBlclNlY3VyZVBhc3N3b3JkWW8"
ad_password = base64.b64decode(encodedpassword)

# Create global variables
global passman,authhandler,opener,req,page,page_content,nonce,headers,cookie,params,e_params

# Code to build opener with HTTP Basic Authentication
passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
passman.add_password(None,url,username,password)
authhandler = urllib2.HTTPBasicAuthHandler(passman)
opener = urllib2.build_opener(authhandler)
urllib2.install_opener(opener)

### Code to capture required page data and cookie required for post back to meet CSRF requirements  ###
req = urllib2.Request(url)
page = urllib2.urlopen(req)
page_content= page.read()

# regex to get the vmware-session-nonce value from the hidden form entry
reg = re.compile('name="vmware-session-nonce" type="hidden" value="?([^\s^"]+)"')
nonce = reg.search(page_content).group(1)

# get the page headers to capture the cookie
headers = page.info()
cookie = headers.get("Set-Cookie")

# Code to join the domain
params = {'vmware-session-nonce':nonce,'domainName':domainname,'userName':ad_username,'password':ad_password}
e_params = urllib.urlencode(params)
req = urllib2.Request(url, e_params, headers={"Cookie":cookie})
page = urllib2.urlopen(req).read()

__JOIN_AD__

#execute python script to Join AD
python /tmp/joinActiveDirectory.py
After your ESXi host has completed installation, you can login to the ESX(i) host using the vSphere Client and you should see a recent successful task on the domain join process.

You can also verify by clicking on Configurations->Authentication Services and verify that your ESX(i) host is now part of the Active Directory domain.

In the next post, I will go over the details of adding domain users within the ESX(i) kickstart.

As a side note, it is quite unfortunate that ESXi only supports Microsoft Active Directory and does not integrate with other well known directory services such as NIS/NIS+, Kerberos, OpenLDAP, eDirectory, etc; this was actually possible with classic ESX. VMware has continued to focus on Windows-centric solutions and neglect the UNIX/Linux community by not supporting OS agnostic management tools that integrate with their vSphere platform. I hope this will change in the future for true interoperability.

More from my site

  • Automating Active Directory User Management in ESXi Kickstart
  • Ghetto webAccess for ESXi
  • Easily automate ESXi 6.0 Active Directory join using domainjoin-cli
  • Disable LUN During ESXi Installation
  • How to Automate the Upgrade of Classic ESX 4.x to ESXi 5

Categories // Uncategorized Tags // active directory, ESXi 4.1, kickstart, mob

Comments

  1. *protecteddconvery says

    02/23/2011 at 1:49 pm

    Will -

    Great post, as always! Is there a way to encrypt the AD Admin password? This would most likely be important in some enterprises where the ESXi admin is not allowed to see the AD admin secrets.

    Dave

    Reply
  2. *protectedWilliam says

    02/23/2011 at 3:28 pm

    Dave,

    The issue is the vSphere method only supports clear text. This means even if you encrypted the password, during the kickstart you still had to decrypt it and if the vSphere admins had access to the ks.cfg, they could easily figure out the password. I was thinking about something like that but I couldn't come up with anything that wouldn't allow someone to easily reverse engineer it. The limitation is with VMware only supported clear text, ideally an encrypted hash or certificate would be a better approach

    Reply
  3. *protectedjasgrif11 says

    09/07/2011 at 4:22 pm

    Thanks Will for this script. I added it to my esxi kickstart but it doesn't seem to run. However if I run it manually on the host it works.
    Any ideas?
    It is part of my %firstboot.

    Thanks Again
    Jason

    Reply
  4. *protectedWilliam says

    09/13/2011 at 1:30 am

    @jasgrif11,

    Have you taken a look at vSphere Client while this is occurring to see what errors it is throwing?

    Reply
  5. *protectedJeremy says

    10/16/2012 at 10:43 pm

    Hi,
    I'm just reading this post, but can't see the snippet for the %firstboot section. Is it missing?

    Cheers,
    Jeremy.

    Reply
    • *protectedWilliam says

      10/16/2012 at 10:49 pm

      @Jeremy,

      It looks like the hosting for syntaxhighlighting might be down. You can view the source of this blog post to get the details. I'm hoping the hosting site will be back soon, sorry for inconvenience.

      Reply
    • *protectedjhonathan barrios says

      01/25/2013 at 9:46 pm

      hello my name is Jhonathan 'I am using this script in my kickstart. in firstboot% for ESX (i) 5.0 and 5.1 and does not work throws no error might help if the commands are the same or if I should make any changes..

      Reply

Trackbacks

  1. How to automatically add ESX(i) host to vCenter in Kickstart | virtuallyGhetto says:
    03/02/2014 at 7:45 pm

    […] recently updating my Automating Active Directory Domain Join in ESX(i) Kickstart article, it reminded me an old blog post by Justin Guidroz who initially identified a way to add an […]

    Reply
  2. Automating ESXi 4.1 Kickstart Tips & Tricks | virtuallyGhetto says:
    03/03/2014 at 2:38 pm

    […] Here is a post on Automating Active Directory Domain Join in ESXi Kickstart […]

    Reply
  3. How to automate vSphere MOB operations using PowerShell? | virtuallyGhetto says:
    10/25/2016 at 8:17 am

    […] MOB and wanted to do so using PowerShell. Several years back I had demonstrated how you could invoke the vSphere MOB using Python but I could not find any PowerShell examples that actually worked. I figured this would be a good […]

    Reply

Thanks for the comment!Cancel reply

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

Search

Thank Author

Author

William is Distinguished Platform Engineering Architect in the VMware Cloud Foundation (VCF) Division at Broadcom. His primary focus is helping customers and partners build, run and operate a modern Private Cloud using the VMware Cloud Foundation (VCF) platform.

Connect

  • Bluesky
  • Email
  • GitHub
  • LinkedIn
  • Mastodon
  • Reddit
  • RSS
  • Twitter
  • Vimeo

Recent

  • Programmatically accessing the Broadcom Compatibility Guide (BCG) 05/06/2025
  • Quick Tip - Validating Broadcom Download Token  05/01/2025
  • Supported chipsets for the USB Network Native Driver for ESXi Fling 04/23/2025
  • vCenter Identity Federation with Authelia 04/16/2025
  • vCenter Server Identity Federation with Kanidm 04/10/2025

Advertisment

Privacy & Cookies: This site uses cookies. By continuing to use this website, you agree to their use.
To find out more, including how to control cookies, see here: Cookie Policy

Copyright WilliamLam.com © 2025