Hello,
I would like add all ESXis' hosts file the entry and wanna do it to chosing ESXi and an entry. I found some codes but it doesnt work. Could you help me
Thanks.
I found codes from there: https://github.com/herseyc/PowerCLI-Scripts/blob/master/Update-HostsFile.ps1
This is the code:
$vCenterServer = Read-Host -Prompt 'Enter the FQDN of the vCenter Server you want to connect to (ex. vcenter.domain.com)'
Try {
Connect-VIServer -Server $vCenterServer -ErrorAction Stop | Out-Null
}
Catch {
Write-Host -ForegroundColor Red -BackgroundColor Black "Could not connect to the vCenter Server [$vCenterServer]." `n
Exit
}
while ($True){
### Prompt the user for the cluster name within that vCenter Server
$ClusterName = Read-Host -Prompt 'Enter the full name of the cluster you want to work with (ex. ProdCluster01)'
### Get information about all hosts in the defined cluster
$vmHosts = Get-Cluster -Name $ClusterName | Get-VMHost | Sort-Object
$cont = ""
$contR = ""
Do {
### Ask the user what step to perform
Write-Host `n
Write-Host "Please enter a task to perform on each host in the cluster:"
Write-Host "1.) Add parameter"
Write-Host "2.) Add Another parameter"
Write-Host "3.) Next Cluster"
Write-Host "4.) Exit" `n
$choice = Read-Host
### Perform a particular task based on user input
Switch ($choice) {
### If task #1 is chosen, add parameter to /etc/hosts
1 {
Write-Host -ForegroundColor Yellow `n "Retrieving current /etc/hosts file from $esxihost"
ForEach ($vmHost in $vmHosts) {
#Connectivity Information
$Username = "root" # ESXi Username
$Password = Read-Host -Prompt 'ESXi Password'
#New Host Entry
$addIP = Read-Host -Prompt ' New Entry IP'
$addHostname = Read-Host -Prompt ' New Entry Hostname'
$addAlias= Read-Host -Prompt ' New Entry Alias'
### 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 and $addAlias
$newhostsfile = $requesthostsfile.Content
$newhostsfile += "`n$addIP`t$addHostname`t$addAlias"
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://$vmHost/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
}
}
$cont=$True
}
### If task #2 is chosen, Add Another Entry
2 {
Write-Host -ForegroundColor Yellow `n "Retrieving current /etc/hosts file from $esxihost"
ForEach ($vmHost in $vmHosts) {
#New Host Entry
$addanotherIP = Read-Host -Prompt ' New Entry IP'
$addanotherHostname = Read-Host -Prompt ' New Entry Hostname'
$addanotherAlias= Read-Host -Prompt ' New Entry Alias'
}
# 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 and $addAlias
$newhostsfile = $requesthostsfile.Content
$newhostsfile += "`n$anotheraddIP`t$addanotherHostname`t$addanotherAlias"
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://$vmHost/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
}
$cont=$True
}
### If task #3 is chosen, next cluster
3 {
Write-Host "Next Cluster..."
$cont = $false
$contR = $false
}
### If task #4 is chosen, exit the script
4 {
Write-Host "Exiting..."
$cont = $false
$contR = $True
}
### If user enters anything other than 1-4, input is invalid and ask question again
default {
Write-Host -ForegroundColor Red ">>> Invalid input. Please select option 1-4."
$cont = $true
$contR = $false
}
### Loop through the script until task #4 (Exit) is chosen
While ($cont)
if ($contR) {
break
}
You can do all escli commands via the Get-EsxCli cmdlet.
$esxcli = Get-esxcli -VMHost <ESXi-name> -V2
$esxcli.network.ip.hosts.remove.Invoke(@{ip='192.168.1.1';hostname='hostname.domain'})
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Can you be a bit more specific?
What exactly doesn't work?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hello @LucD
Those are the errors i got
At C:\Users\editHostFileinHost.ps1:77 char:13
+ $cont=$True
+ ~
Missing statement block in switch statement clause.
At C:\Users\editHostFileinHost.ps1:80 char:4
+ 2 {
+ ~
Unexpected token '{' in expression or statement.
At C:\Users\editHostFileinHost.ps1:119 char:7
+ 3 {
+ ~
Unexpected token '{' in expression or statement.
At C:\Users\editHostFileinHost.ps1:125 char:7
+ 4 {
+ ~
Unexpected token '{' in expression or statement.
At C:\Users\editHostFileinHost.ps1:138 char:18
+ While ($cont)
+ ~
Missing statement body in while loop.
At C:\Users\editHostFileinHost.ps1:19 char:5
+ Do {
+ ~
Missing closing '}' in statement block or type definition.
At C:\Users\editHostFileinHost.ps1:142 char:6
+ }
+ ~
Missing while or until keyword in do loop.
At C:\Users\editHostFileinHost.ps1:10 char:14
+ while ($True){
+ ~
Missing closing '}' in statement block or type definition.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : MissingSwitchStatementClause
The script is having some issues (missing curly braces, curly braces in the wrong location, ...).
Attached a corrected version of your script, try that one.
Change the filetype .txt to .ps1
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hello @LucD
Thank you so much for your help. I got an issue when tried
Retrieving current /etc/hosts file from
Invoke-WebRequest : Cannot bind parameter 'Uri'. Cannot convert value "https:///host/hosts" to type "System.Uri". Error: "Invalid URI: The hostname could not be parsed."
At C:\Users\edithostfile\Untitled5.ps1:49 char:64
+ ... stsfile = Invoke-WebRequest -Uri https://$esxihost/host/hosts -Method ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Invoke-WebRequest], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
Unable to retrieve current /etc/hosts file from
That line should read
$requesthostsfile = Invoke-WebRequest -Uri "https://$($esxihost)/host/hosts" -Method GET -ContentType "text/plain" -Headers $head
But there is the other issue that the variable $esxihost isn't assigned a value anywhere in your script.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I would like to choose all hosts in the cluster, and the script should add some lines in the hosts' /etc/hosts file. Is that possible with that script? @LucD
Hello @LucD
This script works but keeps asking me for these entries over and over for all hosts in the cluster. I want it not to ask me again when I add these entries at first. Is that possible?
$addIP = Read-Host -Prompt ' New Entry IP'
$addHostname = Read-Host -Prompt ' New Entry Hostname'
$addAlias = Read-Host -Prompt ' New Entry Alias'
I'm not sure what you want me to do.
You wrote the script to prompt for these values inside your
ForEach ($vmHost in $vmHosts){
block, so it is normal it prompts for each ESXi node in the cluster.
Why did you place those prompts there in the first place?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Actually i wanna give ip, hostname and alias at first and i wanna add these values each esxi host's hosts file in the cluster. When the script works it prompts the values again for each esxi host and i give those values again and again. Could you help me about that at the begining i give those values and script will add hosts and ask me other options 2,3 or 4. Could i explain what i wanna do?
In the meantime, I discovered you copied a large part of that script from here without so much as referring to the original author.
If you run the original script in a foreach loop over all the ESXi nodes in a cluster, you don't need to prompt for the new entry inside the foreach loop you are using.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks @LucD , i didn't know, i added reference.
Did you make the changes like this?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Yes i did, the script works now. Thanks for everything.
There is the last version of the script. I made another changes.
In the second coice the script keeps asking for the new entries, i put the entries before foreach as you can see on the txt file. Now i wanna add try - catch in the scipt instead of exit. If i can do it i'll share the new version. I'm new about scripts 🙂 If i made a mistake sorry for that.
Thanks @LucD for your help.
If you mean the exit when the StatusCode from the Invoke-WebRequest is not 200?
In that case a Try-Catch would be rather unsuited for catching that 200 statuscode.
The Try-Catch is meant to capture terminating exceptions, i.e. the cmdlet fails.
A not 200 statuscode is saying that the cmdlet worked but that there was a possible issue with the HTTP request.
Those are 2 different things
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I mean if i get an issue for one host the script can continue to the another host in the cluster. Not to stop working. I wanna add like this:
try{
Foreach()
......
}catch{
Write-host $vmhost “...”
}
Imho it would be a lot easier to not call the exit, just write a message and continue
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
If you just leave out the line with exit, the script will continue to the next ESXi nodes.
if ( $puthostsfile.StatusCode -ne "200" ) {
Write-Host "Unable to put new /etc/hosts file on $vmHost" -ForegroundColor Red
}
$cont = $True
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I see, Thank you @LucD . Do you know how to delete an entry in the esxi host file content? I couldnt find it. It can be possible connect Esxi with ssh and run that command:
esxcli network ip hosts remove --hostname="hostname" --ip="IP"
But i couldnt find to do it with powercli for all hosts