VMware Cloud Community
vin01
Expert
Expert
Jump to solution

vmware tools update using UpgradeTools_Task and Invoke-VMscript

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"

}

Regards Vineeth.K
Reply
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

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

View solution in original post

Reply
0 Kudos
12 Replies
LucD
Leadership
Leadership
Jump to solution

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

Reply
0 Kudos
vin01
Expert
Expert
Jump to solution

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.

Regards Vineeth.K
Reply
0 Kudos
vin01
Expert
Expert
Jump to solution

Hi LucD,

Any thoughts on my request.

Regards Vineeth.K
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

vin01
Expert
Expert
Jump to solution

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

tools error1.JPG

tools error2.JPG

tools error3.JPG

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" 

}

Regards Vineeth.K
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

Reply
0 Kudos
vin01
Expert
Expert
Jump to solution

Thanks Guru the script is working as expectedSmiley Happy 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.

Regards Vineeth.K
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

Reply
0 Kudos
vin01
Expert
Expert
Jump to solution

Sure, I will give a try.

Regards Vineeth.K
Reply
0 Kudos
vin01
Expert
Expert
Jump to solution

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

Regards Vineeth.K
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

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

Reply
0 Kudos
vin01
Expert
Expert
Jump to solution

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.

Regards Vineeth.K
Reply
0 Kudos