Last year I was asked to reduce the time spend on installing and configuring our ESX hosts. Because we weren’t using Enterprise Plus licenses, we didn’t have Host Profiles.
I came up with a simple two-step process based on the EDA appliance and a custom PowerShell script.
- Install the host from PXE.
Only setting the minimum configuration, so it’s as versatile as possible.
- Disk layout
- Network teaming
- FQDN and IP
- Configure the host using a custom PowerShell script.
Based on the Datacenter and Cluster the host is to be added to.
- Add to vCenter
- Set COS memory
- Enable VMotion
- License host
- And much more…
A lot of blog posts are available on the net, on how to setup and install an ESX host using the EDA appliance so I won’t trouble you with this.
The PowerShell script is divided into several sections, I won’t explain everyone, only the most relevant, the rest is documented in the full script.
All steps in the script are logged to a host specific log file.
- User input – Only 3 things are asked for when running the script, the rest is stored in the scripts Static section.
- FQDN of the host (must be configured in DNS to work)
- The environment – what environment is the host to be placed in, like PROD, DMZ, etc.
- The hosts VMotion IP.
- Add the host to the right cluster.
You must have get the Datacenter/Cluster variable prior to adding the host, else it will just be placed in the first datacenter (See script for more info).
add-vmhost $strHost -location $strvCenterDatacenter -user $strHostUser -password $strHostUserPWD -force: $true
- Set the host in maintenance mode
Get-VMHost -Name $strHost | Set-VMHost -State maintenance
- License host.
As you can see below, you have to supply the full name of the license you are adding, not just the license key.
$targethostMoRef = (get-VMHost $strHost | get-view).MoRef
$si = Get-View ServiceInstance
$LicManRef=$si.Content.LicenseManager
$LicManView=Get-View $LicManRef
$licassman = (Get-View $LicManView.LicenseAssignmentManager)
#$licassman.UpdateAssignedLicense($targethostMoRef.value,”YOUR LIC KEY”,”vSphere4 Enterprise Plus (1-12 cores per CPU”)
$licassman.UpdateAssignedLicense($targethostMoRef.value,”YOUR LIC KEY”,”vSphere4 Enterprise (1-6 cores per CPU”)
- Set the correct time zone.
$strTimeZone = "Europe/Copenhagen"
$tmpHost = Get-VMHost $strHost | get-view
$tmpDTSystem = $tmpHost.ConfigManager.DateTimeSystem
$tmpMoRef = Get-View $tmpDTSystem
$tmpDateConfig = New-Object Vmware.Vim.HostDateTimeConfig
$tmpDateConfig.timeZone = $strTimeZone
$tmpMoRef.updateDateTimeConfig($tmpDateConfig)
- Add NTP servers.
Use an array of NTP servers like
$arrNTPServer = @(“dk.pool.ntp.org”,”de.pool.ntp.org”,”us.pool.ntp.org”,”clock.cimat.ues.edu.sv”,”ntp1.gbg.netnod.se”,”ntp1.theremailer.net”)
Add-VMHostNtpServer -VMHost $strHost -NtpServer $arrNTPServer -Confirm:$false
If you want you can restart the NTP service – only do it if you don’t plan on restarting the host after configuring.
Restart-VMHostService $ntpd -Confirm:$false
- Open firewall rules
I always open the following firewall rules so that NTP and the SSH is working
Get-VmhostFirewallException -VMHost $strHost -Name "NTP Client" | Set-VMHostFirewallException -enabled:$true
Get-VmhostFirewallException -VMHost $strHost -Name "SSH Client" | Set-VMHostFirewallException -enabled:$true
[/powershel]</li>
<li>Set the correct DNS servers
Use an array of DNS servers, this way you can add multiple DNS servers at once.
@("10.10.10.40","10.10.10.30") or @("10.10.10.40")
$strHost = @("10.10.10.40","10.10.10.30")
Get-VMHost -Name $strHost | Get-View | %{$tmpNS = Get-View -Id $_.configManager.networkSystem
$tmpDNS = $tmpNS.NetworkConfig.DnsConfig
$tmpDNS.domainName = $strHostDomain
$tmpDNS.address = $arrDNSsrv
$tmpDNS.searchDomain = $strSearchDomain
$tmpNS.updateDnsConfig($tmpDNS)}
- Configuring network, adding network including VMotion.
See the script for the full script.
$vSwitch = Get-VirtualSwitch $strHost -Name vSwitch0
#Set-VirtualSwitch -VirtualSwitch $vSwitch -Nic vmnic1
New-VirtualPortGroup -VirtualSwitch $vSwitch -Name "VMOTION" -VLanId 0
New-VMHostNetworkAdapter -VMHost $strHost -PortGroup "VMOTION" -VirtualSwitch $vSwitch -IP $strVMotion -SubnetMask $strSubnetMask -VMotionEnabled $true
$strNetConfig = Get-View (Get-VMHost $strHost | Get-View).ConfigManager.NetworkSystem
$strIPRoute = New-Object VMware.Vim.HostIpRouteConfig
$strIPRoute.defaultGateway = $strGateway
$strNetConfig.UpdateIpRouteConfig($strIPRoute)
New-VirtualPortGroup -VirtualSwitch $vSwitch -Name "PROD" -VLanId 200
New-VirtualPortGroup -VirtualSwitch $vSwitch -Name "PXE" -VLanId 0
If needed you can remove the default VM network
$vSwitch = Get-VirtualSwitch $strHost -Name vSwitch0
$vmnetwork = Get-VirtualPortGroup -VirtualSwitch $vSwitch -Name "VM Network"
Remove-VirtualPortGroup -VirtualPortGroup $vmnetwork -Confirm:$false}
- Reboot the host J
Get-VMHost -Name $strHost | %{Get-View $_.ID} | %{$_.RebootHost_Task($TRUE)}
- If you want your script to wait for the host to be rebooted before continuing, you can do it with these two loops.
do{
$result = Get-VMHost $strHost
Start-Sleep 10 # Wait 10 sec
}
Until($result.State -ne "Maintenance")
# Maintenance - because host entered Maintenence mode earlier
do{
$result = Get-VMHost $strHost
Start-Sleep 10 # Wait 10 sec
}
Until($result.State -eq "Maintenance")
- Finally exit the host from maintenance mode.
Get-VMHost -Name $strHost | Set-VMHost -State connected
If everything is configured correctly, DRS should start migrating VM’s to the newly added host.
This script helped reducing the time spend on installing and configuring a host from 90 minutes to about 18 minutes. That’s a reduction of more than 500%, time you can use on other cool PowerShell tasks. J
By using a script to customize our hosts, we also gained two other benefits.
- Compliance – a host is always installed and configured the exact same way each time.
- Each step is documented in a host specific log file.
The full script can be downloaded here.