Hi, and welcome to my first post.
In the last couple of months I have doing lots of POCs (Proof Of Concepts) about VMware Cloud Foundation (VCF onwards) and every time I reinstalled the hosts to show the Bring Up process (that will be covered in another post) I was spending a lot of time, approximately 10 minutes per host between login, page navigation and configuration, to get a host ready to be used by the Cloud Builder VM.
Because of that, I have developed a script to speedup the process and minimizing the human error of having a configuration mismatchs between hosts.
The Cloud Builber VM requirements for the ESXi are the following:

If any of the above requirements are not met, the Cloud Builder VM will display a warning message that can be dismissed, but the process will fail and you will have to start over.
The script will address only the following ones:
- VM Network portgroup must match the Management Network VLAN ID
- TSM-SSH must be turned on and configured to Start and Stop with Host
- NTP must be configured, running and configured to Start and Stop with Host
- Check if the vSwitch0 has more than one nic configured (just inform, does not modify vSwitch nic assingment)
How to run it? Grab the latest version of Power CLI from VMware{code}, copy the content of the script into a file and save it with a .ps1 extension, open powershell as an administrator and run the .ps1 file. The script itself will modify some PowerShell configurations to run.

The script run will look something like the following.
- Errors that must be fixed are displayed on red
- Warnings might be ignored and are displayed on yellow

