Add an Entry to ESXi /etc/hosts using PowerShell
I was looking for away to easily add an entry to an ESXi host’s /etc/hosts file without using SSH to connect to the ESXi host. I ran across this article from a while back on Using vCLI’s vifs For More Than Just Datastore File Management. I could use vCLI, and that would be easy enough, but I wanted to figure out a way to do with PowerShell. In the article @lamw mentions the file management interface can be accessed with standard GET/PUT operations. The file management interface can be accessed with a Web Browser without enabling SSH on the ESXi host.
I put together a quick example of doing this with PowerShell using Invoke-WebRequest. The script Update-HostsFile.ps1 can be found at https://github.com/herseyc/PowerCLI-Scripts/blob/master/Update-HostsFile.ps1.
Here is the script (most up to date copy can be found https://github.com/herseyc/PowerCLI-Scripts/blob/master/Update-HostsFile.ps1):
############################################################### # # Quick and dirty way to use PowerShell to add an entry # to an ESXi host's /etc/hosts file # # http://www.vhersey.com/ # ############################################################### #Connectivity Information $Username = "root" # ESXi Username $Password = "VMware1!" # ESXi Password $esxihost = "192.168.1.25" # ESXi Host IP #New Host Entry $addIP = "192.168.1.151" $addHostname = "newhostsname" ### Ignore TLS/SSL errors add-type @" using System.Net; using System.Security.Cryptography.X509Certificates; public class TrustAllCertsPolicy : ICertificatePolicy { public bool CheckValidationResult( ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem) { return true; } } "@ [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy ### Create authorization string and store in $head $auth = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($Username + ":" + $Password)) $head = @{"Authorization"="Basic $auth"} # Request current hosts file Write-Host "Retrieving current /etc/hosts file from $esxihost" -ForeGroundColor Green $requesthostsfile = Invoke-WebRequest -Uri https://$esxihost/host/hosts -Method GET -ContentType "text/plain" -Headers $head if ( $requesthostsfile.StatusCode -ne "200" ) { Write-Host "Unable to retrieve current /etc/hosts file from $esxihost" -ForeGroundColor Red Exit } # Add new line to hosts file with $addIP and $addHostname $newhostsfile = $requesthostsfile.Content $newhostsfile += "`n$addIP`t$addHostname`n" Write-Host "Contents of new /etc/hosts" -ForeGroundColor Green Write-Host "-------------------------------------------------------" Write-Host $newhostsfile Write-Host "-------------------------------------------------------" # Put the new hosts file on the host Write-Host "Putting new /etc/hosts file on $esxihost" $puthostsfile = Invoke-WebRequest -Uri https://192.168.1.25/host/hosts -Method PUT -ContentType "text/plain" -Headers $head -Body $newhostsfile if ( $puthostsfile.StatusCode -ne "200" ) { Write-Host "Unable to put new /etc/hosts file on $esxihost" -ForeGroundColor Red Exit } Write-Host "Done!" -ForeGroundColor Green
The script requires some variables to be defined. $Username, $Password, $esxihost, $addIP, and $addHostname all need to be defined. The authorization header required for authentication against the file management interface is created using the $Username and $Password.
The line:
$requesthostsfile = Invoke-WebRequest -Uri https://$esxihost/host/hosts -Method GET -ContentType "text/plain" -Headers $head
Uses Invoke-WebRequest to retrieve the /etc/hosts file from the ESXi host (defined in the $esxihost variable). The content of the /etc/hosts file is $requesthostsfile.Content
.
A new line is added to the current host file content containing the $addIP and $addHostname.
The line:
$puthostsfile = Invoke-WebRequest -Uri https://192.168.1.25/host/hosts -Method PUT -ContentType "text/plain" -Headers $head -Body $newhostsfile
Puts the new hosts file which includes the new line on the ESXi host.
Pretty basic, but it could be expanded to add multiple entries, loop through multiple hosts, even update an existing entry. Might be useful for the home lab where DNS may not always be a good/available/stable option.
Cool script. Need to replace the hard coded IP address in line 63 with $esxihost.
Thank you. Worked perfectly.