vRealize Operations

VCSA License Reporting in vRealize Operations Manager

Multiple customers recently have asked me if they could report on vCenter/vSphere licenses in vRealize Operations Manager (vROps).  Unfortunately, even with the extensive set of metrics and properties pulled from vCenter into vROps, license information is not included in that set.  Now, one of my initial recommendations, especially for properties which are likely not to change often, is to utilize PowerCLI to pull the required information from vCenter and push it to vROps.

Now, I’m not one to reinvent the wheel (lazy by nature?), so I searched the internet and found this blog which details how to extract license information from vCenter via PowerCLI, format and print it out.

So, that solves half of the issue, now let’s discuss pushing the data into vROps.  There are great blogs Getting Started with PowerCLI for vROPs and Using Entire API vROps via PowerCLI from my colleagues that discuss how to add Properties to vROps via PowerCLI:

So, I set out to write a PowerCLI script (given below) that does this:

  1. Connect to vROps and obtain the list of vCenter/VCSA instances
  2. For each vCenter Instance, obtain the Licensing information (Name, Key, Expiration, etc.)
  3. For each vCenter instance, push the license information into vROps as Properties of each vCenter (ResourceKind “VMwareAdapter Instance”).

Now, we are not just doing this for fun (or maybe we are) – we really want to create a Dashboard or Report that shows this data.  This led me to another problem to solve.  I really wanted each license to be listed separately – I really didn’t want one License property with a string that contained the names, keys, expiration date, etc. of all of the licenses.  I wanted the Name of the license to be included in the Hierarchy/Tree of the Properties themselves.  Something like this:

Properties|Licenses|<License Name>|<Properties>

With five properties listed for each License – Name, Key, License Capacity, Licenses Used, Expiration Date.

This created a problem which is: If you don’t know the names of the Licenses, then it’s difficult to create a View, Dashboard, and Report that lists all of the licenses.  You would have to select each property for all of the licenses discovered in your View or Dashboard.  This sounded painful.  However, I know that there is a way to display Instance Metrics – it is a powerful capability of the View construct.  It is a capability that allows you to display the same metric or metrics within a View for all instances of that component object.  For instance, in the View wizard below, you see that I am selecting some metrics for CPU#1 of a Virtual Machine:

Now what if I wanted to display the same metrics for CPU #0?  I could also select those metrics from CPU #0.   But what if you have many metrics and many CPU Instances?  The better way is to select the metrics you would like to be displayed for one instance, and then turn on the Instance breakdown feature of the View construct:

If you do this, and then on the Data screen select the Show Only Instance Name checkbox, and then refresh the Preview, you’ll see that now there is an Instance column, and the metric is shown for all CPU instances:

Last, if there is a non-instance aggregate metric, with checking that Checkbox, you will get that aggregate metric also:

This is all fine, but can this be done with Properties?  Is there such a thing as an Instance Property?  As it turns out, there is.

The format of an instance Metric or Property is a bit different than a normal Metric or Property.  A normal metric or property is of the format:

Folder|subfolder|Component|Metric, with the delimiter of “|”.  Here are some examples:

PS C:\> Get-OMStatKey -resource $vm | findstr "OnlineCapacity"
OnlineCapacityAnalytics|diskspace|... GB      VirtualMachine          The recommended level of usable capacity to mai...
OnlineCapacityAnalytics|timeRemaining Day(s)  VirtualMachine          Number of days remaining after which the usable...
OnlineCapacityAnalytics|diskspace|... GB      VirtualMachine          Amount of usable capacity that is available for...
OnlineCapacityAnalytics|mem|capaci... KB      VirtualMachine          Amount of usable capacity that is available for...
OnlineCapacityAnalytics|diskspace|... %       VirtualMachine          Capacity Remaining expressed as a percentage of...
OnlineCapacityAnalytics|cpu|recomm... MHz     VirtualMachine          The recommended level of usable capacity to mai...
OnlineCapacityAnalytics|cpu|capaci... %       VirtualMachine          Capacity Remaining expressed as a percentage of...
OnlineCapacityAnalytics|cpu|capaci... MHz     VirtualMachine          Amount of usable capacity that is available for...
OnlineCapacityAnalytics|diskspace|... Day(s)  VirtualMachine          Number of days remaining after which the usable...
OnlineCapacityAnalytics|mem|capaci... %       VirtualMachine          Capacity Remaining expressed as a percentage of...
OnlineCapacityAnalytics|cpu|timeRe... Day(s)  VirtualMachine          Number of days remaining after which the usable...
OnlineCapacityAnalytics|capacityRe... %       VirtualMachine          Capacity Remaining expressed as a percentage of...
OnlineCapacityAnalytics|mem|timeRe... Day(s)  VirtualMachine          Number of days remaining after which the usable...
OnlineCapacityAnalytics|mem|recomm... KB      VirtualMachine          The recommended level of usable capacity to mai...
PS C:\>

