For your reference, here are the articles in this mini-series:


I've been spending quite a bit of time with vRealize Operations Manager (vROps) lately, mostly running reports. While this is easy enough to do via the web UI, I found myself running a report, downloading the .csv, and then importing the data into PowerShell to work with it. Obviously, I turned to PowerCLI to see if I could do this all in PowerShell! However, I quickly vRealized (see what I did there) that the vROps PowerCLI module currently does not contain many Cmdlets, as shown below.

Get-Command -Module VMware.VimAutomation.vROps

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Function        Get-vROpsCommand                                   10.0.0.... VMware.VimAutomation.vROps
Cmdlet          Connect-OMServer                                   10.0.0.... VMware.VimAutomation.vROps
Cmdlet          Disconnect-OMServer                                10.0.0.... VMware.VimAutomation.vROps
Cmdlet          Get-OMAlert                                        10.0.0.... VMware.VimAutomation.vROps
Cmdlet          Get-OMAlertDefinition                              10.0.0.... VMware.VimAutomation.vROps
Cmdlet          Get-OMAlertSubType                                 10.0.0.... VMware.VimAutomation.vROps
Cmdlet          Get-OMAlertType                                    10.0.0.... VMware.VimAutomation.vROps
Cmdlet          Get-OMRecommendation                               10.0.0.... VMware.VimAutomation.vROps
Cmdlet          Get-OMResource                                     10.0.0.... VMware.VimAutomation.vROps
Cmdlet          Get-OMStat                                         10.0.0.... VMware.VimAutomation.vROps
Cmdlet          Get-OMStatKey                                      10.0.0.... VMware.VimAutomation.vROps
Cmdlet          Get-OMUser                                         10.0.0.... VMware.VimAutomation.vROps
Cmdlet          Set-OMAlert                                        10.0.0.... VMware.VimAutomation.vROps

Don't get me wrong - this is a good start but doesn't help me run reports. So, I had a look around online and found a great blog post by John Dias on using the entire vROps REST API via PowerCLI. I won't go into massive detail because I think John is far more informative than I would be, but essentially it explains that the entire vROps API is available by manipulating the extensionData container via PowerCLI.

For example: if you connect to your vROps server as follows,

$vrops = Connect-OMServer -Server -User "admin" -Password "Password" -AuthSource "Local Users"

You can then use the $vrops object to access the extensionData. Piping to the Get-Member Cmdlet allows you to see all of the properties and methods available.

$vrops.ExtensionData | Get-Member

   TypeName: VMware.VimAutomation.VROps.Views.ServerApi

