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
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
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
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.
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
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
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
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
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
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
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
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 ) 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?
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
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
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
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
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
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
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
Are you still facing this issue? If so, then refer this or please ping me I can help you.