Lets face it, repetition sucks. When provisioning ESX hosts, using such things as the EDA make life easier, but it only does so much for ESXi.

The install for ESXi is simple and straight forward, but when done, you have to go and set everything else (IP, hostname, DNS, local users, etc…). Doing this for 20 hosts could be a PITA (Pain In The A..), so I set out on writing a script that does all of this for you.

All you have to do is set the IP & root password, then verify you can ping the host by it’s hostname (set host/A record in DNS). Once that’s verified, here’s what the script does for you:

  • Creates an Admins group and assigns it to the Administrator role
  • Creates local users, sets their default password, and adds them to the Admins group
  • Sets primary & secondary NTP & DNS servers
  • Sets DNS search suffix
  • Combines the provided hostname with DNS search suffix to populate the hostname FQDN
  • Sets EnableNaviReg to 0, disabled (requested by my storage team)
  • Disables iSCSI (disabled by default, but enabled in my sd image I created from previous post, thus the need to disable)
  • Disabled Tech Support Mode, aka ‘unsupported’ console

This is a slightly more advanced script, and it’s not fully polished, but works.

param([string[]]$vmhosts = $null, [string[]]$vmusers = $null)
#add the snapin, just in case
Add-PSSnapin VMware.VimAutomation.Core
#instantiate script variable, needed in multiple functions
set-variable -name pw1 -scope script
function usage()
write-host -foregroundcolor green `n`t "This script configures NTP, local users & their password, disables NaviReg, iSCSI, & Tech Support Mode, then reboots"
write-host -foregroundcolor green `n`t "-vmhosts and -vmusers are the available parameters, and the usage is below:"
write-host -foregroundcolor yellow `n`t`t "Set-Config.ps1 -vmhosts (`"server1`",`"server2`") -vmusers (`"user1`",`"user2`")"
write-host -foregroundcolor red `n`t "DO NOT fully qualify the host name, the script sets that based off the DNS Search Suffix."
write-host -foregroundcolor green `n`t "For a single vmhost or vmuser, here's the usage:"
write-host -foregroundcolor yellow `n`t`t "Set-Config.ps1 -vmhosts server -vmusers user"
write-host -foregroundcolor green `n`t "This script sets the username and display name, or description, the same"
write-host -foregroundcolor green `n`t "You may get an error if Admins and/or the user already exists"
write-host -foregroundcolor green `n`t "If the user exists it is still added to the Admins group" `n
function getPassword()
$script:pw1 = read-host -assecurestring `n "Enter default password"
$pw2 = read-host -assecurestring `n "Re-Enter default password"
$String1 = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($script:pw1)
$String2 = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pw2)
$script:pw1 = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($String1)
$pw2 = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($String2)
$match = $script:pw1.CompareTo($pw2)
if ($match -ne 0)
    write-host -foregroundcolor red `n "Passwords do not match!" `n
