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