Nighthawkz
Enthusiast
Enthusiast

The guest operations agent is out of date, stopping script from continuing through loop

Jump to solution

advanced apology/warning!:

I have tried to format my post to show the script nicely/properly using guide I was previously pointed to by a member on here but it just won't (not sure if it's because it's quite long!) so my apologies ( I had this trouble before so I've attached my script instead)

my script is basically looping through every server on my estate, and determining a bunch of things and then getting the uptime of that server via the os guest (wasn't happy with the stat from the hosts itself) . it works fine until it finds a server where invoke-vmscript returns the error "the guest operations agent is out of date"

fine don't mind that i'll just pipe that in my csv, move on and look at it after.. problem is - it stops my script dead, instead of continuing on through the estate (of which I suspect there to be more or the same error)

I thought by checking the tool status (which can seen in the ELSE of the first IF)  before going down to the level of the actual OS checking it would filter/capture it but it seems to be ignoring this. How would I go about doing this with invoke-vmscript? do I simply need to do another if and do something based on the scripts output.

any guidance is appreciated

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership

I rearranged the script a bit.

The test for powered on and tools version out of date needs to be split.

Otherwise you risk a failing Invoke-VMScript due to an outdated tools version.

Also not sure what you want to do with that appliance block?

Try the attached version.
I couldn't actually test all of it, since there are some functions in there that I don't have.


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

View solution in original post

0 Kudos
20 Replies
LucD
Leadership
Leadership

I suspect your file attach didn't work either.

But, no matter, the reason your script stops is because it encounters an exception.

The "the guest operations agent is out of date" one.

To bypass that stop, encapsulate your Invoke-VMScript in aTry-Catch construct.

Something like this for example

Try {

    Invoke-VMScript -VM $vm -ScriptText $code -ScriptType Bash -ErrorAction Stop

}

Catch{

    Write-Error "Invoke-VMScript didn't work!"

}

This way the code in the Catch block will be executed when any exception is encountered.

And your script will continue.


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

0 Kudos
Nighthawkz
Enthusiast
Enthusiast

thanks for the prompt reply. my invoke already is in a try/catch block ,I've posted the entire thing below if my upload didn't work in case it helps!:

$VMs = @(Get-VM -name * |where {  $_.Name -notlike "vPOAD*" -and $_.Name -notlike "SRM_*" }) #| Get-View -Property @("Name", "Config.GuestFullName", "Guest.GuestFullName","Runtime.PowerState")

#$VMs = @(Get-VMwareComputer -Computer $Computers.Name -Verbose:$VerboseState)

foreach ($VM in $VMs) {

$OS = $vm.Guest.OSFullName

        # Determine if the computer is joined to the domain or not

       

            Try { $DomainJoineds = ComputerDomainStatus $VM.Name -Verbose:$VerboseState }

            Catch { Throw $_ }

        # Query the VM if it's on and tools are up to date (bypass toolsOld if specified).

        If ( $VM.PowerState -eq "PoweredOn" -and $VM.ExtensionData.Guest.ToolsStatus -eq "toolsOK" )

       

          {

        #determine if windows OR limux

       

         if ($VM.GuestId -like "*windows*") {

           

            # Authenticate

           

                # Get Admin credentials

              

                    Try { $VMCredentials = @(Get-ComputerCredential -KeePassDBPath $KeePassDBPath -KeePassPasswordFile $KeePassPasswordFile -DomainJoined:$DomainJoineds -OS $OS -Verbose:$VerboseState) }

                    Catch { Throw "Failed to obtain credentials from KeePass for $($VM.Name).`n$_" }

                

                    Foreach ( $VMCredential in $VMCredentials ) {

                       

                        $InvokeScriptParam =@{

                                ScriptText =  '$time = [Management.ManagementDateTimeConverter]::ToDateTime((gwmi Win32_OperatingSystem).LastBootUpTime)

                                                $convert = (get-date)-$time

                                                $Display = "Uptime: " + $convert.Days + " days, " + $convert.Hours + " hours, " + $convert.Minutes + " minutes"

                                                Write-Output $Display'         

                                 VM = $vm.Name

                                 GuestCredential = $VMCredential

                                 ErrorAction = "stop"

                                 ScriptType = 'Powershell'

                                          }

                                     try{ $output =  Invoke-VMScript @InvokeScriptParam #needs to be in a variable inorder to call the ScriptOutPut function

                                      $obj=  New-Object PSObject -Property @{

                                      name = $vm.Name

                                      uptime = $output.ScriptOutput

                                                                            }

                                      $obj | Export-Csv -Path C:\Users\l\Desktop\uptime4.csv -NoTypeInformation -append

                                    }

                                      catch {write-error "Failed to successfully login to $($VM.Name)"}

 

                } #Foreach

        } #end of windows check

elseif ($VM.GuestId -like '*sles*' -or '*linux*' -or '*centos*' -or '*cent0S*' -or '*rhe*'){

            # Authenticate, check then Install agent

          

                # Get Admin credentials (if not supplied)

               

                    Try { $VMCredentials = @(Get-ComputerCredential2 -KeePassDBPath $KeePassDBPath -KeePassPasswordFile $KeePassPasswordFile  -OS $OS -Verbose:$VerboseState) }

                    Catch { Throw "Failed to obtain credentials from KeePass for $($VM.Name).`n$_" }

               

                    Foreach ( $VMCredential in $VMCredentials ) {

                    $InvokeScriptParam =@{

                                           ScriptText = @'

                                           uptime | awk -F, '{sub(".*up ",x,$1);print $1}'

'@

                       

                                           VM = $VM.name

                                           GuestCredential = $VMCredential

                                           ErrorAction = "stop"

                                           }

                                  try{   $output = Invoke-VMScript @InvokeScriptParam

                                     $obj=  New-Object PSObject -Property @{

                                                                           name = $vm.Name

                                                                           uptime = $output.ScriptOutput

                                                                           }

                                     $obj | Export-Csv -Path C:\Users\l\Desktop\uptime4.csv -NoTypeInformation -append

                                    }

                                    catch {write-error "Failed to successfully login to $($VM.Name) as $($VMCredential.UserName)" }

                } #Foreach

 

        } #end of Linux check

  

else {if  ($VM.GuestId -like '*sles*' -or '*linux*' -or '*centos*' -or '*cent0S*'-and $vm.Guest.OSFullName -like "*other*")

                 {    $x= "appliance"

         

             }# end of appliance check

          }#last else

        }

        #else for teh powerstate/vmtoolcheck

        elseif ($VM.PowerState -eq "Poweredoff" -or $vm.ExtensionData.Guest.ToolsStatus -eq "toolsOld" ){$out = write-output "vm is turned off/vm has old version of vmtools upgrade!"

                                                                                     

                                     $output = Invoke-VMScript @InvokeScriptParam

                                     $obj=  New-Object PSObject -Property @{

                                                                           name = $vm.Name

                                                                           uptime = $out

                                                                           }

                                     $obj | Export-Csv -Path C:\Users\l\Desktop\uptime4.csv -NoTypeInformation -append

      

        } #end ofpowerstate

      #end of domain check

}#end of the ENTIRE script

Thanks is it the way i've constructed my invoke query prehaps? like i said - it works fine until it finds a vm where the tools are out of date.

0 Kudos
LucD
Leadership
Leadership

Can you include a screenshot of the error you are getting (and on which the script stops)?


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

0 Kudos
Nighthawkz
Enthusiast
Enthusiast

it's stopping here on this for loop (well - the invoke in this for loop) currently assuming it runs through the vm's in the same order each time I run the script, but i'd expct it to stop at any one if it hits the out of date tool:

elseif ($VM.GuestId -like '*sles*' -or '*linux*' -or '*centos*' -or '*cent0S*' -or '*rhe*'){

    

        

       

            # Authenticate, check then Install agent

          

                # Get Admin credentials (if not supplied)

               

                    Try { $VMCredentials = @(Get-ComputerCredential2 -KeePassDBPath $KeePassDBPath -KeePassPasswordFile $KeePassPasswordFile  -OS $OS -Verbose:$VerboseState) }

                    Catch { Throw "Failed to obtain credentials from KeePass for $($VM.Name).`n$_" }

               

                    Foreach ( $VMCredential in $VMCredentials ) {

                    $InvokeScriptParam =@{

                                           ScriptText = @'

                                           uptime | awk -F, '{sub(".*up ",x,$1);print $1}'

'@

                       

                                           VM = $VM.name

                                           GuestCredential = $VMCredential

                                           ErrorAction = "stop"

                                           }

                                  try{   $output = Invoke-VMScript @InvokeScriptParam

                                     $obj=  New-Object PSObject -Property @{

                                                                           name = $vm.Name

                                                                           uptime = $output.ScriptOutput

                                                                           }

                                     $obj | Export-Csv -Path C:\Users\lc\Desktop\uptime4.csv -NoTypeInformation -append

                                    }

                                    catch {write-error "Failed to successfully login to $($VM.Name) as $($VMCredential.UserName)" }

      

                }

hopefully the attched image shows!

cheers

0 Kudos
LucD
Leadership
Leadership

There might be a hint in KB2010065, it seems guest cmdlets are not backward compatible.

Which PowerCLI version are you using?

And on which vSphere version (ESXi version) are the VMs that have the issue running?


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

0 Kudos
Nighthawkz
Enthusiast
Enthusiast

PowerCLI Version

----------------

   VMware vSphere PowerCLI 6.0 Release 3 build 3205540

---------------

Component Versions

---------------

   VMWare AutoDeploy PowerCLI Component 6.0 build 2358282

   VMWare ImageBuilder PowerCLI Component 6.0 build 2358282

   VMware vSphere PowerCLI Component 6.0 build 3205541

VMware ESXi, 6.0.0, 7504637

0 Kudos
LucD
Leadership
Leadership

And the VMs with the error, do they show that their VMware Tools version needs to be updated?

Are those perhaps Linux boxes with VMware Tools that came with the guest OS?


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

0 Kudos
Nighthawkz
Enthusiast
Enthusiast

havign a look.....the VM was a linux machine but - it was powered off. so no idea why my filter:

If ( $VM.PowerState -eq "PoweredOn" -and $VM.ExtensionData.Guest.ToolsStatus -eq "toolsOK" )

didn't catch it initially with and just throw down the "powered off route" instead of trying to invoke the script

0 Kudos
LucD
Leadership
Leadership

Because it looks like you have the VM name in the $VM variable, not a VirtualMachine object.

And hence, the PowerState property does not exist.


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

0 Kudos
Nighthawkz
Enthusiast
Enthusiast

what would be the suggest correction to make it a vm objject in the first place?

I can't see (and i'm happy to be called stupid here Smiley Happy ) how it makes a difference, the option is being passsed through to be called/queried against  as if output $vm.powerstate to console i get the powerstate back

even outoutting $VM.PowerState -eq "PoweredOn" -and $VM.ExtensionData.Guest.ToolsStatus -eq "toolsOK"  brigns back a boolean result.

- but what you're saying is that actually it's not and so it can't be filtered against?

0 Kudos
Nighthawkz
Enthusiast
Enthusiast

would it be best to us get-view instead of get-vm at the very beginning when accumlatign all the vm's i want to query? ( i believe get-view is virtualmachien object anyway)

so instead of

$VMs = @(Get-VM -name "sles12-64-vcac"  |where {  $_.Name -notlike "vPOAD*" -and $_.Name -notlike "SRM_*" })

using

$vms = @(get-view -viewtype virtualmachine -filter {$_.name -notlike "vPOAD" -and $_.name -notlike "SRM_*"}

though $_.name wouldn't work

0 Kudos
LucD
Leadership
Leadership

No, keep it on Get-VM for now.

And I just noticed that you indeed do a Get-VM at the beginning.

It would help if you could attach you script as a file, the code at the top is rather mangled up.


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

0 Kudos
Nighthawkz
Enthusiast
Enthusiast

hopefully the attachement works now! thanks for all your help so far as well!

0 Kudos
LucD
Leadership
Leadership

I rearranged the script a bit.

The test for powered on and tools version out of date needs to be split.

Otherwise you risk a failing Invoke-VMScript due to an outdated tools version.

Also not sure what you want to do with that appliance block?

Try the attached version.
I couldn't actually test all of it, since there are some functions in there that I don't have.


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

View solution in original post

0 Kudos
Nighthawkz
Enthusiast
Enthusiast

i will take a look now thank you!

the appliance block was simpyl we have some appliances (load balaners etc) that i don't care about so if the script matches those filters it just inputs "this is an applicance" into the csv, and i'll worry abotu exlcuding it at a later date

0 Kudos
Nighthawkz
Enthusiast
Enthusiast

it workw beautifully, and i can see how splitting out the two checks was better - why i didn't do that initially is beyond me. Think I had it in my head something that simple couldn't have been the problem. anyway, tad bit of tweaking and it's running no problem

very much appreciated! thanks again

0 Kudos
Jamie_Langer
Contributor
Contributor

Even I'm looking for the solution for a similar issue. You can refer to a few reliable winding to english translator tools helped me to solve this issue, It might help you also thank you

0 Kudos
LucD
Leadership
Leadership

Can you open a new thread and provide the information?
The script you are using and a screenshot of the error or a description of the problem.


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

0 Kudos
animeshsaxena
Contributor
Contributor

Are you still facing this issue? If so, then refer this or please ping me I can help you.

0 Kudos