VMware: Deploy multiple VM’s from template with PowerCLI
Last week I was working on a new project, they asked me to install 5 new fileservers based on Windows 2008R2, I installed a new VM and converted it to a template, next I configured a template in “Customization Specifications Manager” with the following details:
Customization template:
Registration information: name company
Computer name: Use the virtual machine name (important)
Product key: Didn’t need it because I’ve configured KMS
Password: Company default local administrator password, selected: Automatically login as the Administrator: 2
Timezone: GMT+0100 (Amsterdam)
Runonce: none
Network: Typical settings
Workgroup or Domain: selected to auto join the domain with domain administrator credentials + domain name (important)
Operation System Options: Selected: Generate New Security ID (SID)
VM template settings:
Hard disk: 40 GB with only OS configured with company standard policy
VMware tools: Latest, this must be installed for Specification Template and NIC
Network: VMXNET3 (needed VMware Tools for driver)
Script: (saved as: FileserverDeploy.ps1)
-vmhost = Target host;
-Name = Name of new VM;
-Template: From wich template you want to deploy the new VM;
-Datastore: Target datastore to place the new VM;
-OSCustomizationspec = Wich “prep” template you want to deploy the new VM;
New-vm -vmhost esx04.vmpros.local -Name FS-SVR01 -Template WIN2008R2_Template -Datastore datastore2 -OSCustomizationspec WIN2008R2_Template New-vm -vmhost esx04.vmpros.local -Name FS-SVR02 -Template WIN2008R2_Template -Datastore datastore2 -OSCustomizationspec WIN2008R2_Template New-vm -vmhost esx04.vmpros.local -Name FS-SVR03 -Template WIN2008R2_Template -Datastore datastore2 -OSCustomizationspec WIN2008R2_Template New-vm -vmhost esx04.vmpros.local -Name FS-SVR04 -Template WIN2008R2_Template -Datastore datastore2 -OSCustomizationspec WIN2008R2_Template New-vm -vmhost esx04.vmpros.local -Name FS-SVR05 -Template WIN2008R2_Template -Datastore datastore2 -OSCustomizationspec WIN2008R2_Template
PowerCLI:
Running the script:
Final result:
The 5 fileservers deployed from template and joined the domain.. great!
You might also consider using some of the great features of PowerShell to make this even nicer:
1..5 | Foreach {
New-vm -vmhost esx04.vmpros.local -Name FS-SVR$_ -Template WIN2008R2_Template -Datastore datastore2 -OSCustomizationspec WIN2008R2_Template
}
@Alan Renouf
Cool, thanks Alan! Much easier!
Great this helped me alot
i like it VMware: Deploy multiple VM’s from template with PowerCLI | VMpros now im your rss reader
I have a task to deploy multiple VMs with sequential naming convention, in multiple ESX servers which will use same template but different datastore. can you help with powercli script for same? Thanks! Vinod@Alan Renouf
Anyway to deploy with static IPs? IE add the IP address to the .ps1 file?
Thanks for the tips here. Anybody know how to automatically set the datastore to the one with the most free space?
# Notes: deploy.txt format is as follows,
# serverA
# serverB
# serverC
# serverETC
#
##################################################################################################################################################
#
# Define Variables
$strNewVMName = Get-content “c:\ps\deploy.txt”
$strTemplate = “TEMPLATE NAME”
$strDestinationHost = “HOST NAME”
$strCustomSpec = “CUSTOMIZATION SPEC MANAGER ANSWER FILE”
$strDatastore = “Datastore Name”
#
#For each loop will increment for every string contained with in deploy.txt
Foreach ($strServer in $strServers)
#
# The command below will create the new VM using the name from deploy.txt using the template defined in $strTemplate
# to the host defined in $strDestinationHost using the thin storage format and the customization template defined in $strCustomSpec.
{
New-VM -Name $strNewVMName -Template $(get-template $strTemplate) -VMHost $(Get-VMHost $strDestinationHost) -Datastore $(Get-Datastore $strDatastore) -DiskStorageFormat Thin -OSCustomizationSpec $(Get-OSCustomizationSpec $strCustomSpec)
}
Thanks for this help
one more questions – is there a possibility to change the virtual hardware during the deployment from the template.
there is the option in the GUI -> Edit virtual hardwarae (Experimental)
Does anyone know this?
Thanks a lot
Many thanks. I was using Google to seach how to deploy multiple VM’s, then I am here. Really useful.
Thank you all for the post. This is very handy for creating several VMs.
I have a question, I would like to have 100+ servers created using the same vm template, yet I would like it to assign the server and IP from a csv file. Is the possible?
something like Server-xyz, IP 192.168.1.xxx….. Server-abc, IP 10.123.5.xxx
Thank you for any ideas.
Tom
Hi,
First of all thanks for the script, your script works like a charm. one question, if I configure script to create 10 vpc , script starts to deploy 10 vpc together, is it possible to create 3 vPC at a time and other will be in queue, once first 3 is done, new 3 vPC will start for deployment, like wise it will go.
May be we can start with 1 vpc at a time.
I believe some body must have already done this.
Regards
Gurjit Dhillon
I am getting following error while executing the above script.
=========
New-VM : Cannot convert ‘System.Object[]’ to the type ‘System.String’ required
by parameter ‘Name’. Specified method is not supported.
At C:\Users\Administrator\Desktop\scripts\deploy.ps1:8 char:13
+ New-VM -Name <<<< $strNewVMName -Template $(get-template $strTemplate) -VMHo
st $(Get-VMHost $strDestinationHost) -Datastore $(Get-Datastore $strDatastore)
-DiskStorageFormat Thin -OSCustomizationSpec $(Get-OSCustomizationSpec $strCust
omSpec)
===========
Hi Swapnil,
try below script.
# Define Variables
$NameVM =”vmtest00″
$strTemplate = “vPC template Win7 BNL 3.0.b5”
$strDestinationHost = “vmnlutr01-host02.capgemini.nl”
$strCustomSpec = “vPC Vista-Win7 customization”
$strDatastore = “UTR-VPC-pool09”
$strLocation = “vPCs BPO”
$strPool = “vPCs UTR”
# Mention number of VM to create
$HOW_MANY_TO_CREATE=2
$Date=get-date -uformat “%Y%m%d”
$NumArray = (1..$HOW_MANY_TO_CREATE)
#$NumArray = $HOW_MANY_TO_CREATE
for ([int]$seq=1;$seq -le $HOW_MANY_TO_CREATE;$seq++)
{$string = $NameVM + ($seq.tostring(“0##”)) #orginale
“Creating $string”
New-VM -Name $string -Template $(get-template $strTemplate) -location (get-folder $strLocation) -pool (get-resourcepool $strPool) -VMHost $(Get-VMHost $strDestinationHost) -Datastore $(Get-Datastore $strDatastore) -OSCustomizationSpec $(Get-OSCustomizationSpec $strCustomSpec) | Start-VM -RunAsync
}
Hi,
But I want to keep server list file separately and just put server names over there instead of in the script…Please assist.
hi, superb man
we have same kind of work in our organization to deploy multiple vms from Template. from one temp to 24 vms, which kind of precautions we have to take.
the thing is i have bit knowledge on powercli and i dont which tool to develop scripts of powercli.
what is this and how to use this ”-OSCustomizationspec WIN2008R2_Template”
does this script automatically install the OSs on the VMs? where there’s no need to manually go install the os on each VM??
coz now i have a script which can automatically create ‘n’ VMs and link the iso image to them all….but i have to go and install the OS on each:(
plzz help with a script to execute the above query!thanks
Did you ever get the script to accomplish deployemnt to the datastore with the most available space? I have the same type of requirement in my environment. Thanks for your help!
BrentG
@Brent
@bgonzales
Here is how I get a datastore with enough space. I probably can’t help debug this if you run in to errors but thought I’d share:
# Create new properties for Datastore calculations
New-VIProperty -Name UsedGB -ObjectType Datastore `
-Value {
param($ds)
[Math]::Round(($ds.ExtensionData.Summary.Capacity – $ds.ExtensionData.Summary.FreeSpace)/1GB,1)
} `
-BasedONextensionProperty ‘Summary’ `
-Force
New-VIProperty -Name ProvisionedGB -ObjectType Datastore `
-Value {
param($ds)
[Math]::Round(($ds.ExtensionData.Summary.Capacity – $ds.ExtensionData.Summary.FreeSpace + $ds.ExtensionData.Summary.Uncommitted)/1GB,1)
} `
-BasedONextensionProperty ‘Summary’ `
-Force
# Get datastore like a particular name (win*)and where used and provisioned are within our acceptable range
# Selects the first one it finds
$Datastore = Get-Datastore -VMHost $VMHost | where {$_.Name -like “*win*”} |
where-object {($_.UsedGB) -le 710 -and $_.ProvisionedGB -le 1360}|
Select-Object -first 1
@bvi1998
bvi1998 :
@bgonzales
Here is how I get a datastore with enough space. I probably can’t help debug this if you run in to errors but thought I’d share:
(edited the post to add where I the vmhost)
#Get an ESX host at random to find datastores
$VMHost = Get-Cluster $ClusterName |Get-VMHost | Get-Random
# Create new properties for Datastore calculations
New-VIProperty -Name UsedGB -ObjectType Datastore `-Value {param($ds)
[Math]::Round(($ds.ExtensionData.Summary.Capacity – $ds.ExtensionData.Summary.FreeSpace)/1GB,1)} `-BasedONextensionProperty ‘Summary’ `-Force
New-VIProperty -Name ProvisionedGB -ObjectType Datastore `-Value {param($ds)
[Math]::Round(($ds.ExtensionData.Summary.Capacity – $ds.ExtensionData.Summary.FreeSpace + $ds.ExtensionData.Summary.Uncommitted)/1GB,1)} `-BasedONextensionProperty ‘Summary’ `-Force
# Get datastore like a particular name (win*)and where used and provisioned are within our acceptable range
# Selects the first one it finds
$Datastore = Get-Datastore -VMHost $VMHost | where {$_.Name -like “*win*”} |where-object {($_.UsedGB) -le 710 -and $_.ProvisionedGB -le 1360}|Select-Object -first 1
@Tom Casull
Get-OSCustomizationSpec Spec | Get-OSCustomizationNicMapping | Set-OSCustomizationNicMapping -IpMode UseStaticIp -IpAddress 10.10.0.1 -SubnetMask 255.255.255.0 -DefaultGateway 10.10.0.1 -AlternateGateway 10.10.0.1 -Dns 10.10.150.1 -PrimaryWins 10.10.150.2
@santhosh pani
Current “** Create Win XP **”;
$freespaceCalc = @{ Name = “FreespaceGB”; Expression = { Re: PowerCLI script to deploy vm’s from a template::Round($_.FreeSpaceMB * 1MB / 1GB ) } }
$capacityCalc = @{ Name = “CapacityGB”; Expression = { Re: PowerCLI script to deploy vm’s from a template::Round($_.CapacityMB * 1MB / 1GB) } }
User enters how manny agents are requred
$agentTotal = Re: PowerCLI script to deploy vm’s from a template(Read-Host “Enter how many WinXp Agents you need.”)
$totalXPCount = (Get-VM -Name WinXP-* | Measure-Object).Count
if($totalXPCount -lt $agentTotal){
Add missing XP guests
for($adt = $totalXPCount + 1; $adt -le $agentTotal; $adt++){
Execute the New-Vm part
}
}
Get-Datastore | Select Name, $freespaceCalc, $capacityCalc |Sort-Object Name | ft -Force -AutoSize| Out-Default
$datastore = Read-Host “What DataStore do you want to use?”
$hostList = Get-VmHost | select Name | Sort-Object
$i = 1
$hostList | %{Write-Host $i “:” $_.Name; $i++}
$hostIndex = Read-Host “Enter a number (1 -” $hostList.Count “)”
Write-Host “You selected host” $hostIndex “with hostname” $hostList[$hostIndex – 1].Name
$XP = Get-VM -Name WinXP-*
$totalXPCount = @($XP).Length
$totalXP = ($totalXPCount + 1)
for($adt = ($totalXP + $agentTotal);$totalXP -lt $adt; $totalXP++){
if($totalXPCount -eq $adt)
{
break
}
$machineName = “WinXP-$totalXPCount”
$template = “XP-32 Template”
$osspec = Get-OSCustomizationSpec $XP
foreach ($vm in $machineName)
{$vm = New-VM -Name $machineName -Template $template -Host $hostIndex -Datastore $datastore -OSCustomizationSpec $osspec |start-vm }
}
Disconnect-VIServer -Server $DefaultVIServer -Confirm:$false
Hi,
I need to deploy 150 VMs from a template. We use Spreadsheet to pass the inputs for deploying VMs.
It would be huge input the 150 rows of data into the spreadsheet and looks messy.
Kindly help in optimizing the same. Let me know if there is an easy way to input the details to the script?.
Thanks in advance.
@Tom Casull
Hello Tom, have you found a solution? I am also facing the same problem…please let me know if it’s possible. Thank you!
#############################################################
# David Mitchell 2014/06/04
# Script to deploy VM(s) from Template(s) and set appropriate
# IP config for Windows VMs. Also sets # of CPUs, MemoryMB,
# port group.
# Moves deployed VM to specific VMs/Template blue folder.
# Assumptions:
# connected to viserver before running
# Customization spec and templates in place and tested
#############################################################
# Syntax and sample for CSV File:
# template,datastore,diskformat,vmhost,custspec,vmname,ipaddress,subnet,gateway,pdns,sdns,pwins,swins,datacenter,folder,stdpg,memsize,cpucount
# template.2008ent64R2sp1,DS1,thick,host1.domain.com,2008r2CustSpec,Guest1,10.50.35.10,255.255.255.0,10.50.35.1,10.10.0.50,10.10.0.51,10.10.0.50,10.10.0.51,DCName,FldrNm,stdpg.10.APP1,2048,1
#
$vmlist = Import-CSV “E:\DeployVMServers.csv”
# Load PowerCLI
$psSnapInName = “VMware.VimAutomation.Core”
if (-not (Get-PSSnapin -Name $psSnapInName -ErrorAction SilentlyContinue))
{
# Exit if the PowerCLI snapin can’t be loaded
Add-PSSnapin -Name $psSnapInName -ErrorAction Stop
}
connect-viserver ESX.yourdomain.local
foreach ($item in $vmlist) {
# Map variables
$template = $item.template
$datastore = $item.datastore
$diskformat = $item.diskformat
$vmhost = $item.vmhost
$custspec = $item.custspec
$vmname = $item.vmname
$ipaddr = $item.ipaddress
$subnet = $item.subnet
$gateway = $item.gateway
$pdns = $item.pdns
$sdns = $item.sdns
$datacenter = $item.datacenter
$destfolder = $item.folder
$stdpg = $item.stdpg
$memsize = $item.memsize
$cpucount = $item.cpucount
#Configure the Customization Spec info
Get-OSCustomizationSpec $custspec | Get-OSCustomizationNicMapping | Set-OSCustomizationNicMapping -IpMode UseStaticIp -IpAddress $ipaddr -SubnetMask $subnet -DefaultGateway $gateway -Dns $pdns,$sdns
#Deploy the VM based on the template with the adjusted Customization Specification
New-VM -Name $vmname -Template $template -Datastore $datastore -DiskStorageFormat $diskformat -VMHost $vmhost | Set-VM -OSCustomizationSpec $custspec -Confirm:$false
#Move VM to Application Group’s folder
Get-vm -Name $vmname | move-vm -Destination $(Get-Folder -Name $DestFolder -Location $(Get-Datacenter $Datacenter))
#Set the Port Group Network Name (Match PortGroup names with the VLAN name)
Get-VM -Name $vmname | Get-NetworkAdapter | Set-NetworkAdapter -NetworkName $stdpg -Confirm:$false
#Set the number of CPUs and MB of RAM
Get-VM -Name $vmname | Set-VM -MemoryMB $memsize -NumCpu $cpucount -Confirm:$false
}
Disconnect-VIServer ESX.yourdomain.local
Hi,
Thanks for the details. I have a scenario to load more than 500 VM. So i have cloned a real VM and formed a template and used it to multiply via the above script. But the VM which i cloned consumes 5 GB. DO we have any template which will have less than 2 GB. I also need OS to be installed in the VM’s. Just what to check if there are any OS which i can use which consumes less disk space.
Thanks
Vettri
@Vettriselvan you should probably look at something like DSL (Damn Small Linux – http://www.damnsmalllinux.org/) as the OS of choice here.
I am assuming that you’re just testing mass deployments?
@David Mitchell
How do you run that E:\DeployVMServers.csv, and is the script PS1 format?
Hi Everyone,
Looking for script which can create multiple vms using template and use oscustomization from Vcenter and take IP address and name of the VMS