function Confirm($strMessage)
write-host -foregroundcolor yellow `n $strMessage
$answer = $host.ui.rawui.readkey("NoEcho,IncludeKeyUp")
if ($answer.Character -ine "y")
    write ""
write ""
function config()
$ntp1 = (read-host `n "Enter the name of the first NTP server").tolower()
$ntp2 = (read-host `n "Enter the name of the second NTP server").tolower()
$dns1 = (read-host `n "Enter the primary DNS server").tolower()
$dns2 = (read-host `n "Enter the alternate DNS server").tolower()
write-host -foregroundcolor green `n`t "DNS Search Suffix is used to create the FQDN of the host"
$dnsSearch = (read-host `n "Enter DNS search suffix, ie sub.domain.com").tolower()
write-host -foregroundcolor yellow `n`t "Primary NTP:" $ntp1
write-host -foregroundcolor yellow `n`t "Secondary NTP:" $ntp2
write-host -foregroundcolor yellow `n`t "Primary DNS:" $dns1
write-host -foregroundcolor yellow `n`t "Secondary DNS:" $dns2
write-host -foregroundcolor yellow `n`t "DNS Search & FQDN Suffix:" $dnsSearch
Confirm("Press 'Y' to continue, or any other key to exit...")
$creds = get-credential
foreach ($vmhost in $vmhosts)
    $vmhostfqdn = $vmhost.ToString() + "." + $dnsSearch.ToString()
	write `n "Connecting to" $vmhostfqdn
	connect-viserver $vmhost -credential $creds
	write `n "Setting up NTP servers"
	add-vmhostntpserver -ntpserver $ntp1,$ntp2
	write `n "Adding DNS, Hostname, & Search Order"
	$vmhostnetwork = get-vmhostnetwork -vmhost $vmhost
	set-vmhostnetwork -network $vmhostnetwork -dnsaddress $dns1,$dns2 -DomainName $dnsSearch -searchdomain $dnsSearch -HostName $vmhost
	write `n "Now adding users to admin group"
    	New-VMHostAccount -group Admins
	foreach ($vmuser in $vmusers)
		New-VMHostAccount -User -Id $vmuser -Password $script:pw1 -Description $vmuser
		set-vmhostaccount -user $vmuser -AssignGroups localadmin,users,Admins
    	#add Admins to admin role
	$AuthMgr = Get-View (Get-View ServiceInstance).Content.AuthorizationManager
    	$Entity = Get-Folder ha-folder-root | Get-View
   	$Perm = New-Object VMware.Vim.Permission
    	$Perm.entity = $Entity.MoRef
    	$Perm.group = $true
    	$Perm.principal = "Admins"
    	$Perm.propagate = $true
    	$Perm.roleId = ($AuthMgr.RoleList | where {$_.Name -eq "Admin"}).RoleId
	#Set EnableNaviReg to 0
    	set-vmhostadvancedconfiguration -vmhost $vmhost -name Disk.EnableNaviReg -value 0
	#disable iSCSI
	$hostView = Get-View -VIObject (Get-vmhost $vmhost)
	$storageSystem = Get-View $hostView.configManager.storageSystem
	#disable 'unsupported' Tech Support Mode
	set-vmhostadvancedconfiguration -vmhost $vmhost -name VMkernel.Boot.techSupportMode -value False
	#restart for settings
	restart-vmhost $vmhost -runasync -confirm:$false -force
	Disconnect-VIServer -confirm:$false
#garbage collection, just in case
Function collectGarbage()
$creds = $null
$script:pw1 = $null
$pw2 = $null
$string1 = $null
$string2 = $null
$ntp1 = $null
$ntp2 = $null
$dns1 = $null
$dns2 = $null
$dnsSearch = $null
$vmhosts = $null
$vmusers = $null
if (($vmhosts -eq $null) -or ($vmusers -eq $null))
#Lets run the config now after setting up all the functions

To run this script, save it as Set-Config.ps1, and run:

.\Set-Config.ps1 -vmhosts ("host1","host2","host3") -vmusers ("user1","user2")


.\Set-Config.ps1 -vmhosts host -vmusers user

Should you want to not disable EnableNaviReg, simply add at # in front of that line, same with Tech Support Mode or iSCSI.

Since Tech Support Mode is ‘unsupported’ by VMware, I disable it so we don’t rely on it. If something needs to be ‘fixed’, we need to find a supported way to get that done. So far, our biggest hurdle was lack of CNA drivers for our hosts that ONLY use the CNA’s to connect, but using a host connected through the LOM, we were able to inject the drivers just fine.

I also wanted to enable lockdown mode via this script, but it’s not currently available.

I imagine you could use this to config ESX as well, and add such things as adding users to sudoers, but our plan is to move to ESXi only, so I haven’t tested it with full ESX.

**UPDATED 03-26-2012**
I’ve test this with ESXi 5.0 and it works. Some of the commands are older and PowerCLI will bark at you for them, but they still work. I’ll update for 5.0 and repost when I have time.