Skip navigation
VMware

This Question is Possibly Answered

1 "correct" answer available (10 pts) 2 "helpful" answers available (6 pts)
1,391 Views 22 Replies Last post: Sep 5, 2011 5:15 AM by virtuallysi RSS
klich Enthusiast 66 posts since
Jul 25, 2005
Currently Being Moderated
15. Mar 14, 2011 11:31 AM in response to: lamw
Re: join domain kickstart

Has anybody tried this on ESX Classic?

 

Seems to work fine on ESXi, but on classic I get this error "raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 403: Forbidden: Possible Cross-Site Request Forgery"

 

Thanks.

klich Enthusiast 66 posts since
Jul 25, 2005
Currently Being Moderated
17. Mar 23, 2011 12:42 PM in response to: tdubb123
Re: join domain kickstart

I didn't track it to the exact patch, but one of the pre v4.1 Update 1 patches  added detection for "Possible Cross-Site Request Forgery"

 

I setup my mob to run over http, did some network captures, and determined that the following needed to be included:

1. Session cookie

2. Hidden form / value for 'vmware-session-nonce'

 

I'm not a python guru, so if you have a better way to do what I've done, please contribute back to this thread.

 

The following code is working for me (at least post-install, I'll trying during scripted installation shortly).

 

I sure hope this helps somebody else, as it was a challenge to resolve.

 

Enjoy!

 

 

import sys,re,os,urllib,urllib2,base64
### Define Variables ###

print 'Begin executing join domain script'

# 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
domainname = "my.domain.com/VMWare Server OU"

# Active Directory credentials with rights to join a computer to the domain
# create encoded password with the command: python -c "import base64; print base64.b64encode('mypassword')"
# note: escape special characters in your password with a \
# Feel free to improve this solution, but it at least keeps cleartext out of the file.
ad_username = "user@my.domain.com"
encodedpassword = "cGFzc3dvcmQ="
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
try:
  passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
  passman.add_password(None,url,username,password)
  authhandler = urllib2.HTTPBasicAuthHandler(passman)
  opener = urllib2.build_opener(authhandler)
  urllib2.install_opener(opener)
except IOError, e:
    if hasattr(e, 'reason'):
        print 'FAIL: HTTP Authentication'
        print 'Reason: ', e.reason
        sys.exit(1)
    elif hasattr(e, 'code'):
        print 'FAIL: HTTP Authentication'
        print 'Error code: ', e.code
        sys.exit(1)
else:
    print 'SUCCESS: Build HTTP Basic Authentication Handler'

### Code to capture required page data and cookie required for post back to meet CSRF requirements  ###
try:
  req = urllib2.Request(url)
  page = urllib2.urlopen(req)
  page_content= page.read()
except IOError, e:
    if hasattr(e, 'reason'):
        print 'FAIL: MOB Page Request'
        print 'Reason: ', e.reason
        sys.exit(1)
    elif hasattr(e, 'code'):
        print 'FAIL: MOB Page Request'
        print 'Error code: ', e.code
        sys.exit(1)
else:
  print 'SUCCESS: Request MOB page data'

# 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
try:

  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()
except IOError, e:
    if hasattr(e, 'reason'):
        print 'FAIL: MOB Page Request'
        print 'Reason: ', e.reason
        sys.exit(1)
    elif hasattr(e, 'code'):
        print 'FAIL: MOB Page Request'
        print 'Error code: ', e.code
        sys.exit(1)
else:
  print 'SUCCESS: Host joined to the domain'
virtuallysi Enthusiast 22 posts since
Feb 25, 2009
Currently Being Moderated
18. Mar 25, 2011 5:46 AM in response to: klich
Re: join domain kickstart

Good work klich!  This worked for me.  Also, its nice that the AD password is no longer in clear text and you can specify an OU

lamw Guru vExpert 5,959 posts since
Nov 27, 2007
Currently Being Moderated
19. Mar 26, 2011 4:55 PM in response to: klich
Re: join domain kickstart

Hi klich,

 

Thanks for sharing this information, I've gone ahead and updated my original log post with your modified code - http://www.virtuallyghetto.com/2011/02/automating-active-directory-domain-join.html

*Disclaimer: VMware Employee - William Lam | http://www.virtuallyghetto.com | http://blogs.vmware.com/vsphere/automation | @lamw
Marko1902 Lurker 2 posts since
Mar 14, 2011
Currently Being Moderated
20. Apr 29, 2011 1:20 AM in response to: lamw
Re: join domain kickstart

Hi,

 

I have succed adding ESXi 4.1 U1 host to AD domain.

You need to crate AD computer account manualy on domain controller (just hostname, without FQDN) before joining host to domain.

 

Regard,

Marko.

klich Enthusiast 66 posts since
Jul 25, 2005
Currently Being Moderated
21. Apr 29, 2011 7:56 AM in response to: Marko1902
Re: join domain kickstart

Marko,

 

I'm not sure what is different in your configuration that is requiring you to create the computer object first, but in our deployment this step it is not required.

 

The only additional step we required was to grant the AD account that we use in the script the ability to create computer objects in the domain.

 

There are several ways to accomplish that, but for those looking for an example, look at: http://kb.vmware.com/kb/1007697

 

Regards,

 

klich

virtuallysi Enthusiast 22 posts since
Feb 25, 2009
Currently Being Moderated
22. Sep 5, 2011 5:15 AM in response to: klich
Re: join domain kickstart
I've been updating my scripted install forESXi 5 and couldn't get the domain join script to work.  It seems that ESXi 5 now requires the root password included at the start of the script.

I amended the existing lines:

# mob url url = "https://localhost/mob/?moid=ha-ad-auth&method=joinDomain" # mob login credentials -- use password = "" for build scripting username = "root" password = ""
To the below (using an encoded password - Details on how to create this are mentioned in the code)

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

# mob login credentials -- use password = "" for build scripting
username = "root"
encodedlocalpassword = "%ENCODEDPASSWORD%"
password = base64.b64decode(encodedlocalpassword)

Once I made this change the ESXi 5 build successfully joined to the domain.

Bookmarked By (0)

Share This Page

Communities