VMware Cloud Community
sivagndl
Enthusiast
Enthusiast
Jump to solution

Updatemanager_Baselineupdate for cluster

Hi All,

I am working on patch update for each host, below code is working perfect. 

looking some logic, if any host is in maintenance/not responding in cluster, skip for that cluster. (continue rest of hosts other cluster) 

foreach($cls in Get-Cluster) {
foreach ($ho in $cls|Get-VMHost|?{$_.build -ne "BuildNO"}|Get-Random) {
foreach($ho1 in get-vmhost $ho){Remediate-Inventory -Entity $ho1 -Baseline (Get-Baseline -Name "BaselineName")-Confirm:$false -ErrorAction SilentlyContinue -RunAsync}}}

Thanks for advance. 

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

My snippet can easily be adapted for only 1 ESXi node per cluster.

Get-Cluster -PipelineVariable cluster |
ForEach-Object -Process {
    $esx = Get-VMHost -Location $cluster | where{$_.ConnectionState -eq 'Connected'}

    if($esx.Count -eq $cluster.ExtensionData.Host.Count){
        $esx | Get-Random |
        Remediate-Inventory -Entity $ho1 -Baseline (Get-Baseline -Name "BaselineName")-Confirm:$false -ErrorAction SilentlyContinue -RunAsync
    }
}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

11 Replies
LucD
Leadership
Leadership
Jump to solution

Did you test that snippet, it looks as if only one ESXi node in each cluster will be remediated?
Also, even if you launch a remediation against all ESXi nodes in a cluster, the RunAsync will practically start them all in parallel.
Is that the intention?

In any case, to only remediate when all ESXi nodes in a cluster are in the 'Connected' state, you could do

Get-Cluster -PipelineVariable cluster |
ForEach-Object -Process {
    $esx = Get-VMHost -Location $cluster | where{$_.ConnectionState -eq 'Connected'}

    if($esx.Count -eq $cluster.ExtensionData.Host.Count){
        ForEach-Object -InputObject $esx -Process {
            Remediate-Inventory -Entity $ho1 -Baseline (Get-Baseline -Name "BaselineName")-Confirm:$false -ErrorAction SilentlyContinue -RunAsync
        }
    }
}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

sivagndl
Enthusiast
Enthusiast
Jump to solution

Thanks LucD for update. 

Your are correct. My snippet is working only each host in the clusters start them all in parallel(first set). 

My intention is any point ,only one host should be run one cluster(All are VSAN Cluster).

For example we have 5 clusters in vCenter, each cluster having 10 hosts,  when we run the script it will pick the 5 hosts and run in parallel((RunAsync). If any  host is in maintenance/not responding or disconnected in any cluster ,we have to skip that cluster and run the script for other set of the hosts in the clusters.

 

  

0 Kudos
LucD
Leadership
Leadership
Jump to solution

My snippet can easily be adapted for only 1 ESXi node per cluster.

Get-Cluster -PipelineVariable cluster |
ForEach-Object -Process {
    $esx = Get-VMHost -Location $cluster | where{$_.ConnectionState -eq 'Connected'}

    if($esx.Count -eq $cluster.ExtensionData.Host.Count){
        $esx | Get-Random |
        Remediate-Inventory -Entity $ho1 -Baseline (Get-Baseline -Name "BaselineName")-Confirm:$false -ErrorAction SilentlyContinue -RunAsync
    }
}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

sivagndl
Enthusiast
Enthusiast
Jump to solution

Thanks Lucd , It looks grate. 

i want to repeat enter VC using same code, is it work ?

i used below your snippet for testing out put i get only first set.. 

++++++++++++++++++++++++++++++++++++++++++++++++++++++

Get-Cluster -PipelineVariable cluster |
ForEach-Object -Process {
$esx = Get-VMHost -Location $cluster |where{$_.ConnectionState -eq 'Connected'}

if($esx.Count -eq $cluster.ExtensionData.Host.Count){
$esx|?{$_.Manufacturer -eq "HPE" -and $_.build -ne "XXXX"}| Get-Random |
#Remediate-Inventory -Entity  -Baseline (Get-Baseline -Name "BaselineName")-Confirm:$false -ErrorAction SilentlyContinue -RunAsync
select name,parent,build,Manufacturer
}
}

++++++++++++++++++++++++++++++++++++++++++++

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Not sure I understand the question.
Do you want to prompt for a vCenter name?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
sivagndl
Enthusiast
Enthusiast
Jump to solution

sorry for that Lucd. 

Not vCenter prompt...

i have to loop this code for entire VC..

once complete remediation for first set of hosts(random hosts) , automatically run second set and so on.. 

As per above code its running only one set.. 

  

 

 

0 Kudos
LucD
Leadership
Leadership
Jump to solution

That will require quite a bit more logic in the script, and it should probably not use Get-Random anymore in that case.
Do all the clusters have the same amount of ESXi nodes?
If not, you will have to take that into account as well


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
sivagndl
Enthusiast
Enthusiast
Jump to solution

Yaa. mixed node of clusters. (10,12 ,14 and 16 max).

or can we use wait or sleep commend for  10 to 15 min and rerun same script(not sure do or while).

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Since you run the update task in the background (RunAsync), you will have to test if the current task in each cluster is completed, before tackling the next ESXi node in the cluster.
Best way in my opinion would be to store those background Task objects in a table, and test for completion in a loop.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
sivagndl
Enthusiast
Enthusiast
Jump to solution

Thanks Lucd. I Will try that. 

How can i store background Task objects in a table using Get-VIEvent ?

0 Kudos
LucD
Leadership
Leadership
Jump to solution

When you run a cmdlet with RunAsync, you get a Task object back.
You can use that to track the progress of the Task


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference