Using Puppet to join Windows guests to a domain with vCloud Director

Posted by

You may be aware that you can join Windows VMs to a domain using the built-in functionality within vCloud Director.  However, this requires that a DHCP server be available on the network that the VMs are connecting to.  This can sometimes be a pain if you’re spinning multiple networks and have to engage with another team to set up a DHCP server.  In this post I’ll show how to use Puppet to join vCloud VMs to a domain.

Software versions used

  • Puppet 3.2
  • vCloud 5.1.1
  • vSphere 5.5
  • Windows 2012 R2

Puppet Server Configuration

I’m not going to cover how to install the Puppet server.  You can read how to install it here:

We need to install two Puppet modules: domain_membership and reboot.  Reboot is needed to reboot the guest after it has been joined to the domain.

Here is a video on how to use the reboot module.

site.pp changes


Here I edit site.pp so that when my vCloud VMs (default names of win2012-###) contact the puppet server, the Puppet server will run the domain_membership module.   Read the domain_membership link above for all of the module’s options.

node /^win2012.*\.vmware\.local$/ {
   class { 'domain_membership':
   domain   => 'vmware.local',
   username => 'chris',
   password => 'password',
   force    => true,
   resetpw  => false,

domain_membership module’s init.pp file


You can leave most of this file alone, but we need to add the reboot module info.

I did change the join option from a value of 32 to 39.  You can read all of the options here and enter what makes the most sense in your environment.  If you want more flexibility, you can edit the code so it will build up the value depending on what parameters you pass in.

# 1 (0x1)   Default. Joins a computer to a domain. If this value is not specified, the join is a computer to a workgroup.
 if $force {
 $fjoinoption = '39' # I changed this from the default of 32.
 } else{
 $fjoinoption = '1'

Here are the commands that add the guest to the domain.  All of these are defaults except the notify entry.  The notify entry says to call the Reboot module once the guest has been joined to the domain.

# Since the powershell command is combersome, we'll construct it here for clarity... well, almost clarity
$command = "(Get-WmiObject -Class Win32_ComputerSystem).JoinDomainOrWorkGroup('${domain}',${_password},'${username}@${domain}',${_machine_ou},${fjoinoption})" 

exec { 'join_domain':
  command  => $command,
  unless  => "if((Get-WmiObject -Class Win32_ComputerSystem).domain -ne '${domain}'){ exit 1 }",
  provider => powershell,
  notify   => Reboot['after']

Add the reboot module by adding these lines to the end of the class.

reboot { 'after':
   apply => finished,

Puppet Agent Configuration

On the Windows 2012 R2 VM that is going to be your vCloud template, download and install the Puppet agent

$url = “”

Invoke-WebRequest -Uri $url -OutFile puppet.msi

cmd /c “msiexec /qn /i puppet.msi /l*v install.log”

Verify the Puppet agent version

& ‘C:\Program Files (x86)\Puppet Labs\Puppet\bin\puppet.bat’ –version

Add the Puppet agent to the PATH environment variable

set PATH=%PATH%;C:\Program Files (x86)\Puppet Labs\Puppet\bin

The Puppet agent configuration file (puppet.conf) is located in puppet.conf is in %PROGRAMDATA%\PuppetLabs\.  By default, it looks to a server named puppet, which is what my server is named.  You may need to change this.


Make sure that your vCloud template has “Enable  Guest Customization” and “Change SID” enabled under the VM’s Guest Customization tab.  If everything is set up properly, the following steps will happen when you power on a VM deployed from the template:

  1. vCloud will power the VM on in vCenter
  2. When it first boots it will have the templates original name and IP settings.  If the puppet agent service is configured to automatically start and the VM can talk to the Puppet server, the VM will try to its configuration from the Puppet server. Later I’ll discuss this further.
  3. Sysprep will run and the VM will reboot.
  4. When the VM boots back up vCloud will configure the name and IP.
  5. The VM will talk to the Puppet server, run the domain_membership module, which will join it to the domain and then the reboot module will reboot the VM.
  6. After the VM reboots it should be joined to the domain.

In step #2 I mentioned that when the VM first boots and has yet to be sysprep’d or customized (depending on your settings) it’s possible for the VM to be on the network using the templates name/IP and try to talk to the Puppet server.  You probably don’t want this happening so here are a few ways to avoid this.

  • Give the template a name that’s won’t be identified as a node on the Puppet server.
  • Have the Puppet agent service set to manual and then use vCloud’s post guest customization set the service to automatic and start the service.  Once the service is running it will attempt to talk to the Puppet server.
  • Have vCloud’s post customization install the Puppet agent.

Here are some examples using vCloud’s customization script options.  This can be found towards the bottom of the VM’s “Guest Customization” tab within vCloud.

Start the Puppet agent after guest customization

if "%1%" == "precustomization" (
  goto end
) else if "%1%" == "postcustomization" (
  net puppet start

Set the Puppet agent service to automatic and start the Puppet agent after guest customization

if "%1%" == "precustomization" (
  goto end
) else if "%1%" == "postcustomization" (
  sc config puppet start= auto 
  net puppet start


  • I’m a Puppet novice.
  • Location of sysprep log files
  • If sysprep is failing, c:\Windows\Debug\NetSetup.log is a good place to look.
  • If you’ve sysprep’d more than three times during your testing, you can reset it by following these instructions.
  • Location of the vCloud customization log has changed to c:\windows\temp\vmware-imc\guestcust.log
  • Testing was done with UAC turned off.

One comment

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s