A recent project revisited deploying virtual machines via PowerCli. Its fair to say this isn’t a new tool but sometimes over looked.

Part 1 / Part 2

My requirements were to deploy :

100+ virtual machines (within a few hours)

domain join all machines

license the OS

various virtual machine specifications

various Windows OS versions.

to two different data centers within a linked vCenter setup

to resource pools

to different data stores

to different networks

The constraints:

vSphere 6.0 update 2

no budget for third party automation tools

small window of opportunity to deploy the VMs

On the plus side there was:

o Loads of available CPU and RAM

o Large datastores presented

o Subnets prepared

o Stretched VLANs across Data Centers

The tools I used to the task

Excel (CSV)

Notepad++

PowerCLi

The CSV file example

# Example Bulk_VMs_Deploy.csv

Template Datastore VMhost Custspec VMname IPaddress Subnet Gateway 2012_Template Storage1 ESXi.domain 2012_Spec test2003VL1 192.168.0.191 255.255.255.0 192.168.0.1 PDNS SDNS ResourcePool RAM CPU VLAN Size Format 192.168.0.10 127.0.0.1 resource1 2 2 VM Network 10 thin

The Script

# Automate the deployment of customised virtual machines deployed in vSphere 6.0. Tested against u2

#

# Prereq’s

# 1) Populate the a CSV file called Bulk_VMs_Deploy.csv

# 2) Create a Windows Server template

# 3) Create a customization spec within vSphere for Windows

# 4) Run Bulk_VMs_Deploy.ps1 script via PowerCli as administrator (CSV file must be stored in the same location where the script is run from)

#

#https://blogs.vmware.com/PowerCLI/2015/03/powercli-6-0-introducing-powercli-modules.html

if ( !(Get-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue) ) {

###### IMPORTANT, Check this file path is correct##########

. “C:\Program Files (x86)\VMware\Infrastructure\PowerCLI\Scripts\Initialize-PowerCLIEnvironment.ps1”

}

Connect-VIServer VC6.test.domain

#connect to a VC. This also works with Linked VC’s

$vmlist = Import-CSV .\Bulk_VMs_Deploy.csv

foreach ($item in $vmlist) {

#set variables to read from CSV

$template = $item.template

$datastore = $item.datastore

$vmhost = $item.vmhost

$custspec = $item.custspec

$vmname = $item.vmname

$ipaddr = $item.ipaddress

$subnet = $item.subnet

$gateway = $item.gateway

$pdns = $item.pdns

$sdns = $item.sdns

$resourcepool = $item.resourcepool

$cpu = $item.cpu

$ram = $item.ram

$vlan = $item.vlan

$size = $item.size

$format = $item.format

#Get the Specification and set the Nic Mapping

New-OSCustomizationNicMapping -Spec $custspec -IpMode UseStaticIp –Position 1 -IpAddress $ipaddr -SubnetMask $subnet -DefaultGateway $gateway -Dns $pdns,$sdns

#Create VM using Template with the adjusted Customization Specification

New-VM -Name $vmname -Template $template -Datastore $datastore -VMHost $vmhost -ResourcePool $resourcepool | Set-VM -OSCustomizationSpec $custspec -Confirm:$false

#Set the Network Name

Get-VM -Name $vmname | Get-NetworkAdapter | Set-NetworkAdapter -NetworkName $vlan -Confirm:$false

#Set the CPU and Memory

Get-VM -Name $vmname | Set-VM -MemoryGB $ram -NumCPU $cpu -Confirm:$false

#Additional Disk

#Get-VM -Name $vmname | New-HardDisk -CapacityGB $size -StorageFormat $format -Confirm:$false

#Remove the NicMapping

Get-OSCustomizationSpec $custspec | Get-OSCustomizationNicMapping | Remove-OSCustomizationNicMapping -Confirm:$false

#PowerOn VM

Start-VM $vmname

}

#Disconnect from VC.

disconnect-VIServer VC6.test.domain -Confirm:$false

Disclaimer Please take the code and evolve it into a different project? Credit / Tag me on your project Twitter #StephenHackers

Any use of this code is at your own risk. Remember bulk automation jobs require the right resources to be available.

This project & code was based on :

https://communities.vmware.com/thread/315193

Which progressed to : https://communities.vmware.com/thread/436734

Part 1 / Part 2