
Restart Stopping Objects in vROps
Here is a quick post about a problem I faced a couple of months back. Every now and then I found that there are some VM objects in the stopping state in vROps. Upon investigation this happened due to an patch script, that tries to set the VMs in a stopped state. But somehow not all VMs reach that state and get stuck in the stopping state. This then impacts the collection of metrics and thus impacts proper alerting. In order to counter this, I wrote the following script. It simply checks the state of the VMs and if that state is stopping is stops and starts the collection again.
<# Author: Kabir Ali - info@kablog.nl Script name: RSO (Restart Stopping Objects) Version: 1.0 (Tested) Date: Oct 7 2020 Why: Due to patching the collection is stopped for all VMs... but sometimes not all objects reach that stage and remain stuck with status "STOPPING" Remark: Test setup vROps Version: 8.1.1 (16522874) #> <# How it works: Collect a list of all VMs. Find VMs with collection state STOPPING. Stop and start collection for those VMs. Example: .\RSO.ps1 -vROpsServer "vROps.local.domain" -vROpsUser "API-User" -vROpsPass "VMware1!" #> ### Define Defaults ### Param ( [Parameter(Mandatory = $true)][string]$vROpsServer, [Parameter(Mandatory = $true)][string]$vROpsUser, [Parameter(Mandatory = $true)][string]$vROpsPass ) # Bypass SSL certificate verification add-type @" using System.Net; using System.Security.Cryptography.X509Certificates; public class TrustAllCertsPolicy : ICertificatePolicy { public bool CheckValidationResult( ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem) { return true; } } "@ [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ### vROps API Connection ### #Building vROps API string & invoking REST API $vROpsURL = "https://" + $vROpsServer + "/suite-api/api/" $vROpsAuthURL = "https://" + $vROpsServer + "/suite-api/api/auth/token/acquire" $Type = "application/json" # Creating JSON for Auth Body $AuthJSON = "{ ""username"": ""$vROpsUser"", ""password"": ""$vROpsPass"" }" # Authenticating with API Try { $vROpsSessionResponse = Invoke-RestMethod -Method POST -Uri $vROpsAuthURL -Body $AuthJSON -ContentType $Type } Catch { $_.Exception.ToString() $error[0] | Format-List -Force write-host "Failed to login to vROps server:" $vROpsServer -ForegroundColor RED Break } # Extracting the session ID from the response $vROpsSessionHeader = @{"Authorization"="vRealizeOpsToken "+$vROpsSessionResponse.'auth-token'.token "Accept"="application/json"} ### Main Code ### # Collect a list of virtualMachines from vROps $VMColState = $null $ResourcesURL = $vROpsURL+"resources?resourceKind=VirtualMachine&pageSize=10000" $VMColState = Invoke-RestMethod -Method GET -Uri $ResourcesURL -Headers $vROPSSessionHeader -ContentType $Type # Outerloop to loop trough the collected VM list, Innerloop for the Collection state of that resource [array]$VMFullStatus = @() foreach ($VM in ($VMColState.resourceList | where {$_.ResourceStatusStates.resourceState -like "STOPPING"})) { foreach ($Instance in $VM.resourceStatusStates) { $VMFullStatus += New-Object PSObject -Property @{ "VM Name" = $VM.resourceKey.name "VM ID" = $VM.identifier "adapterInstanceId" = $Instance.adapterInstanceId "resourceState" = $Instance.resourceState } } } # Filter on resource status STOPPING $StoppingVMs = $VMFullStatus | where {$_.resourceState -like "STOPPING"} # There are multiple solutions, so 1 VM can have multiple stopping states. All solutions start/stop based on VM ID, so filter on ID and grab only unique IDs $UniqueVMs = $StoppingVMs."VM ID" | sort -Unique # Start stop based on collected unique VM object ID foreach ($UniqueID in $UniqueVMs) { $ResourcesURL = $vROpsURL+'resources/'+$UniqueID+'/monitoringstate/stop' write-host "Stopping VM:" (($StoppingVMs | where {$_."VM ID" -eq $UniqueID})."VM name" | select -First 1) -ForegroundColor RED Invoke-RestMethod -Method PUT -Uri $ResourcesURL -Headers $vROPSSessionHeader -ContentType $Type Sleep 15 $ResourcesURL = $vROpsURL+'resources/'+$UniqueID+'/monitoringstate/start' write-host "Starting VM:" (($StoppingVMs | where {$_."VM ID" -eq $UniqueID})."VM name" | select -First 1) -ForegroundColor GREEN Invoke-RestMethod -Method PUT -Uri $ResourcesURL -Headers $vROPSSessionHeader -ContentType $Type Write-host "---- ---- ---- ----" Sleep 15 } # Close sessions and done Invoke-RestMethod -Method POST -Uri https://$vROpsServer/suite-api/api/auth/token/release -Headers $vROpsSessionHeader -ContentType $Type