If you have ever needed to insert custom metrics (stats) into a vRops object this next post is for you!
I needed to extract some metrics from vCenter for host NIC’s which are not available in vRops by default…. so I built this powershell script to extract and push the metrics into vRops using the suite-api.
So the script calls vCenter using PowerCLI and Get-Esxcli to get the stats for all hosts which are connected, powered on & for the NIC’s that are “connected”… it then uses the suite-api to push those metrics into vRops.
Here is an example from the GUI and the API:
As you can see below the metrics now exist in vRops for the object
And here is an example of it in the api
The script can be setup on a scheduled task using parameters below…
.\CustomNetStats-API2vROPS -vRopsAddress 'vRops.vMan.ch' -vc 'vc.vMan.ch' -vRopsCreds 'vRops' -vcCreds 'vc'
and here is the script!!
####### Collect some counters for vmnic's on hosts which are PoweredOn and where vmnic is connected #######
#Collects metrics and pushes them into vRops related HostSystem.
#v1.0 vMan.ch, 15.07.2018 - Initial Version
param
(
[String]$vRopsAddress,
[String]$vcAddress,
[String]$vRopsCreds,
[String]$vcCreds
)
# Usage
# .\CustomNetStats-API2vROPS -vRopsAddress 'vRops.vMan.ch' -vc 'vc.vMan.ch' -vRopsCreds 'vRops' -vcCreds 'vc'
#Functions
#Get vRops ResourceID from Name
Function GetObject([String]$vRopsObjName, [String]$resourceKindKey, [String]$vRopsServer, $vRopsCredentials){
$vRopsObjName = $vRopsObjName -replace ' ','%20'
[xml]$Checker = Invoke-RestMethod -Method Get -Uri "https://$vRopsServer/suite-api/api/resources?resourceKind=$resourceKindKey&name=$vRopsObjName" -Credential $vRopsCredentials -Headers $header -ContentType $ContentType
#Check if we get 0
if ([Int]$Checker.resources.pageInfo.totalCount -eq '0'){
Return $CheckerOutput = ''
}
else {
# Check if we get more than 1 result and apply some logic
If ([Int]$Checker.resources.pageInfo.totalCount -gt '1') {
$DataReceivingCount = $Checker.resources.resource.resourceStatusStates.resourceStatusState.resourceStatus -eq 'DATA_RECEIVING'
If ($DataReceivingCount.count -gt 1){
If ($Checker.resources.resource.ResourceKey.name -eq $vRopsObjName){
ForEach ($Result in $Checker.resources.resource){
IF ($Result.resourceStatusStates.resourceStatusState.resourceStatus -eq 'DATA_RECEIVING'){
$CheckerOutput = New-Object PsObject -Property @{Name=$vRopsObjName; resourceId=$Result.identifier; resourceKindKey=$Result.resourceKey.resourceKindKey}
Return $CheckerOutput
}
}
}
}
Else
{
ForEach ($Result in $Checker.resources.resource){
IF ($Result.resourceStatusStates.resourceStatusState.resourceStatus -eq 'DATA_RECEIVING'){
$CheckerOutput = New-Object PsObject -Property @{Name=$vRopsObjName; resourceId=$Result.identifier; resourceKindKey=$Result.resourceKey.resourceKindKey}
Return $CheckerOutput
}
}
}
}
else {
$CheckerOutput = New-Object PsObject -Property @{Name=$vRopsObjName; resourceId=$Checker.resources.resource.identifier; resourceKindKey=$Checker.resources.resource.resourceKey.resourceKindKey}
Return $CheckerOutput
}
}
}
$ScriptPath = (Get-Item -Path ".\" -Verbose).FullName
if($vRopsCreds -gt ""){
$vRopsCred = Import-Clixml -Path "$ScriptPath\config\$vRopsCreds.xml"
}
else
{
echo "vRops Credentials not specified, stop hammer time!"
Exit
}
if($vcCreds -gt ""){
$vcCred = Import-Clixml -Path "$ScriptPath\config\$vcCreds.xml"
}
else
{
echo "VC Credentials not specified, stop hammer time!"
Exit
}
[DateTime]$NowDate = (Get-date)
[int64]$NowDateEpoc = Get-Date -Date $NowDate.ToUniversalTime() -UFormat %s
$NowDateEpoc = $NowDateEpoc * 1000
#Take all certs.
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]::Tls
#Stuff for Invoke-RestMethod
$ContentType = "application/xml"
$header = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$header.Add("Accept", 'application/xml')
$header.Add("User-Agent", 'vRopsPowershellMetricExtractor/1.0')
#Connect to VC's
Connect-viserver -Server $vcAddress -Credential $vcCred -Force
$Report = @()
$esxihosts = Get-VMHost | Sort-Object
foreach ($esxihost in $esxihosts | Where-Object {$_.ConnectionState -match "Connected" -and $_.PowerState -match "PoweredOn"}) {
$esxcli = Get-Esxcli -v2 -VMHost $esxihost
foreach ($Nic in $esxcli ){
ForEach ($N in $Nic.network.nic.list.Invoke() | Where-Object {$_.Link -match "Up"}){
$NicData = $esxcli.network.nic.stats.get.invoke(@{nicname = $N.Name})
$Report += New-Object PSObject -Property @{
"ESXiHost" = $esxihost.name
"VMNIC" = $N.Name
"ReceiveCRCerrors" = $NicData.ReceiveCRCerrors
"ReceiveFIFOerrors" = $NicData.ReceiveFIFOerrors
"Receiveframeerrors" = $NicData.Receiveframeerrors
"Receivelengtherrors" = $NicData.Receivelengtherrors
"Receivemissederrors" = $NicData.Receivemissederrors
"Receiveovererrors" = $NicData.Receiveovererrors
"Receivepacketsdropped" = $NicData.Receivepacketsdropped
"TotalReceiveerrors" = $NicData.TotalReceiveerrors
"Totaltransmiterrors" = $NicData.Totaltransmiterrors
"TransmitFIFOerrors" = $NicData.TransmitFIFOerrors
"Transmitabortederrors" = $NicData.Transmitabortederrors
"Transmitcarriererrors" = $NicData.Transmitcarriererrors
"Transmitheartbeaterrors" = $NicData.Transmitheartbeaterrors
"Transmitpacketsdropped" = $NicData.Transmitpacketsdropped
"Transmitwindowerrors" = $NicData.Transmitwindowerrors
"Date" = $NowDateEpoc
}
}
}
}
#Push in Metrics
$HostList = @()
$HostList = $Report.ESXiHost | unique
$MetricXML = @('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ops:stat-contents xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ops="http://webservice.vmware.com/vRealizeOpsMgr/1.0/">')
ForEach ($Hst in $HostList){
$resourceid = GetObject $Hst 'HostSystem' $vRopsAddress $vRopsCred
ForEach ($MetricInsert in $Report | where {$_.ESXiHost -eq $Hst}){
If($resourceid.resourceId -gt '') {
$MetricXML += @('<ops:stat-content statKey="vMAN|net|'+$MetricInsert.VMNIC+'|ReceiveMissedErrors">
<ops:timestamps>'+$MetricInsert.Date+'</ops:timestamps>
<ops:data>'+$MetricInsert.ReceiveMissedErrors+'</ops:data>
<ops:unit>num</ops:unit>
</ops:stat-content>
<ops:stat-content statKey="vMAN|net|'+$MetricInsert.VMNIC+'|Receivepacketsdropped">
<ops:timestamps>'+$MetricInsert.Date+'</ops:timestamps>
<ops:data>'+$MetricInsert.Receivepacketsdropped+'</ops:data>
<ops:unit>num</ops:unit>
</ops:stat-content>
<ops:stat-content statKey="vMAN|net|'+$MetricInsert.VMNIC+'|Transmitpacketsdropped">
<ops:timestamps>'+$MetricInsert.Date+'</ops:timestamps>
<ops:data>'+$MetricInsert.Transmitpacketsdropped+'</ops:data>
<ops:unit>num</ops:unit>
</ops:stat-content>
<ops:stat-content statKey="vMAN|net|'+$MetricInsert.VMNIC+'|Transmitwindowerrors">
<ops:timestamps>'+$MetricInsert.Date+'</ops:timestamps>
<ops:data>'+$MetricInsert.Transmitwindowerrors+'</ops:data>
<ops:unit>num</ops:unit>
</ops:stat-content>
<ops:stat-content statKey="vMAN|net|'+$MetricInsert.VMNIC+'|Transmitheartbeaterrors">
<ops:timestamps>'+$MetricInsert.Date+'</ops:timestamps>
<ops:data>'+$MetricInsert.Transmitheartbeaterrors+'</ops:data>
<ops:unit>num</ops:unit>
</ops:stat-content>
<ops:stat-content statKey="vMAN|net|'+$MetricInsert.VMNIC+'|TransmitFIFOerrors">
<ops:timestamps>'+$MetricInsert.Date+'</ops:timestamps>
<ops:data>'+$MetricInsert.TransmitFIFOerrors+'</ops:data>
<ops:unit>num</ops:unit>
</ops:stat-content>
<ops:stat-content statKey="vMAN|net|'+$MetricInsert.VMNIC+'|Transmitabortederrors">
<ops:timestamps>'+$MetricInsert.Date+'</ops:timestamps>
<ops:data>'+$MetricInsert.Transmitheartbeaterrors+'</ops:data>
<ops:unit>num</ops:unit>
</ops:stat-content>
<ops:stat-content statKey="vMAN|net|'+$MetricInsert.VMNIC+'|Receiveovererrors">
<ops:timestamps>'+$MetricInsert.Date+'</ops:timestamps>
<ops:data>'+$MetricInsert.Receiveovererrors+'</ops:data>
<ops:unit>num</ops:unit>
</ops:stat-content>
<ops:stat-content statKey="vMAN|net|'+$MetricInsert.VMNIC+'|ReceiveCRCerrors">
<ops:timestamps>'+$MetricInsert.Date+'</ops:timestamps>
<ops:data>'+$MetricInsert.ReceiveCRCerrors+'</ops:data>
<ops:unit>num</ops:unit>
</ops:stat-content>
<ops:stat-content statKey="vMAN|net|'+$MetricInsert.VMNIC+'|TotalReceiveerrors">
<ops:timestamps>'+$MetricInsert.Date+'</ops:timestamps>
<ops:data>'+$MetricInsert.TotalReceiveerrors+'</ops:data>
<ops:unit>num</ops:unit>
</ops:stat-content>
<ops:stat-content statKey="vMAN|net|'+$MetricInsert.VMNIC+'|Receiveframeerrors">
<ops:timestamps>'+$MetricInsert.Date+'</ops:timestamps>
<ops:data>'+$MetricInsert.Receiveframeerrors+'</ops:data>
<ops:unit>num</ops:unit>
</ops:stat-content>
<ops:stat-content statKey="vMAN|net|'+$MetricInsert.VMNIC+'|ReceiveFIFOerrors">
<ops:timestamps>'+$MetricInsert.Date+'</ops:timestamps>
<ops:data>'+$MetricInsert.ReceiveFIFOerrors+'</ops:data>
<ops:unit>num</ops:unit>
</ops:stat-content>
<ops:stat-content statKey="vMAN|net|'+$MetricInsert.VMNIC+'|Transmitcarriererrors">
<ops:timestamps>'+$MetricInsert.Date+'</ops:timestamps>
<ops:data>'+$MetricInsert.Transmitcarriererrors+'</ops:data>
<ops:unit>num</ops:unit>
</ops:stat-content>
<ops:stat-content statKey="vMAN|net|'+$MetricInsert.VMNIC+'|Totaltransmiterrors">
<ops:timestamps>'+$MetricInsert.Date+'</ops:timestamps>
<ops:data>'+$MetricInsert.Totaltransmiterrors+'</ops:data>
<ops:unit>num</ops:unit>
</ops:stat-content>
<ops:stat-content statKey="vMAN|net|'+$MetricInsert.VMNIC+'|Receivelengtherrors">
<ops:timestamps>'+$MetricInsert.Date+'</ops:timestamps>
<ops:data>'+$MetricInsert.Receivelengtherrors+'</ops:data>
<ops:unit>num</ops:unit>
</ops:stat-content>')
}
}
$MetricXML += @('</ops:stat-contents>')
[xml]$MetricXML = $MetricXML
$vRopsMetricURL = 'https://' + $vRopsAddress + '/suite-api/api/resources/'+$resourceid.Resourceid+'/stats'
Invoke-RestMethod -Method POST -uri $vRopsMetricURL -Body $MetricXML -Credential $vRopsCred -ContentType "application/xml;charset=utf-8"
Remove-Variable vRopsMetricURL -ErrorAction SilentlyContinue
Remove-Variable MetricXML -ErrorAction SilentlyContinue
Remove-Variable MetricInsert -ErrorAction SilentlyContinue
}
Disconnect-viserver -server $vcAddress -Force -Confirm:$false
vMan




Recent Comments