So now that we know which are the requirements and how to run it lets dig in into the code. Feel free to copy, modify and share it. If you find any bug or recommendation please post it in the comments section.
Ps! While this post is out, I’m working on a new version to make it even easier. So be ready for more VCF scripts!
If it fails just run $error on powershell and send me the output to fix it!
#10/24/2020
#Speed up of VCF host readiness
#OCT/31/2020 -> Added DNS Server configuration
#NOV/12/2020 -> Fixed a bug when no hostnames were entered
#Added to ignore the invalid certificate warning
Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false
#Clear the view
cls
Write-Host -ForeGround 'Yellow' -back 'black' 'To use this script you will need to:'
Write-Host -ForeGround 'Yellow' -back 'black' '- Have configured ESXi management networks'
Write-Host -ForeGround 'Yellow' -back 'black' '- Have root password'
Write-Host -ForeGround 'Yellow' -back 'black' '- Provide all the IP Addresses, VLAN ID, and NTP Addreses'
$warning = 'Enter Y to continue. ---> '
Do {
Write-Host -ForeGround 'Yellow' -back 'black' -noNewLine $warning
$continue = Read-Host
$warning = 'Mmmm... Some info missing? When ready enter a Y to continue! ---> '
} While ($continue -notmatch 'Y')
#Regex patterns for validations
$ipRegexPattern = '^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$'
$vlanRegexPattern = '[0-4095]'
$fqdnRegexPattern = '(?=^.{1,254}$)(^(?:(?!\d+\.|-)[a-zA-Z0-9_\-]{1,63}(?<!-)\.?)+(?:[a-zA-Z]{2,})$)'
$hostcountRegexPattern = '[1-100]'
#Variables
$esxiIPs = @()
$hostnames = @()
#Constants
$esxUser = 'root'
$warning = 'Enter the root password, it wil be hidden so relax of watchers! ---> '
Write-Host -ForeGround 'Yellow' -back 'black' -noNewLine $warning
#Request root password for host configuration
$esxPswd = Read-Host -AsSecureString
$credentials = New-Object System.Management.Automation.PSCredential ('root', $esxPswd)
for ($i= 0 ;$i -lt 4;$i++){
switch ( $i )
{
0 { $warning = 'Enter the IP address of the FIRST ESXi! ---> '}
1 { $warning = 'Enter the IP address of the SECOND ESXi! ---> '}
2 { $warning = 'Enter the IP address of the THIRD ESXi! ---> '}
3 { $warning = 'Enter the IP address of the FORTH ESXi! ---> '}
}
Do {
Write-Host -ForeGround 'Yellow' -back 'black' -noNewLine $warning
$esxi = Read-Host
$warning = 'You did not enter a valid IP address. Please try again! ---> '
} While ($esxi -notmatch $ipRegexPattern)
$esxiIPs += $esxi
}
#Configure hostnames?
$warning = 'Do you want to configure esxi Hostnames? If already configured on DCUI, skip this step. Enter Y to confirm. ---> '
Write-Host -ForeGround 'Yellow' -back 'black' -noNewLine $warning
$configureHostnames = Read-Host
if ($configureHostnames -eq 'Y'){
for ($i= 0 ;$i -lt 4;$i++){
switch ( $i )
{
0 { $warning = 'Enter the Hostname (FQDN) of the FIRST ESXi! ---> '}
1 { $warning = 'Enter the Hostname (FQDN) of the SECOND ESXi! ---> '}
2 { $warning = 'Enter the Hostname (FQDN) of the THIRD ESXi! ---> '}
3 { $warning = 'Enter the Hostname (FQDN) of the FORTH ESXi! ---> '}
}
Do {
Write-Host -ForeGround 'Yellow' -back 'black' -noNewLine $warning
$hostname = Read-Host
$warning = 'You did not enter a valid FQDN. Please try again! ---> '
} While ($hostname -notmatch $fqdnRegexPattern)
$hostnames += $hostname
}
}
else{
Write-Host -ForeGround 'Yellow' -back 'black' 'Ok, no hostname configuration'
}
$warning = 'Enter the VLAN ID for the VM Network (it must match the Management Network VLAN)! ---> '
Do {
Write-Host -ForeGround 'Yellow' -back 'black' -noNewLine $warning
$VLANID = Read-Host
$warning = 'You did not enter a valid VLAN ID. Please try again! ---> '
} While ($VLANID -notmatch $vlanRegexPatter)
$warning = 'Enter the NTP Address! ---> '
Do {
Write-Host -ForeGround 'Yellow' -back 'black' -noNewLine $warning
$NTP1 = Read-Host
$warning = 'You did not enter a valid NTP IP Address. Please try again! ---> '
} While ($NTP1 -notmatch $ipRegexPattern)
#Need another NTP Server?
$warning = 'Add a second NTP? Enter Y to confirm ---> '
Write-Host -ForeGround 'Yellow' -back 'black' -noNewLine $warning
$anotherNTP = Read-Host
if ($anotherNTP -eq 'Y'){
$warning = 'Enter the Secondary NTP Address! ---> '
Do {
Write-Host -ForeGround 'Yellow' -back 'black' -noNewLine $warning
$NTP2 = Read-Host
$warning = 'You did not enter a valid NTP IP Address. Please try again! ---> '
} While ($NTP2 -notmatch $ipRegexPattern)
}
#DNS Configurations
$warning = 'Enter primary DNS Server! ---> '
Do {
Write-Host -ForeGround 'Yellow' -back 'black' -noNewLine $warning
$dnspri = Read-Host
$warning = 'You did not enter a valid DNS IP Address. Please try again! ---> '
} While ($dnspri -notmatch $ipRegexPattern)
#Need another DNS Server?
$warning = 'Add a second DNS Server? Enter Y to confirm ---> '
Write-Host -ForeGround 'Yellow' -back 'black' -noNewLine $warning
$anotherDNS = Read-Host
if ($anotherDNS -eq 'Y'){
$warning = 'Enter the Secondary DNS IP Address! ---> '
Do {
Write-Host -ForeGround 'Yellow' -back 'black' -noNewLine $warning
$dnsalt = Read-Host
$warning = 'You did not enter a valid DNS IP Address. Please try again! ---> '
} While ($dnsalt -notmatch $ipRegexPattern)
}
#DNS Configurations
$warning = 'Enter search domain name! ---> '
Do {
Write-Host -ForeGround 'Yellow' -back 'black' -noNewLine $warning
$searchdomainname = Read-Host
$warning = 'You did not enter a valid DNS IP Address. Please try again! ---> '
} While ($searchdomainname -notmatch $fqdnRegexPattern)
#Loop with all the ip address provided
$counter = 0
foreach ($esxi in $esxiIPs) {
$errorFlag = $false
Write-host 'Connecting to ' $esxi
try {
Connect-VIServer -Server $esxi -Credential $credentials -ErrorAction Stop | Out-Null
Write-Host -ForeGround 'black' -back 'green' 'Connected to host =======> ' $esxi
$esxcli = Get-EsxCli -VMHost $esxi
if ($hostnames.length -gt 0){
$esxcli.system.hostname.set($null,$hostnames[$counter],$null) | Out-Null
}
#Search for vSwitch0 object
$vswitch = Get-VirtualSwitch -VMHost $esxi -Name vSwitch0
if ($vswitch.nic.length -gt 1){
Write-Host -ForeGround 'white' -back 'red' 'Host ' $esxi ' has more than 1 nic on vSwitch0, please check the host before proceeding with Bring Up Process.'
$errorFlag = $true
}
else{
Write-Host -ForeGround 'black' -back 'green' 'Host ' $esxi ' has only 1 nic on vSwitch 0. Well done!'
}
try{
$VMNetworkPG = Get-VirtualPortgroup -Name 'VM Network'
Set-VirtualPortGroup -VirtualPortGroup $VMNetworkPG -VLanID $VLANID -ErrorAction Stop | Out-Null
Write-Host -ForeGround 'black' -back 'green' 'Configured VM Network of host ' $esxi ' with VLAN ID ' $VLANID
}
catch
{
Write-Host 'The portgroup might not be created, lets try to fix it.'
#Create the PG and set the VLAN ID
$VMNetworkPG = New-VirtualPortGroup -VirtualSwitch $vswitch -Name 'VM Network' | Out-Null
Set-VirtualPortGroup -VirtualPortGroup $VMNetworkPG -VLanID $VLANID -ErrorAction Stop | Out-Null
Write-Host -ForeGround 'black' -back 'green' 'Configured VM Network of host ' $esxi ' with VLAN ID ' $VLANID
}
try{
#NTP Adjustment
Add-VMHostNtpServer -VMHost $esxi -NtpServer $NTP1 -ErrorAction Stop | Out-Null
Write-Host -ForeGround 'black' -back 'green' 'Configured NTP Server 1 of host ' $esxi ' with NTP ' $NTP1
}
catch
{
Write-Host -ForeGround 'black' -back 'Yellow' 'I was not able to configure NTP ' $NTP1 ' on ' $esxi ' maybe its already added.'
}
if ($NTP2 -ne '') {
try{
#NTP Adjustment
Add-VMHostNtpServer -VMHost $esxi -NtpServer $NTP2 -ErrorAction Stop | Out-Null
Write-Host -ForeGround 'black' -back 'green' 'Configured NTP Server 2 of host ' $esxi ' with NTP ' $NTP2
}
catch
{
Write-Host -ForeGround 'black' -back 'Yellow' 'I was not able to configure NTP ' $NTP2 ' on ' $esxi ' maybe its already added.'
}
}
if ($dnsalt -ne '') {
try{
#DNS Servers Adjustment
Get-VMHostNetwork -VMHost $esxi | Set-VMHostNetwork -DNSAddress $dnspri, $dnsalt -SearchDomain $searchdomainname -Confirm:$false | Out-Null
Write-Host -ForeGround 'black' -back 'green' 'Configured DNS Servers of host ' $esxi ' with DNS Server ' $dnspri ' and ' $dnsalt
}
catch
{
Write-Host -ForeGround 'black' -back 'Yellow' 'I was not able to configure DNS ' $dnspri ' and ' $dnsalt ' on ' $esxi ' maybe its already added.'
}
}
else
{
try{
#DNS Servers Adjustment
Get-VMHostNetwork -VMHost $esxi | Set-VMHostNetwork -DNSAddress $dnspri -SearchDomain $searchdomainname -Confirm:$false | Out-Null
Write-Host -ForeGround 'black' -back 'green' 'Configured DNS Server 1 of host ' $esxi ' with DNS Server ' $dnspri
}
catch
{
Write-Host -ForeGround 'black' -back 'Yellow' 'I was not able to configure DNS ' $dnspri ' on ' $esxi ' maybe its already added.'
}
}
#Adjust the ESXi time with local computer time
$t = Get-Date
$dst = Get-VMHost -Name $esxi | %{ Get-View $_.ExtensionData.ConfigManager.DateTimeSystem }
$dst.UpdateDateTime((Get-Date($t.ToUniversalTime()) -format u)) | Out-Null
Write-Host -ForeGround 'black' -back 'green' 'Synchornized time of host ' $esxi ' with computer time '
#Open NTP ports
Get-VMHostFirewallException -VMHost $esxi | where {$_.Name -eq 'NTP client'} | Set-VMHostFirewallException -Enabled:$true | Out-Null
Write-Host -ForeGround 'black' -back 'green' 'Added firewall exception for NTP Client on host ' $esxi
#Start NTP Service and set it to autostart
Get-VmHostService -VMHost $esxi | Where-Object {$_.key -eq 'ntpd'} | Start-VMHostService -Confirm:$false | Out-Null
Get-VmHostService -VMHost $esxi | Where-Object {$_.key -eq 'ntpd'} | Set-VMHostService -policy 'on' | Out-Null
Write-Host -ForeGround 'black' -back 'green' 'NTP started and configured to Start and Stop with host on host ' $esxi
#Start SSH Service and set it to autostart
Get-VmHostService -VMHost $esxi | Where-Object {$_.key -eq 'TSM-SSH'} | Start-VMHostService -Confirm:$false | Out-Null
Get-VmHostService -VMHost $esxi | Where-Object {$_.key -eq 'TSM-SSH'} | Set-VMHostService -policy 'on' | Out-Null
Write-Host -ForeGround 'black' -back 'green' 'TSM-SSH started and configured to Start and Stop with host on host ' $esxi
$counter += 1
Disconnect-VIServer -Server $esxi -Confirm:$false
Write-Host -ForeGround 'black' -back 'green' '<======= Disonnected from host ' $esxi
if ($errorFlag){
Write-Host -ForeGround 'white' -back 'red' 'Check the configuration of ' $esxi ' before proceeding with bring up process.'
}
else{
Write-Host -ForeGround 'black' -back 'green' 'Host ' $esxi ' is ready for VCF! Woho!'
}
}
catch{
Write-Host -ForeGround 'white' -back 'red' 'I was not able to connect ' $esxi ' please check the connection to it.'
}
}
Good idea! I’ll try it.
LikeLike
Thanks localhostAR!
LikeLike
My nodes are now ready for VCF! Woho!!!
Great article thanks for sharing!
LikeLike