Name                                          MemberType Definition
----                                          ---------- ----------
AcquireToken                                  Method     VMware.VimAutomation.VROps.Views.AuthToken AcquireToken(VMware.VimAutomation.VROps.Views.UsernamePassword input)
AcquireTokenAsync                             Method     System.Threading.Tasks.Task[VMware.VimAutomation.VROps.Views.AuthToken] AcquireTokenAsync(System.Threading.CancellationToken cancellationToken, V...
AddAuthSource                                 Method     VMware.VimAutomation.VROps.Views.AuthSource AddAuthSource(VMware.VimAutomation.VROps.Views.AuthSource input)
AddAuthSourceAsync                            Method     System.Threading.Tasks.Task[VMware.VimAutomation.VROps.Views.AuthSource] AddAuthSourceAsync(System.Threading.CancellationToken cancellationToken,...
AddLicenseKeyToProduct                        Method     VMware.VimAutomation.VROps.Views.SolutionLicenses AddLicenseKeyToProduct(VMware.VimAutomation.VROps.Views.SolutionLicenses input)
AddLicenseKeyToProductAsync                   Method     System.Threading.Tasks.Task[VMware.VimAutomation.VROps.Views.SolutionLicenses] AddLicenseKeyToProductAsync(System.Threading.CancellationToken can...
AddStatsForResources                          Method     void AddStatsForResources(VMware.VimAutomation.VROps.Views.ResourcesStatContents input, System.Nullable[bool] disableAnalyticsProcessing)
AddStatsForResourcesAsync                     Method     System.Threading.Tasks.Task AddStatsForResourcesAsync(System.Threading.CancellationToken cancellationToken, VMware.VimAutomation.VROps.Views.Reso...
AddStatsForResourcesUsingPushAdapterKind      Method     void AddStatsForResourcesUsingPushAdapterKind(string adapterKind, VMware.VimAutomation.VROps.Views.ResourcesStatContents input, System.Nullable[b...
AddStatsForResourcesUsingPushAdapterKindAsync Method     System.Threading.Tasks.Task AddStatsForResourcesUsingPushAdapterKindAsync(System.Threading.CancellationToken cancellationToken, string adapterKin...
ChangePassword                                Method     void ChangePassword(VMware.VimAutomation.VROps.Views.PasswordChange input)
ChangePasswordAsync                           Method     System.Threading.Tasks.Task ChangePasswordAsync(System.Threading.CancellationToken cancellationToken, VMware.VimAutomation.VROps.Views.PasswordCh...

I have cut the list short as there are hundreds of properties and methods available, but you can see that this is how all the vROps REST API methods are made available in PowerCLI.

With this information, and the vROps API documentation that can be accessed via your vROps appliance (e.g., I was able to generate and download a report as a powershell object. This mini-series will guide you through how I did it, starting with generating a report.

Generating A Report

The first step is to generate a report. This is made possible by the CreateReport() method of the extensionData container. Looking at the API documentation, you will see that this method takes the <ns3:report> object as its input. The <ns3:report> model shows that it has the following three required properties.

Name Description Type Required
resourceId Resource identifier for which the Report needs to be generated. xs:uuid yes
reportDefinitionId Identifier of the Report Definition used to generate this Report. xs:uuid yes
traversalSpec The traversal spec for which the Report Definition needs to be applied. ns3:traversal-spec yes

Let's take a look at getting the resourceId first, as there is already a cmdlet for this in the VMware.VimAutomation.vROps module. So, if I wanted to get the Id for the vSphere World resource, I would use the following.

Import-Module VMware.VimAutomation.vROps
Get-OMResource -Name "vSphere World" | Select-Object Id


That was easy. Next, let's take a look at getting the reportDefinitionId for the report that we want to generate. In this example, I am going to use the Oversized VMs report. Unfortunately, there is not a cmdlet for this yet, so we have to use the extensionData container as explained previously. If you haven't done so already, connect to your vROps instance like so.

$vrops = Connect-OMServer -Server -User "admin" -Password "Password" -AuthSource "Local Users"

Now, we can use the GetReportDefinitions() method to search through the available reports and find the Id of the report that we want. I'm using the third parameter of this method to filter the results by name.

$vrops.ExtensionData.GetReportDefinitions($null, $null, "Oversized Virtual Machines").ReportDefinition

Name                 : Optimization Report - Oversized Virtual Machines
Description          : Oversized VMs Report.
Subject              : {Virtual Machine}
Traversalspecs       : {vSphere Networking, Custom Datacenters, vCAC CDC View, VM Dependency...}
LastRunTime          : 01/01/0001 00:00:00
LastRunTimeSpecified : False
Owner                : admin
Links                :
Any                  :
Id                   : 1f69952f-7ff4-4d2c-9446-81a811de19b0
CreationTime         : 01/01/0001 00:00:00
Active               : True
ActiveSpecified      : True
AnyAttr              :

I hope you agree that that also wasn't too difficult. However, now comes the slightly trickier part. We need to use a traversalSpec to tell vROps which inventory to traverse when generating the report. You can list all available traversalSpecs by calling the GetTraversalSpecs() method.


You may have noticed when looking at the <ns3:report> model previously that the traversalSpec property actually expects to receive a <ns3:traversal-spec> object, not a string Id as is the case with the other two properties. Therefore, we need to create a traversalSpec object to use with the CreateReport() method. I am targeting the vSphere Hosts and Clusters traversalSpec for this example, so let's filter the results from the previous command.

$vrops.ExtensionData.GetTraversalSpecs($null, $null, "vSphere Hosts and Clusters").TraversalSpec

Name                       : vSphere Hosts and Clusters
Description                : Enables view of resources imported from vCenter like Clusters, Hosts, VMs and ResourcePools
RootAdapterKindKey         : VMWARE
RootResourceKindKey        : vSphere World
Any                        :
AdapterInstanceAssociation : False
AnyAttr                    :

We can use this information to build a traversalSpec object. If you look at the API documentation for the <ns3:traversal-spec> model, you will find that there is only one required property, which is the Name. However, during testing I found that I also needed to specify the RootAdapterKindKey and the RootResourceKindKey. Therefore, we can create the object and assign the property values as follows.

$TraversalSpec = New-Object VMware.VimAutomation.VROps.Views.TraversalSpec
$TraversalSpec.Name = "vSphere Hosts and Clusters"
$TraversalSpec.RootAdapterKindKey = "VMWARE"
$TraversalSpec.RootResourceKindKey = "vSphere World"

Now we have all of the required properties for the <ns3:report> object we can piece this all together and finally generate the report!

First, we need to create a report object in our PowerShell session.

$Report = New-Object VMware.VimAutomation.VROps.Views.Report

Next, we can set the three required properties on the report object using the information we just collected.

$Report.ResourceId = "26717f44-cd8d-486a-821f-e1df41bb49b3"
$Report.ReportDefinitionId = "1f69952f-7ff4-4d2c-9446-81a811de19b0"
$Report.TraversalSpec = $TraversalSpec

Finally, we can run the CreateReport() method to generate the report!


Name               :
Description        : Oversized VMs Report.
ResourceId         : 26717f44-cd8d-486a-821f-e1df41bb49b3
ReportDefinitionId : 1f69952f-7ff4-4d2c-9446-81a811de19b0
TraversalSpec      :
Subject            : VirtualMachine VirtualMachine
Owner              : f315d79d-72ac-46ff-a512-cb43073246c3
CompletionTime     : null
Status             : QUEUED
Links              : {linkToSelf, linkToResource, linkToReportDefinition}
Any                :
Id                 : 5ef2e8c9-09bb-4a74-b560-f9ad2e810854
AnyAttr            :

Congratulations - your report is now being generated! As you can see, its status is currently QUEUED. Depending on the size of your environment, it may take a while to complete. We can use the Id from above to check the status of the report.


Name               :
Description        : Oversized VMs Report.
ResourceId         : 26717f44-cd8d-486a-821f-e1df41bb49b3
ReportDefinitionId : 1f69952f-7ff4-4d2c-9446-81a811de19b0
TraversalSpec      :
Subject            : VirtualMachine VirtualMachine
Owner              : f315d79d-72ac-46ff-a512-cb43073246c3
CompletionTime     : Wed May 16 12:07:50 BST 2018
Status             : COMPLETED
Links              : {linkToSelf, linkToResource, linkToReportDefinition}
Any                :
Id                 : 5ef2e8c9-09bb-4a74-b560-f9ad2e810854
AnyAttr            :

If you log into your vROps web UI, you should now see your generated report.

Next Steps

That was a lot of information but I hope it has helped you to understand the concepts of manipulating the entire vROps API using the extensionData container in PowerCLI and, more specifically, how to generate a report. Check back for part 2 of this mini-series, where I will demonstrate how to retreive the generated report as a PowerShell object.