A few weeks ago I decided I wanted to start automating a bit more of the provisioning I did for my test beds. One of the main requirements I had was to reduce the amount of interaction that was involved from me to spin up a set number of hosts. I didn’t necessarily care how long it took (within reason) but wanted to tell something to generate me a certain number of hosts and take care of as much as possible.
The following script accomplishes most of what I wanted to and in full disclosure I am no where near a PowerShell expert and relied a lot on the community to figure out how to do many of the things in this script. If you have suggestions for improvement please do send them along! There is very little error checking currently in the script as it stands today.
For starters there is quite a bit of input required ahead of time as the script will help do many things for you. For starters, it assumes you have a nested vSphere template available which has been prepared to be used for cloning. See here for further details on doing so.
Secondly it assumes you will input all kinds of VMware parameters including cluster names, prefixes, IP subnets, etc. This is because it will take that template and create clones for you, create a DHCP reservation, add DNS records, and then join these new hosts to a specified datacenter and cluster, enabling HA and DRS in the process. Anything else I’m accomplishing through host profiles at this point but look to continue to improve upon this script in the near future.
Check it out below
#Specify vCenter Credentials
$vCenter=”vCENTER NAME HERE “
$vCenterUser=”vCENTER USER HERE“
$vCenterUserPassword=”vCENTER PW HERE“
# Specify vSphere Host Credentials
$root_user = "root"
$root_pw = "PW HERE"
$template = “TEMPLATE NAME HERE“ # Specify the VM you want to clone
$ds = “DATSTORE NAME HERE“ # Specify the datastore got placement
$Folder = “vCENTER FOLDER HERE“ #vCenter Folder location
$datacenter_name = "DC HERE" #vCenter Datacenter Name
$cluster_name = "CLUSTER For NESTED Hosts" #vCenter Cluster Name for Nested
$cluster = "CLUSTER TO PLACE VMs IN" #vCenter Cluster where VMs Reside
$VM_prefix = “vvSphere-“ #Virtual Machine Prefix
$dhcp_server = "DHCP Server Name Here" # DHCP Server
$scope_id = "DHCP Scope Here" #DHCP Scope ID
$vm_count = read-host ‘How many clones do you want to create?’ # Ask User Number of VMs to Create
#__________ end of user defined input__________
Connect-viserver $vCenter -user $vCenterUser -password $vCenterUserPassword -WarningAction 0
#For each VM create a clone based on template
1..$vm_count | foreach {
$y=”{0:D2}” -f $_
$VM_name= $VM_prefix + $y
$ESXi=Get-Cluster $Cluster | Get-VMHost -state connected | Get-Random
write-host “Creation of VM $VM_name initiated” -foreground green
New-VM -Name $VM_Name -template $template -VMHost $ESXi -Datastore $ds -Location $Folder -runasync
}
#insert wait here for 5 minutes or make sequential/sync operations
start-sleep 150
1..$vm_count | foreach {
$y=”{0:D2}” -f $_
$VM_name= $VM_prefix + $y
$vm = get-vm -name $VM_Name
start-vm -vm $vm #Start VMs
$mac_address= $VM.networkadapters[0].macaddress -replace ":", "-"
$freeip = Get-DhcpServerv4FreeIPAddress -ComputerName $dhcp_server -ScopeId $scope_id
start-sleep 15
Add-DhcpServerv4Reservation -ComputerName $dhcp_server -reservationname $vm -ScopeId $scope_id -IPAddress $freeip -ClientId $mac_address -Description "Reservation for $VM_Name"
start-sleep 15
add-DnsServerResourceRecordA -Name $vm -ZoneName corp.local -IPv4Address $freeip -ComputerName $dhcp_server
start-sleep 15
#get last octet of IP and set to name for DNS PTR
$freeip_split = $freeip.split(‘.’)
$freeip = $freeip_split[3]
Add-DnsServerResourceRecordPtr -Name $freeip -ZoneName "157.24.10.in-addr.arpa" -PtrDomainName "$vm.corp.local" -ComputerName $dhcp_server
}
# Create new Datacenter if it doesn’t already exist
If (-Not ($NewDatacenter = Get-Datacenter $datacenter_name -ErrorAction SilentlyContinue))
{
Write-Host "Adding $datacenter_name"
$NewDatacenter = New-Datacenter -Name $datacenter_name -Location (Get-Folder Datacenters)
}
# Create cluster if it doesn’t already exist
if (-Not ($NewCluster = Get-Cluster $cluster_name -ErrorAction SilentlyContinue))
{
Write-Host "Adding $cluster_name"
New-Cluster -Name $cluster_name -Location $datacenter_name
start-sleep -s 15
}
1..$vm_count | foreach
{
$y=”{0:D2}” -f $_
$VM_name= $VM_prefix + $y
$vm = get-vm -name $VM_Name
$vm = "$vm" + ".corp.local"
Add-VMHost -Name $vm -Location $cluster_name -User $root_user -Password $root_pw -Force
Start-Sleep 90
#Create new datastore. Note my templates assume a 10 GB store for the local datastore. Other sizes are used for nested VSAN in my environment.
$datastore_path = get-scsilun -vmhost $vm |where CapacityGB -EQ 10
new-datastore -vmhost $vm -name $vm -path $datastore_path.canonicalname -vmfs -filesystemversion 5
}
set-cluster -cluster $cluster_name -DRSEnabled:$true -DRSautomationlevel FullyAutomated -haenabled:$true -confirm:$false