Which are these metrics:

But an Instance Metric’s format is this:

Folder|subFolder:Component|Metric, with the delimiter of “:” for the Component name.  Here is an example:

PS C:\> Get-OMStatKey -resource $vm | findstr "readyPct"
cpu|readyPct                          %       VirtualMachine          Percentage of CPU the VM is ready to run, but u...
cpu:1|readyPct                                VirtualMachine
cpu:0|readyPct                                VirtualMachine
PS C:\>

You can see the format of the aggregated metric, as well as for the two CPU instance metrics.

Armed with that knowledge, I setup the Licenses as Instance Properties.  You can see in the PowerCLI script how I name the Licenses Properties (the StatKey).  This is the StatKey for the License Key Value:

  $contentprop.StatKey = "Licenses:" + $Details.Name + "|key"

So, when you run the script, you should see output such as this:

After a few minutes, you should see new Properties:

 

I then created my View and Dashboard:

Conclusion:

vRealize Operations Manager is a powerful platform with many different display capabilities – Dashboards with the many Widget constructs, Views, and Reports – with many options to manipulate the data for Dashboarding or Reporting in the format desired.  This use-case took advantage of the View construct’s Instance Breakdown.  vRealize Operations Manager also has a multitude of APIs and SDKs – all based on the RESTful API – that allow for insertion and extraction of data in/out of vROps.  This use-case took advantage of the PowerCLI interface to vROps.

PopulateVCSA_LicenseKeyInfoToVROPs.ps1:

# Set to multiple VC Mode
if(((Get-PowerCLIConfiguration).DefaultVIServerMode) -ne "Multiple") {
Set-PowerCLIConfiguration -DefaultVIServerMode Multiple | Out-Null
}

# Make sure you connect to your VCs here
# $vcs = Connect-VIServer -Server vcsa-01a.corp.local -User Administrator -Password VMware1!
$user = Read-Host "Please enter the username for your vcsa instances"
#$pw = Read-Host "Please enter the password for your vcsa instances" -AsSecureString
$pw = Read-Host "Please enter the password for your vcsa instances"


# Now connect to vROps
$fqdn = Read-Host "Please enter the FQDN of your vROps instance"
#$vropspw = Read-Host "Please enter the local admin password for your vROPs instance" -AsSecureString
$vropspw = Read-Host "Please enter the local admin password for your vROPs instance" 
echo "=============================================="
echo "Attempting to connect to your vROps Instance: " $fqdn
$vrops = Connect-OMServer -Server $fqdn -User admin -Password $vropspw

# From vROps, get the VCSA instances
$vcsas = Get-OMResource -ResourceKind "VMwareAdapter Instance"

