Hi this is the code which i have written to update vmware tools using both UpgradeTools_Task and Invoke-VMscript based on a customer environment. I am stucked with few things to get this script running perfectly.
Can someone please go through the script and correct on below points.
1. On Line 15 I have kept Start-sleep but here the script should wait to complete all the vmware tools update task (UpgradeTools_Task) and catch any failures tasks while updating using (UpgradeTools_Task) cmdlet and then it should move to line 16.
2.In this environment there are multiple passwords for administrator account for windows and root for non-windows( In this case for some vms admin password is password@1 etc..). Can we truncate the try/catch method to increase speed in execution.
3.Finally is still any truncate required in the complete script to reduce few more lines? please suggest this will be helpful for a learner like me to develop script in correct way.
Start-sle
Write-Host 'Fetching Resource Pools Info'
$allresourcepools = 'res1','res2'
$respExpression = "^$($allresourcepools -join '$|^')$"
foreach($resourcepool in (Get-View -ViewType ResourcePool -Filter @{'Name'=$respExpression})){
Write-Host "Fetching VMs in $resourcepool"
$vmsinresourcepool = Get-View -Id $resourcepool.Vm
$vmtoolsoutdate = $vmsinresourcepool|Where-Object {$_.guest.ToolsRunningStatus -eq 'guestToolsRunning' -and $_.guest.toolsversionstatus -eq 'guestToolsNeedUpgrade'}
$vmexpression= "^$($vmtoolsoutdate.name -join '$|^')$"
$vmtoolsupdate=Get-View -ViewType VirtualMachine -Filter @{'Name'=$vmexpression}
$msoutdate=Get-View -ViewType VirtualMachine -Filter @{'Name'=$vmexpression} |?{$_.Guest.GuestFullName -like '*Windows*'}
$otheros=Get-View -ViewType VirtualMachine -Filter @{'Name'=$vmexpression} |?{$_.Guest.GuestFullName -notlike '*Windows*'}
$installerArgs = '/S /v "/qn REBOOT=R ADDLOCAL=ALL REMOVE=Hgfs,WYSE"'
%{($winoutdate).UpgradeTools_Task($installerArgs)}
%{($otheros).UpgradeTools_Task($null)}
Start-sleep -s 300
$tasklist=Get-Task |Where-Object {$_.Name -eq 'UpgradeTools_Task' -and $_.State -eq 'Error'}
$installfailedvms= Get-View -Id $tasklist.ObjectId -Property Name| Select-Object -ExpandProperty Name
$viewexpression= "^$($installfailedvms -join '$|^')$"
$allfailedvms=Get-View -ViewType VirtualMachine -Filter @{'Name'= $viewexpression} -Property Name,"Runtime.ToolsInstallerMounted" |?{$_.Runtime.ToolsInstallerMounted -ne 'true'} | %{$_.MountToolsInstaller()}
$msinstallfailed=Get-View -ViewType VirtualMachine -Filter @{'Name'=$viewexpression} |?{$_.Guest.GuestFullName -like '*Windows*'}
$installfailedotheros=Get-View -ViewType VirtualMachine -Filter @{'Name'=$viewexpression} |?{$_.Guest.GuestFullName -notlike '*Windows*'}
Write-Host Updating vmware tools on $msinstallfailed.name using invoke method
$scriptforwin = @'
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs; exit }
$driveletter=(Get-WmiObject win32_logicaldisk -filter 'DriveType=5').DeviceID
Start-Process -FilePath $driveletter\setup.exe -ArgumentList '-s -v-qn ADDLOCAL=ALL REBOOT=R'
'@
$found = $false
try{
$out1 = Invoke-VMScript -VM $msinstallfailed.name -GuestUser "administrator" -GuestPassword "password@1" -ScriptText $scriptforwin -ScriptType Powershell -ErrorAction Stop | Select -ExpandProperty ScriptOutput
$found = $true
}
catch [VMware.VimAutomation.ViCore.Types.V1.ErrorHandling.InvalidGuestLogin]{
$out1 = "Invalid logon"
}
catch{
$out1 = "any other output"
}
if(!$found){
try{
$out2 = Invoke-VMScript -VM $msinstallfailed.name -GuestUser "administrator" -GuestPassword "password@2" -ScriptText $scriptforwin -ScriptType Powershell -ErrorAction Stop | Select -ExpandProperty ScriptOutput
$found = $true
}
catch [VMware.VimAutomation.ViCore.Types.V1.ErrorHandling.InvalidGuestLogin]{
$out2 = "Invalid logon"
}
catch{
$out2 = "any other output"
}
}
if(!$found){
try{
$out3 = Invoke-VMScript -VM $msinstallfailed.name -GuestUser "administrator" -GuestPassword "password@3" -ScriptText $scriptforwin -ScriptType Powershell -ErrorAction Stop | Select -ExpandProperty ScriptOutput
$found = $true
}
catch [VMware.VimAutomation.ViCore.Types.V1.ErrorHandling.InvalidGuestLogin]{
$out3 = "Invalid logon"
}
catch{
$out3 = "any other output"
}
}
Write-Output "VM: $($msinstallfailed.name): $found"
Write-Output "VM: $($msinstallfailed.name): $out1"
Write-Output "VM: $($msinstallfailed.name): $out2"
Write-Output "VM: $($msinstallfailed.name): $out3"
Write-Host Updating vmware tools on non-windows VMs $installfailedotheros.name using invoke method
$scriptfornonwindows = @'
mkdir -p /mnt/vmw-tools && mount /dev/cdrom /mnt/vmw-tools && VMW_TOOLS=$(ls /mnt/vmw-tools/ | grep .gz) && cp -f /mnt/vmw-tools/${VMW_TOOLS} /tmp/ && umount /mnt/vmw-tools && rmdir /mnt/vmw-tools && tar -zxvf /tmp/${VMW_TOOLS} -C /tmp/ && cd /tmp/vmware-tools-distrib/ && ./vmware-install.pl -d default && rm -rf vmware-tools-distrib/ && rm -f /tmp/${VMW_TOOLS} && cd ~
'@
$found = $false
try{
$out1 = Invoke-VMScript -VM $installfailedotheros.name -GuestUser "root" -GuestPassword "password@3" -ScriptText $scriptfornonwindows -ScriptType Bash -ErrorAction Stop | Select -ExpandProperty ScriptOutput
$found = $true
}
catch [VMware.VimAutomation.ViCore.Types.V1.ErrorHandling.InvalidGuestLogin]{
$out1 = "Invalid logon"
}
catch{
$out1 = "any other output"
}
if(!$found){
try{
$out2 = Invoke-VMScript -VM $installfailedotheros.name -GuestUser "root" -GuestPassword "password@3" -ScriptText $scriptfornonwindows -ScriptType Bash -ErrorAction Stop | Select -ExpandProperty ScriptOutput
$found = $true
}
catch [VMware.VimAutomation.ViCore.Types.V1.ErrorHandling.InvalidGuestLogin]{
$out2 = "Invalid logon"
}
catch{
$out2 = "any other output"
}
}
if(!$found){
try{
$out3 = Invoke-VMScript -VM $installfailedotheros.name -GuestUser "root" -GuestPassword "password@3" -ScriptText $scriptfornonwindows -ScriptType Bash -ErrorAction Stop | Select -ExpandProperty ScriptOutput
$found = $true
}
catch [VMware.VimAutomation.ViCore.Types.V1.ErrorHandling.InvalidGuestLogin]{
$out3 = "Invalid logon"
}
catch{
$out3 = "any other output"
}
}
Write-Output "VM: $($installfailedotheros.name): $found"
Write-Output "VM: $($installfailedotheros.name): $out1"
Write-Output "VM: $($installfailedotheros.name): $out2"
Write-Output "VM: $($installfailedotheros.name): $out3"
}
Perhaps try like this
Write-Host 'Fetching Resource Pools Info'
$allresourcepools = 'SEZ02'
$respExpression = "^$($allresourcepools -join '$|^')$"
foreach($resourcepool in (Get-View -ViewType ResourcePool -Filter @{'Name'=$respExpression})){
Write-Host "Fetching VMs in $resourcepool"
$vmsinresourcepool = Get-View -Id $resourcepool.Vm
$vmtoolsoutdate = $vmsinresourcepool|Where-Object {$_.guest.ToolsRunningStatus -eq 'guestToolsRunning' -and $_.guest.toolsversionstatus -eq 'guestToolsNeedUpgrade'}
$vmexpression= "^$($vmtoolsoutdate.name -join '$|^')$"
$vmtoolsupdate=Get-View -ViewType VirtualMachine -Filter @{'Name'=$vmexpression}
$msoutdate=Get-View -ViewType VirtualMachine -Filter @{'Name'=$vmexpression} |?{$_.Guest.GuestFullName -like '*Windows*'}
$otheros=Get-View -ViewType VirtualMachine -Filter @{'Name'=$vmexpression} |?{$_.Guest.GuestFullName -notlike '*Windows*'}
$installerArgs = '/S /v "/qn REBOOT=R ADDLOCAL=ALL REMOVE=Hgfs,WYSE"'
$scriptstarttime=Get-Date
%{($msoutdate).UpgradeTools_Task($installerArgs)} -ErrorAction SilentlyContinue
%{($otheros).UpgradeTools_Task($null)} -ErrorAction SilentlyContinue
$scriptendtime=Get-Date
$tasks = @(Get-Task | where{$_.Name -eq 'UpgradeTools_Task' -and $_.StartTime -gt $scriptstarttime -and $_.StartTime -lt $scriptendtime -and 'Running','Queued' -contains $_.State})
while ($tasks.Count -ne 0){
sleep 5
$tasks = @(Get-Task | where{$_.Name -eq 'UpgradeTools_Task' -and $_.StartTime -gt $scriptstarttime -and $_.StartTime -lt $scriptendtime -and 'Running','Queued' -contains $_.State})
}
$tasklist = Get-Task | Where-Object {$_.Name -eq 'UpgradeTools_Task' -and $_.StartTime -gt $scriptstarttime -and $_.StartTime -lt $scriptendtime -and $_.State -eq 'Error'}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Not sure what line 13 and 14 are supposed to do?
When you submit an async task, you can monitor these tasks in a while loop.
Test if their status ($task.Info.State) is 'running', if not continue the while loop.
You can find an example in About Async tasks, the Get-Task cmdlet and a hash table
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks for your time LucD. I am sorry for the late reply.
Its my mistake while copying the script I mentioned variable wrongly.
The variables should be like this in 13 & 14 lines
%{($msoutdate).UpgradeTools_Task($installerArgs)}
%{($otheros).UpgradeTools_Task($null)}
on 13th line the upgrade task is initiated to upgrade windows vms by passing installation arguments and 14th line follows for linux.
When I execute the script like this its working fine but the only concern is on line 16 after sleep time when it fetches for the failure tasks I am missing few tasks b/c they are still in progress. I have gone through your example but i am not successful in creating the while loop. I am confused from where I should keep hashtable and start while loop. Can you please correct the code for me.
My intention is after executing line 13 and 14 the script should wait until all the update task finishes and it should catch the failure tasks.($_.Name -eq 'UpgradeTools_Task' -and $_.State -eq 'Error')
Then it should move to invoke method on that failed VMs.
Hi LucD,
Any thoughts on my request.
Try this way, it replaces the sleep by a while-loop that waits till there are no more running or queued tasks.
All the other lines in your script stay unchanged
Write-Host 'Fetching Resource Pools Info'
$allresourcepools = 'res1','res2'
$respExpression = "^$($allresourcepools -join '$|^')$"
foreach($resourcepool in (Get-View -ViewType ResourcePool -Filter @{'Name'=$respExpression})){
Write-Host "Fetching VMs in $resourcepool"
$vmsinresourcepool = Get-View -Id $resourcepool.Vm
$vmtoolsoutdate = $vmsinresourcepool|Where-Object {$_.guest.ToolsRunningStatus -eq 'guestToolsRunning' -and $_.guest.toolsversionstatus -eq 'guestToolsNeedUpgrade'}
$vmexpression= "^$($vmtoolsoutdate.name -join '$|^')$"
$vmtoolsupdate=Get-View -ViewType VirtualMachine -Filter @{'Name'=$vmexpression}
$msoutdate=Get-View -ViewType VirtualMachine -Filter @{'Name'=$vmexpression} |?{$_.Guest.GuestFullName -like '*Windows*'}
$otheros=Get-View -ViewType VirtualMachine -Filter @{'Name'=$vmexpression} |?{$_.Guest.GuestFullName -notlike '*Windows*'}
$installerArgs = '/S /v "/qn REBOOT=R ADDLOCAL=ALL REMOVE=Hgfs,WYSE"'
%{($winoutdate).UpgradeTools_Task($installerArgs)}
%{($otheros).UpgradeTools_Task($null)}
$tasks = @(Get-Task | where{$_.Name -eq 'UpgradeTools_Task' -and 'Running','Queued' -contains $_.State})
while ($tasks.Count -ne 0){
sleep 5
$tasks = @(Get-Task | where{$_.Name -eq 'UpgradeTools_Task' -and 'Running','Queued' -contains $_.State})
}
$tasklist = $tasks | Where-Object {$_.State -eq 'Error'}
$installfailedvms= Get-View -Id $tasklist.ObjectId -Property Name| Select-Object -ExpandProperty Name
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks for your time Guru.
When I execute the code $tasks is showing empty and its not able to view the object id ($tasklist.ObjectId) as $tasklist is empty.
But in vcenter i can able to see the error task.
When I do Get-Task parallelly I can see error and success tasks but its not collecting error tasks in $tasklist.
Below is the error
This is the complete script which I am trying to execute.Can you please re-correct.
Write-Host 'Fetching Resource Pools Info'
$allresourcepools = 'res1','res2'
$respExpression = "^$($allresourcepools -join '$|^')$"
foreach($resourcepool in (Get-View -ViewType ResourcePool -Filter @{'Name'=$respExpression})){
Write-Host "Fetching VMs in $resourcepool"
$vmsinresourcepool = Get-View -Id $resourcepool.Vm
$vmtoolsoutdate = $vmsinresourcepool|Where-Object {$_.guest.ToolsRunningStatus -eq 'guestToolsRunning' -and $_.guest.toolsversionstatus -eq 'guestToolsNeedUpgrade'}
$vmexpression= "^$($vmtoolsoutdate.name -join '$|^')$"
$vmtoolsupdate=Get-View -ViewType VirtualMachine -Filter @{'Name'=$vmexpression}
$msoutdate=Get-View -ViewType VirtualMachine -Filter @{'Name'=$vmexpression} |?{$_.Guest.GuestFullName -like '*Windows*'}
$otheros=Get-View -ViewType VirtualMachine -Filter @{'Name'=$vmexpression} |?{$_.Guest.GuestFullName -notlike '*Windows*'}
$installerArgs = '/S /v "/qn REBOOT=R ADDLOCAL=ALL REMOVE=Hgfs,WYSE"'
%{($msoutdate).UpgradeTools_Task($installerArgs)}
%{($otheros).UpgradeTools_Task($null)}
$tasks = @(Get-Task | where{$_.Name -eq 'UpgradeTools_Task' -and 'Running','Queued' -contains $_.State})
while ($tasks.Count -ne 0){
sleep 5
$tasks = @(Get-Task | where{$_.Name -eq 'UpgradeTools_Task' -and 'Running','Queued' -contains $_.State})
}
$tasklist = $tasks | Where-Object {$_.State -eq 'Error'}
$installfailedvms= Get-View -Id $tasklist.ObjectId -Property Name| Select-Object -ExpandProperty Name
$viewexpression= "^$($installfailedvms -join '$|^')$"
$allfailedvms=Get-View -ViewType VirtualMachine -Filter @{'Name'= $viewexpression} -Property Name,"Runtime.ToolsInstallerMounted" |?{$_.Runtime.ToolsInstallerMounted -ne 'true'} | %{$_.MountToolsInstaller()}
$msinstallfailed=Get-View -ViewType VirtualMachine -Filter @{'Name'=$viewexpression} |?{$_.Guest.GuestFullName -like '*Windows*'}
$installfailedotheros=Get-View -ViewType VirtualMachine -Filter @{'Name'=$viewexpression} |?{$_.Guest.GuestFullName -notlike '*Windows*'}
Write-Host Updating vmware tools on $msinstallfailed.name using invoke method
$scriptforwin = @'
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs; exit }
$driveletter=(Get-WmiObject win32_logicaldisk -filter 'DriveType=5').DeviceID
Start-Process -FilePath $driveletter\setup.exe -ArgumentList '-s -v-qn ADDLOCAL=ALL REBOOT=R'
'@
$found = $false
try{
$out1 = Invoke-VMScript -VM $msinstallfailed.name -GuestUser "administrator" -GuestPassword "admin@123" -ScriptText $scriptforwin -ScriptType Powershell -ErrorAction Stop | Select -ExpandProperty ScriptOutput
$found = $true
}
catch [VMware.VimAutomation.ViCore.Types.V1.ErrorHandling.InvalidGuestLogin]{
$out1 = "Invalid logon"
}
catch{
$out1 = "any other output"
}
if(!$found){
try{
$out2 = Invoke-VMScript -VM $msinstallfailed.name -GuestUser "administrator" -GuestPassword "admin@1234" -ScriptText $scriptforwin -ScriptType Powershell -ErrorAction Stop | Select -ExpandProperty ScriptOutput
$found = $true
}
catch [VMware.VimAutomation.ViCore.Types.V1.ErrorHandling.InvalidGuestLogin]{
$out2 = "Invalid logon"
}
catch{
$out2 = "any other output"
}
}
if(!$found){
try{
$out3 = Invoke-VMScript -VM $msinstallfailed.name -GuestUser "administrator" -GuestPassword "admin@1235" -ScriptText $scriptforwin -ScriptType Powershell -ErrorAction Stop | Select -ExpandProperty ScriptOutput
$found = $true
}
catch [VMware.VimAutomation.ViCore.Types.V1.ErrorHandling.InvalidGuestLogin]{
$out3 = "Invalid logon"
}
catch{
$out3 = "any other output"
}
}
Write-Output "VM: $($msinstallfailed.name): $found"
Write-Output "VM: $($msinstallfailed.name): $out1"
Write-Output "VM: $($msinstallfailed.name): $out2"
Write-Output "VM: $($msinstallfailed.name): $out3"
Write-Host Updating vmware tools on non-windows VMs $installfailedotheros.name using invoke method
$scriptfornonwindows = @'
mkdir -p /mnt/vmw-tools && mount /dev/cdrom /mnt/vmw-tools && VMW_TOOLS=$(ls /mnt/vmw-tools/ | grep .gz) && cp -f /mnt/vmw-tools/${VMW_TOOLS} /tmp/ && umount /mnt/vmw-tools && rmdir /mnt/vmw-tools && tar -zxvf /tmp/${VMW_TOOLS} -C /tmp/ && cd /tmp/vmware-tools-distrib/ && ./vmware-install.pl -d default && rm -rf vmware-tools-distrib/ && rm -f /tmp/${VMW_TOOLS} && cd ~
'@
$found = $false
try{
$out1 = Invoke-VMScript -VM $installfailedotheros.name -GuestUser "root" -GuestPassword "admin@123" -ScriptText $scriptfornonwindows -ScriptType Bash -ErrorAction Stop | Select -ExpandProperty ScriptOutput
$found = $true
}
catch [VMware.VimAutomation.ViCore.Types.V1.ErrorHandling.InvalidGuestLogin]{
$out1 = "Invalid logon"
}
catch{
$out1 = "any other output"
}
if(!$found){
try{
$out2 = Invoke-VMScript -VM $installfailedotheros.name -GuestUser "root" -GuestPassword "admin@1234" -ScriptText $scriptfornonwindows -ScriptType Bash -ErrorAction Stop | Select -ExpandProperty ScriptOutput
$found = $true
}
catch [VMware.VimAutomation.ViCore.Types.V1.ErrorHandling.InvalidGuestLogin]{
$out2 = "Invalid logon"
}
catch{
$out2 = "any other output"
}
}
if(!$found){
try{
$out3 = Invoke-VMScript -VM $installfailedotheros.name -GuestUser "root" -GuestPassword "admin@12345" -ScriptText $scriptfornonwindows -ScriptType Bash -ErrorAction Stop | Select -ExpandProperty ScriptOutput
$found = $true
}
catch [VMware.VimAutomation.ViCore.Types.V1.ErrorHandling.InvalidGuestLogin]{
$out3 = "Invalid logon"
}
catch{
$out3 = "any other output"
}
}
Write-Output "VM: $($installfailedotheros.name): $found"
Write-Output "VM: $($installfailedotheros.name): $out1"
Write-Output "VM: $($installfailedotheros.name): $out2"
Write-Output "VM: $($installfailedotheros.name): $out3"
}
Try changing line 21 into
$tasklist = Get-Task | Where-Object {$_.Name -eq 'UpgradeTools_Task' -and $_.State -eq 'Error'}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks Guru the script is working as expected But while executing on multiple resources pools simultaneously I found that a logic I missed that the error tasks in vcenter which are still not cleared the script is again trying to mount the tools and running invoke cmd. So is there any way to fix it or should I wait until all the old tasks error tasks get cleared before running on other resource pools.
No, you could get the time at the start of the script, and in the While-construct only look at Tasks that were started after that time.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Sure, I will give a try.
Like this way? If not please correct.
I can able to fetch tasks (get-task) in between $scriptstarttime and $scriptendtime. When executed separately.
$time=Get-Date -DisplayHint Time
$timeend=Get-Date -DisplayHint Time
Get-Task |? {$_.StartTime -ge $time -and $_.StartTime -le $timeend -and 'Running','Queued','Success' -contains $_.State}
Below is the script.
$scriptstarttime=Get-Date -DisplayHint Time
Write-Host 'Fetching Resource Pools Info'
$allresourcepools = 'SEZ02'
$respExpression = "^$($allresourcepools -join '$|^')$"
foreach($resourcepool in (Get-View -ViewType ResourcePool -Filter @{'Name'=$respExpression})){
Write-Host "Fetching VMs in $resourcepool"
$vmsinresourcepool = Get-View -Id $resourcepool.Vm
$vmtoolsoutdate = $vmsinresourcepool|Where-Object {$_.guest.ToolsRunningStatus -eq 'guestToolsRunning' -and $_.guest.toolsversionstatus -eq 'guestToolsNeedUpgrade'}
$vmexpression= "^$($vmtoolsoutdate.name -join '$|^')$"
$vmtoolsupdate=Get-View -ViewType VirtualMachine -Filter @{'Name'=$vmexpression}
$msoutdate=Get-View -ViewType VirtualMachine -Filter @{'Name'=$vmexpression} |?{$_.Guest.GuestFullName -like '*Windows*'}
$otheros=Get-View -ViewType VirtualMachine -Filter @{'Name'=$vmexpression} |?{$_.Guest.GuestFullName -notlike '*Windows*'}
$installerArgs = '/S /v "/qn REBOOT=R ADDLOCAL=ALL REMOVE=Hgfs,WYSE"'
%{($msoutdate).UpgradeTools_Task($installerArgs)} -ErrorAction SilentlyContinue
%{($otheros).UpgradeTools_Task($null)} -ErrorAction SilentlyContinue
$tasks = @(Get-Task | where{$_.Name -eq 'UpgradeTools_Task' -and $_.StartTime -ge $scriptstarttime -and 'Running','Queued' -contains $_.State})
while ($tasks.Count -ne 0){
sleep 5
$tasks = @(Get-Task | where{$_.Name -eq 'UpgradeTools_Task' -and $_.StartTime -ge $scriptstarttime -and 'Running','Queued' -contains $_.State})
}
$scriptendtime=Get-Date -DisplayHint Time
$tasklist = Get-Task | Where-Object {$_.Name -eq 'UpgradeTools_Task' -and $_.StartTime -ge $scriptstarttime -and $_.StartTime -le $scriptendtime -and $_.State -eq 'Error'}
$installfailedvms= Get-View -Id $tasklist.ObjectId -Property Name| Select-Object -ExpandProperty Name
Perhaps try like this
Write-Host 'Fetching Resource Pools Info'
$allresourcepools = 'SEZ02'
$respExpression = "^$($allresourcepools -join '$|^')$"
foreach($resourcepool in (Get-View -ViewType ResourcePool -Filter @{'Name'=$respExpression})){
Write-Host "Fetching VMs in $resourcepool"
$vmsinresourcepool = Get-View -Id $resourcepool.Vm
$vmtoolsoutdate = $vmsinresourcepool|Where-Object {$_.guest.ToolsRunningStatus -eq 'guestToolsRunning' -and $_.guest.toolsversionstatus -eq 'guestToolsNeedUpgrade'}
$vmexpression= "^$($vmtoolsoutdate.name -join '$|^')$"
$vmtoolsupdate=Get-View -ViewType VirtualMachine -Filter @{'Name'=$vmexpression}
$msoutdate=Get-View -ViewType VirtualMachine -Filter @{'Name'=$vmexpression} |?{$_.Guest.GuestFullName -like '*Windows*'}
$otheros=Get-View -ViewType VirtualMachine -Filter @{'Name'=$vmexpression} |?{$_.Guest.GuestFullName -notlike '*Windows*'}
$installerArgs = '/S /v "/qn REBOOT=R ADDLOCAL=ALL REMOVE=Hgfs,WYSE"'
$scriptstarttime=Get-Date
%{($msoutdate).UpgradeTools_Task($installerArgs)} -ErrorAction SilentlyContinue
%{($otheros).UpgradeTools_Task($null)} -ErrorAction SilentlyContinue
$scriptendtime=Get-Date
$tasks = @(Get-Task | where{$_.Name -eq 'UpgradeTools_Task' -and $_.StartTime -gt $scriptstarttime -and $_.StartTime -lt $scriptendtime -and 'Running','Queued' -contains $_.State})
while ($tasks.Count -ne 0){
sleep 5
$tasks = @(Get-Task | where{$_.Name -eq 'UpgradeTools_Task' -and $_.StartTime -gt $scriptstarttime -and $_.StartTime -lt $scriptendtime -and 'Running','Queued' -contains $_.State})
}
$tasklist = Get-Task | Where-Object {$_.Name -eq 'UpgradeTools_Task' -and $_.StartTime -gt $scriptstarttime -and $_.StartTime -lt $scriptendtime -and $_.State -eq 'Error'}
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks Guru. Its working as expected. Once I will give try on multiple clusters by adding leftover lines in the script. If any error I will post here.