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