Would this work with install-vmhost patch?
$vmhost = get-vmhost -name (get-content esx.txt)
foreach ($esx in $vmhost)
{
set-vmhost -vmhost $esx -state maintenance
Install-VMHostPatch -VMHost $esx -HostPath /vmfs/volumes/datastore/ESXi600-201905001/metadata.zip
}
would the host automatically reboot after the install-vmhostpatch and set itself back into connected state or will it stay in maintenance mode?
Do I need a wait loop?
You will have to do the restart afaik.
And you will have to take the ESXi node out of maintenance mode.
On a side note, I personally prefer using esxcli software ... (via Get-EsxCli) over Install-VMHostPatch.
It gives you better control over the process, there are more parameters to use.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
havent tested this. would it work?
$vmhost = get-vmhost -name (get-content esx.txt)
foreach ($esx in $vmhost)
{
set-vmhost -vmhost $esx -state maintenance -evacuate -runasync
Install-VMHostPatch -VMHost $esx -HostPath /vmfs/volumes/datastore/ESXi600-201905001/metadata.zip -runasync
restart-vmhost -vmhost $esx -runasync
# Wait for server to reboot
do {
sleep 60
$State = (get-vmhost $esx).ConnectionState
Write-Host "Waiting for Reboot …"
}
while ($State -ne "Maintenance")
Write-Host "$ServerName is back up"
# Exit maintenance mode
Write-Host "Exiting Maintenance mode"
Set-VMhost $esx -State Connected | Out-Null -runasync
}
I don't think you should use the RunAsync switch on the Set-VMHost and Install-VMHostPatch cmdlet.
If you do, you would need a loop to wait till the ESXi is respectively in maintenance mode, and the patch is installed, before continuing with next line.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
like this?
$vmhost = get-vmhost -name (get-content esx.txt)
foreach ($esx in $vmhost)
{
set-vmhost -vmhost $esx -state maintenance -evacuate -runasync
do {
sleep 60
$State = (get-vmhost $esx).ConnectionState
}
while ($State -ne "Maintenance")
Write-Host "$esx is in Maintenance mode"
Install-VMHostPatch -VMHost $esx -HostPath /vmfs/volumes/datastore/ESXi600-201905001/metadata.zip -runasync
restart-vmhost -vmhost $esx -runasync
# Wait for server to reboot
do {
sleep 60
$State = (get-vmhost $esx).ConnectionState
Write-Host "Waiting for Reboot …"
}
while ($State -ne "Maintenance")
Write-Host "$ServerName is back up"
# Exit maintenance mode
Write-Host "Exiting Maintenance mode"
Set-VMhost $esx -State Connected | Out-Null -runasync
}
Also on the Install-VMHostPatch get rid of the RunAsync, otherwise you risk restrating the ESXi node before the patch is installed.
And in the end, what do you win by using RunAsync when you have to include a loop to wait.
That would only bring something when you run the actions on multiple ESXi nodes in parallel.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I want to put all the hosts in the txt file in maintenance mode. Then patching then together.
If you want to run those jobs in parallel, I would opt for background jobs.
Something like this
param(
[string]$EsxName,
[string]$Server,
[string]$SessionId
)
Connect-VIServer -Server $Server -Session $SessionId
$esx = Get-VMHost -Name $EsxName
Set-VMHost -VMHost $esx -State Maintenance -Evacuate -Confirm:$false
Install-VMHostPatch -VMHost $esx -HostPath '/vmfs/volumes/datastore/ESXi600-201905001/metadata.zip'
Restart-VMHost -VMHost $esx -Confirm:$false
Set-VMHost -VMHost $esx -State Connected -Confirm:$false
}
$jobs = Get-Content -Path esx.txt |
ForEach-Object -Process {
Start-Job -Name EsxPatch -ScriptBlock $code -ArgumentList $_,$global:defaultviserver.Name,$global:DefaultVIServer.SessionId
}
Receive-Job -Job $jobs -Wait
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi Luc
getthis this error
Receive-Job : Cannot bind parameter 'Job'. Cannot convert the "xxxxxxx" value of type "System.String" to type "System.Management.Automation.Job".
At line:49 char:18
+ Receive-Job -Job $jobs -Wait
+ ~~~~~
+ CategoryInfo : InvalidArgument: (:) [Receive-Job], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.ReceiveJobCommand
Can you check what is in the variable $jobs?
The only way an entry could be a [string] is when the Start-Job failed for one reason or another.
In that case the $jobs variable should contain an entry with the error message, which is a [string]
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
$jobs shows a lit of my hosts in
esx.txt
host1.domain.com
host2.domain.com
host3.domain.com
Did something go wrong in the copy/paste of the code?
Can you attach the script as you are running it?
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I changed it a bit to use update manager instead
$code = {
param(
[string]$EsxName,
[string]$Server,
[string]$SessionId
)
Connect-VIServer -Server $Server -Session $SessionId
$baseline = get-baseline -server xxxx -name "65 baseline"
$esx = Get-VMHost -Name $EsxName
Set-VMHost -VMHost $esx -State Maintenance -Evacuate -Confirm:$false
$baseline | Attach-Baseline -entity $esx -Confirm:$false
Scan-inventory -Entity $esx
$baseline | Remediate-Inventory -Entity $esx -Confirm:$false -ErrorAction SilentlyContinue
Restart-VMHost -VMHost $esx -Confirm:$false
Set-VMHost -VMHost $esx -State Connected -Confirm:$false
}
$jobs = Get-Content -Path "c:\scripts\esxhosts.txt"
ForEach-Object -Process {
Start-Job -Name EsxPatch -ScriptBlock $code -ArgumentList $_, $global:defaultviserver.Name, $global:DefaultVIServer.SessionId
}
Receive-Job -Job $jobs -Wait
Ok, I see the problem, you dropped the pipeline symbol after the Get-Content line
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks Luc. I got the hosts in maintenance mode but dont see any other activity after that
I didn't test the code with Update Manager, with Install-VMHostPatch it worked without a problem.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
It could be that the background jobs is hanging on a prompt or something.
See if there is anything in the job output, otherwise use Start-Transcript inside the background job
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
get-job shows
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
1 EsxPatch BackgroundJob Completed True localhost ...
3 EsxPatch BackgroundJob Completed True localhost ...
5 EsxPatch BackgroundJob Completed True localhost ...
7 EsxPatch BackgroundJob Completed True localhost ...
9 EsxPatch BackgroundJob Running True localhost ...
11 EsxPatch BackgroundJob Running True localhost ...
13 EsxPatch BackgroundJob Running True localhost ...
15 EsxPatch BackgroundJob Running True localhost ...
17 EsxPatch BackgroundJob Running True localhost ...
That's just the status of the jobs, we want to see what the captured output is.
Perhaps try with
Get-Job | Stop-Job | Receive-Job
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I did a start-transcript but did not see a file that got logged