In our customer environment, we use templates for VM deployments and sometimes leverage VMware PowerCLI to automate the creation of multiple VMs at once.
This PowerShell script is tailored to our needs.
It connects to vCenter and deploys several VMs from a template with consistent settings:
- Applies a Windows Server OS customization spec
- Places VMs in the Production cluster, under the specific folder
- Uses the metioned datastore cluster
- Connects each VM to a specific distributed port group
- Sets each VM to same CPU and RAM config
The script is designed to work especially well with VMs that have similar names with numbers increasing in order (like 01, 02, 03, 04). It generates VM names such as prod-vm01 to prod-vm04 using a simple number range, so you can easily scale the deployment by changing the range.
The PowerCLI Script:
Get-Module -ListAvailable VMware* | Import-Module
Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false # if needed
#Add-PSSnapin vmware.vimautomation.core -ErrorAction SilentlyContinue
Import-Module -Name VMware.VimAutomation.Core -ErrorAction SilentlyContinue
Set-PowerCLIConfiguration -ProxyPolicy NoProxy -DefaultVIServerMode multiple -Scope User -InvalidCertificateAction ignore -Confirm:$false | out-null
# --- vCenter connection ---
$vc = "vCenter-name" #TODO
Connect-VIServer $vc
$template = Get-Template -Name "template-name" #TODO
$spec = Get-OSCustomizationSpec -Name "OS-customization-name" #TODO
$cluster = Get-Cluster -Name "Cluster-name" #TODO
$folder = Get-Folder -Name "Folder1" -Type VM | #TODO
Get-Folder -Name "Folder2" #| #TODO
#Get-Folder -Name "Folder3" #TODO
$dsCluster = Get-DatastoreCluster -Name "Datastore-cluster" #TODO
$pg = Get-VDPortgroup -Name "vDS-PG" #TODO
$names = 01..02 | ForEach-Object { "server-name{0:d2}" -f $_ } #TODO replace server-name
foreach($name in $names){
$vm = New-VM `
-Name $name `
-Template $template `
-ResourcePool ($cluster | Get-ResourcePool -Name "Resource-pool") ` #TODO replace resource-pool
-Datastore $dsCluster `
-Location $folder `
-OSCustomizationSpec $spec
# CPU/RAM
Set-VM -VM $vm -NumCpu X -MemoryGB Y -Confirm:$false | Out-Null #TODO replace X and Y
# Network (distributed port group)
Get-NetworkAdapter -VM $vm |
Set-NetworkAdapter `
-NetworkName $pg.Name `
-StartConnected:$true `
-Confirm:$false
<#
# Extra data disk (100GB)
New-HardDisk `
-VM $vm `
-CapacityGB 100 `
-Datastore $dsCluster `
-StorageFormat Thin | Out-Null
#>
}
Disconnect-VIServer -Confirm:$false
Feel free to customize this script based on your specific reporting requirements and share your experiences or improvements in the comments below.
It should be noted that the script is not entirely authored by me; certain information and code snippets are sourced from various places, including blogs, GitHub repositories, and community forums.