# For each vcsa instance, extract the FQDN of the instance and connect to it.
Foreach ($vcI in $vcsas) {
echo "======================================"
echo "Obtained vROps vCenter Instance Name: " $vcI.Name
$resourceIds = $vcI.ExtensionData.ResourceKey.ResourceIdentifiers.GetEnumerator()
Foreach ($ris in $resourceIds) {
# if ($ris.Value.contains($vcI.Name)) {
if ($ris.Value.contains(".")) {
$vcname = $ris.Value
$vcsa = Get-OMResource -name $vcI.Name
}
}
echo "============================================="
echo "Attempting to connect to VCSA Instance FQDN: " $vcname
$vcs = Connect-VIServer -Server $vcname -User $user -Password $pw
# echo "vCenter Instance Full Listing:"
# $vcs | FL

# Get the license info from each VC in turn
$vSphereLicInfo = @()
$ServiceInstance = Get-View ServiceInstance
Foreach ($LicenseMan in Get-View ($ServiceInstance | Select -First 1).Content.LicenseManager) {
Foreach ($License in ($LicenseMan | Select -ExpandProperty Licenses)) {
$Details = "" |Select VC, Name, Key, Total, Used, ExpirationDate , Information
$Details.VC = ([Uri]$LicenseMan.Client.ServiceUrl).Host
$Details.Name= $License.Name
$Details.Key= $License.LicenseKey
$Details.Total= $License.Total
$Details.Used= $License.Used
$Details.Information= $License.Labels | Select -expand Value
$Details.ExpirationDate = $License.Properties | Where { $_.key -eq "expirationDate" } | Select -ExpandProperty Value
$vSphereLicInfo += $Details

echo "============================================="
echo "Attempting to set License Properties for VCSA/License: " $vcname $Details.Name

# Set Name 
$contentprop = New-Object VMware.VimAutomation.VROps.Views.PropertyContent
$contentprops = New-Object VMware.VimAutomation.VROps.Views.PropertyContents
$contentprop.StatKey = "Licenses:" + $Details.Name + "|name"
$contentprop.values = @($Details.Name)
$contentprop.timestamps = [double]::Parse((Get-Date -UFormat %s))
$contentprops.propertycontent = @($contentprop)
$vcsa.ExtensionData.AddProperties($contentprops)

# Set Key
$contentprop = New-Object VMware.VimAutomation.VROps.Views.PropertyContent
$contentprops = New-Object VMware.VimAutomation.VROps.Views.PropertyContents
$contentprop.StatKey = "Licenses:" + $Details.Name + "|key"
$contentprop.values = @($Details.Key)
$contentprop.timestamps = [double]::Parse((Get-Date -UFormat %s))
$contentprops.propertycontent = @($contentprop)
$vcsa.ExtensionData.AddProperties($contentprops)

# Set Capacity 
$contentprop = New-Object VMware.VimAutomation.VROps.Views.PropertyContent
$contentprops = New-Object VMware.VimAutomation.VROps.Views.PropertyContents
$contentprop.StatKey = "Licenses:" + $Details.Name + "|capacity"
$contentprop.values = @($Details.Total)
$contentprop.timestamps = [double]::Parse((Get-Date -UFormat %s))
$contentprops.propertycontent = @($contentprop)
$vcsa.ExtensionData.AddProperties($contentprops)

# Set Assigned 
$contentprop = New-Object VMware.VimAutomation.VROps.Views.PropertyContent
$contentprops = New-Object VMware.VimAutomation.VROps.Views.PropertyContents
$contentprop.StatKey = "Licenses:" + $Details.Name + "|assigned"
$contentprop.values = @($Details.Used)
$contentprop.timestamps = [double]::Parse((Get-Date -UFormat %s))
$contentprops.propertycontent = @($contentprop)
$vcsa.ExtensionData.AddProperties($contentprops)

# Set Expiration Date 
$contentprop = New-Object VMware.VimAutomation.VROps.Views.PropertyContent
$contentprops = New-Object VMware.VimAutomation.VROps.Views.PropertyContents
$contentprop.StatKey = "Licenses:" + $Details.Name + "|expiration"
$contentprop.values = @($Details.ExpirationDate)
$contentprop.timestamps = [double]::Parse((Get-Date -UFormat %s))
$contentprops.propertycontent = @($contentprop)
$vcsa.ExtensionData.AddProperties($contentprops)
}
}
# $vSphereLicInfo | Format-Table -AutoSize

}