Sorting bits into bytes...

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 -
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
$vROpsSessionResponse = Invoke-RestMethod -Method POST -Uri $vROpsAuthURL -Body $AuthJSON -ContentType $Type
$error[0] | Format-List -Force
write-host "Failed to login to vROps server:" $vROpsServer -ForegroundColor RED
# Extracting the session ID from the response
$vROpsSessionHeader = @{"Authorization"="vRealizeOpsToken "+$vROpsSessionResponse.'auth-token'.token

### 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 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


Leave a Reply