Automate server deployment with PowerCLI


I'm new to the VMWare world and PowerCLI.  We are working on a project that requires the creation of a few dozen servers.  We are currently cloning templates and manually configuring them, but there's obviously better ways to accomplish this.  My first attempt was to use PowerCLI and the Invoke-VMScript.  I have it configuring the NICs, setting the static IP, renaming the machine, activating windows, and joining it to the domain.  I've found that the Invoke-VMScript works about 60-75% of the time.  It will throw errors about waiting for VMWare tools, regardless of the VMWare tools state.  I've dug as much as I can and cannot get any solid answers.  The servers are 2012R2, so I'm wondering if it's a compatibility issue since it seems that only up through 2008 is supported.

I found another avenue to try, the OSCustomizationSpec, but I'd had even less luck with that.  Can anyone shed some light on what should be a fairly simple task?


0 Kudos
4 Replies

You should perhaps first try to determine what is causing the failures.

There are some logs available that might help.

  • On the VM level: check the vmware.log files in the VM's datastore folder
  • Inside the VM: check the eventlogs.

Did you add some verbosity to your customisation scripts ?

Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos

I can't say exactly what's happening, but it seems that if you call a restart from within an Invoke script like below:

$pscript = 'Add-Computer -DomainName cloud.com -OUPath "OU=WSUS Managed,OU=Servers,DC=cloud,DC=com" -Credential $CC -Restart'

Invoke-VMScript -VM $NewSaaSSQLServer -HostCredential $HC -GuestCredential $GC -ScriptType powershell -ScriptText $pscript

you get all kinds of odd behavior.  I found that using the Stop-VMGuest and Start-VMGuest is a lot more reliable.

0 Kudos

Matt, I worked with LucD on a great script for deploying VMs leveraging PowerCLI, OSCustomizationSpec and CSV file.  I have been using it for a couple of years now.  Its perfect to roll out multiple VMs leveraging templates and getting the servers onto the domain.  Reach out and I will send them to you. Thanks, BostonTechGuy

0 Kudos

Following up on this.  Below is a copy of another post I replied to with the same question.  Please take a look.


This script was developed a number of years ago with huge assistance from LucD.  You may have seen it in other postings.  Its also geared towards Windows Servers.  I have not used in on Linux servers.  If you know what changes are needed to make it Linux friendly please feel free to update it and share with others.

The whole script works with CSV File, Powershell Loops, and OS CustomizationSpec.

FIRST: create a customization spec in vCenter to get the general options that will always be the same on every box completed.  Settings like Domain Access and such.  Dont worry about IPs and names.  We are going to modify those in real time with the script.

SECOND: Get the script changed to your specs. vCenter name and the like.  In order for this to work, you need the first row in the CSV to be Headers of the variables in the script.  MOST IMPORTANT: Punctuation is not forgivable. What is in the CSV must match EXACTLY whats in the script.  I have made this error more than once

SCRIPT: (NOTE: I made several attempts to get the HTML code correct for this to appear correctly and failed.  I have placed the whole thing in a quote instead..)

<#Deploy VMs with Custom Specs for Automated Deployments
with Static IP Addresses and Domain Access
Hosts within a Cluster.
Written by Boston Tech Guy May 2,2013
Last Updated June 13, 2015


# List to deploy from. Standard CSV file with headings for script to pull from

$deploylist = "<Location of CSV File>\name of CSV.csv"

# VCenter you are connecting too. For the name, use FQDN

$vcserver = "<Name of VCENTER to connect to>"

# Connect to vCenter server. It will use cache creds of user logged into workstation

Connect-VIServer $vcserver

# Deployment loop and customization done during server creation

Import-Csv $deploylist -UseCulture | %{

    Get-OSCustomizationSpec $_."Customization" | Get-OSCustomizationNicMapping | `

    Set-OSCustomizationNicMapping -IpMode UseStaticIP -IpAddress $_."IP Address" `

        -SubnetMask -DefaultGateway $_."Gateway" -Dns $_."First DNS",$_."Second DNS"

    New-VM -Name $_."Server Name" -Template $_."Template" -VMHost $_."Esx Host" `

        -Datastore $_."Datastore" -OSCustomizationSpec $_."Customization" `

        -Confirm:$false -RunAsync


Disconnect-VIServer -Confirm:$false



This script was written in a template format.  It can easily be modified.

Since majority of the Subnet Masks at most companies are the same, the number is hard coded. However it can easily be changed

If deploying a number of servers on same domain, the DNS entries can also be hard coded.

This script also is not forgiving on punctuation.  Host, VM Template, VM Customization Script and Server Names MUST BE EXACT!

Given the number of servers that could be deployed and resources needed to generate those

servers, this script does not assign Port Groups or Powers on the server. Servers do not complete

in a timable fashion. Its somewhat random when a server completes.  Therefor a second script

has been created to perform those task.  That script should be ran once the last server has

been deployed from this script.


As you can see couple things are going here.  During the first loop the Customization Spec is changed for the next VM you are going to deploy.  The second part of the script actually builds the New VM.  Then the loop starts over again with the next row in the CSV.  Wash, Rinse, Repeat.

Key couple points

  • The deployments will go at different speeds depending on what else the Hosts are doing.  There really isnt a "5 VMs every 2 Mins" timetable
  • Automating the Power On VM becomes problematic due to the point above.  Recommend you have a different script to power on the VMs.

Here is what the first couple of rows would look like on the CSV

Server NameESX HostDatastoreTemplateCustomizationIP AddressGatewayFirst DNSSecond DNSVLAN
Name of VMHost NameDatastore NameTemplate NameOS Customize Spec Name192.168.1.100192.168.1.1192.168.1.101192.168.1.102Servers

I have used this script to deploy hundreds of VMs at a single time.  Again to repeat, the speed of the deployments depends on what the Hosts are doing. If a lot of vMotions are going on, the Hosts will queue the builds.



Boston Tech Guy

0 Kudos