What is this?

This knowledgebase contains questions and answers about PRTG Network Monitor and network monitoring in general.

Learn more

PRTG Network Monitor

Intuitive to Use. Easy to manage.
More than 500,000 users rely on Paessler PRTG every day. Find out how you can reduce cost, increase QoS and ease planning, as well.

Free Download

Top Tags


View all Tags

PRTG Nvidia Grid Sensor

Votes:

0

Hi to all of you, I am posting a help request as I need to create a PRTG Output for a superb Nvidia Grid License Overview Powershell Script that was created by John Billekens and that you can find here:

https://blog.j81.nl/2018/11/08/view-nvidia-grid-license-details-via-powershell/

The PowerShell scripts works perfectly even with multiple Nvidia Grid Licenses, the only issue I have not being a PowerShell Pro is to write to PRTG multiple licenses outputs.

Here is the script:

<#
.SYNOPSIS
    Get the Nvidia License Feature Details
.DESCRIPTION
    Get the Nvidia License Feature Details
.EXAMPLE
    Get-NvidiaLicencedFeatureDetails.ps1
    View all license details 
.EXAMPLE
    Get-NvidiaLicencedFeatureDetails.ps1 | Where-Object {$_.FeatureName -eq "GRID-Virtual-PC" }
    View all GRID-Virtual-PC licenses
.NOTES
    File Name : Get-NvidiaLicencedFeatureDetails.ps1
    Version   : v1.1
    Author    : John Billekens
    Requires  : PowerShell v5 and up
                Nvidia License server
.PARAMETER URI
    Specify the License server URI
    Default Value: http://localhost:8080/
.PARAMETER MaxIDs
    Specify the Max number of IDs being scanned, if you miss licenses, try to enter an higher ID (only for large companies or with multiple licenses)
    Default Value: 20
.LINK
    https://blog.j81.nl
#>
[CmdletBinding(DefaultParameterSetName = "URI")]
param (
    [Parameter(ParameterSetName = "URI", Position = 0)]
    [ValidatePattern('^(http[s]?)(:\/\/)([^\s,]+)')]
    [System.URI]$URI = "http://localhost:8080/",

    [Parameter(ParameterSetName = "Other")]
    [ValidateNotNullOrEmpty()]
    [String]$Protocol = "http",

    [Parameter(ParameterSetName = "Other")]
    [ValidateNotNullOrEmpty()]
    [string]$ServerFQDN = "localhost",

    [Parameter(ParameterSetName = "Other")]
    [ValidateNotNullOrEmpty()]
    [string]$ServerPort = "8080",

    [Parameter(ParameterSetName = "URI")]
    [Parameter(ParameterSetName = "Other")]
    [ValidateNotNullOrEmpty()]
    [Int]$MaxIDs = 20,

    [Parameter(ParameterSetName = "URI")]
    [Parameter(ParameterSetName = "Other")]
    [Switch]$Summary
)
#requires -version 5.0

if (-Not ($PSCmdlet.ParameterSetName -eq "URI")) {
    Write-Warning "-Protocol, -ServerFQDN and -ServerPort are legacy parameters"
    $URI = [System.URI]"{0}://{1}:{2}/" -f $Protocol, $ServerFQDN, $ServerPort
}
$LicencedFeatureDetails = [PSCustomObject]@()
$ErrorLoopCount = 0
$DataFound = $false
for ($i = 1; $i -le $MaxIDs; $i++) {
    try {
        $URL = "{0}licserver/manageFeatureUsage_featureDetails.action?feature.featureId={1}&page=1" -f $URI.AbsoluteUri, $i
        $Response = Invoke-WebRequest -UseBasicParsing -Uri $URL
        $FeatureName = try { $Response.RawContent | Where-Object { $_ -match '(?:<span class="heading1"><a title=")(?<FeatureName>[a-zA-Z-]+?)"' } | ForEach { $matches['FeatureName'] } } catch { $null }
        if (-not [String]::IsNullOrEmpty($FeatureName)) {
            $Version  = try { $Response.RawContent | Where-Object { $_ -match '(?:.+?(?=Version).+?(?=;));(?<Version>.+?(?= <))' } | ForEach { $matches['Version'] } } catch { $null }
            $TotalCount = try { $Response.RawContent | Where-Object { $_ -match '(?:.+?(?=Total count).+?(?=;));(?<TotalCount>.+?(?= <))' } | ForEach { $matches['TotalCount'] } } catch { $null }
            $Available = try { $Response.RawContent | Where-Object { $_ -match '(?:.+?(?=Available).+?(?=;));(?<Available>.+?(?= <))' } | ForEach { $matches['Available'] } } catch { $null }
            $CurrentUsage = try { $Response.RawContent | Where-Object { $_ -match '(?:.+?(?=Current Usage).+?(?=;));(?<CurrentUsage>.+?(?= <))' } | ForEach { $matches['CurrentUsage'] } } catch { $null }
            $ReservedCount = try { $Response.RawContent | Where-Object { $_ -match '(?:.+?(?=Reserved Count).+?(?=;));(?<ReservedCount>.+?(?= <))' } | ForEach { $matches['ReservedCount'] } } catch { $null }
            $VendorString = try { $Response.RawContent | Where-Object { $_ -match '(?:.+?(?=Vendor String).+?(?=;));(?<VendorString>.+?(?= <))' } | ForEach { $matches['VendorString'] } } catch { $null }
            $FeatureExpiry = try { $Response.RawContent | Where-Object { $_ -match '(?:.+?(?=Feature Expiry).+?(?=;));(?<FeatureExpiry>.+?(?=\s))' } | ForEach { $matches['FeatureExpiry'] } } catch { $null }

            try {
                $FeatureExpiry = [DateTime]::Parse($FeatureExpiry)
                $FeaturesDaysLeft = (New-TimeSpan -Start $(Get-Date) -End $FeatureExpiry).Days
                if ($FeaturesDaysLeft -lt 1) {
                    Write-Warning "License `"$FeatureName`" (ID: $i) is expired!"
                } elseif ($FeaturesDaysLeft -lt 90) {
                    Write-Warning "The `"$FeatureName`" (ID: $i) license will expire in $FeaturesDaysLeft days!"
                }
            } catch {
                $FeatureExpiry = $FeatureExpiry
                $FeaturesDaysLeft = -1
            }
            
            $CurrentUsageClients = [PSCustomObject]@{
                ClientID         = [string]""
                ClientIDType     = [string]""
                ClientType       = [string]""
                TotalCountServed = [Int32]0
                Expiry           = [Nullable[DateTime]]$null 
            }

            $Pattern = '(?:.+?(?=TRTableBorderBottom)(?s:.)+?(?=<a title=).+?(?=>))>(?<ClientID>.+?(?=<))(?:(?s:.)+?(?=<a title=).+?(?=>))>(?<ClientIDType>.+?(?=<))(?:(?s:.)+?(?=<a title=).+?(?=>))>(?<ClientType>.+?(?=<))(?:(?s:.)+?(?=[0-9]))(?<TotalCountServed>[0-9])(?:(?s:.)+?(?=[0-9]))(?<Expiry>[a-zA-Z0-9-:.]*)'
            $RxMatches = Select-String -InputObject $Response.RawContent -Pattern $pattern -AllMatches
            
            try {
                $CurrentUsageClients = $RxMatches.Matches | ForEach-Object { [PSCustomObject]@{
                    ClientID         = $(try { $_.Groups["ClientID"].Value } catch { $null })
                    ClientIDType     = $(try { $_.Groups["ClientIDType"].Value } catch { $null })
                    ClientType       = $(try { $_.Groups["ClientType"].Value } catch { $null })
                    TotalCountServed = $(try { [Int32]::Parse($($_.Groups["TotalCountServed"].Value)) } catch { $($_.Groups["TotalCountServed"].Value) })
                    Expiry           = $(try { [DateTime]::Parse($($_.Groups["Expiry"].Value)) } catch { $($_.Groups["Expiry"].Value) })
                                }
                }
            } catch { }
            $LicencedFeatureDetails += [PSCustomObject]@{
                ID                  = $i
                FeatureName         = $FeatureName
                Version             = $Version
                TotalCount          = $(try { [int]::Parse($TotalCount) } catch { $TotalCount } )
                Available           = $(try { [int]::Parse($Available) } catch { $Available } )
                CurrentUsage        = $(try { [int]::Parse($CurrentUsage) } catch { $CurrentUsage } )
                ReservedCount       = $(try { [int]::Parse($ReservedCount) } catch { $ReservedCount } )
                VendorString        = $VendorString
                FeatureExpiry       = $FeatureExpiry
                FeatureDaysLeft     = $FeaturesDaysLeft
                Uri                 = $URL
                CurrentUsageClients = $CurrentUsageClients
            }
        } elseif ($Data -like "*Error:*") {
            if ($DataFound) {
                $ErrorLoopCount++
            }
            if ($ErrorLoopCount -ge 20) {
                break
            }
        } 
    } catch {
        $ErrorLoopCount++
        Write-Verbose "Error Message: $_.Exception.Message"
    }
}
if ($Summary) {
    $LicencedFeatureDetails | Format-Table -Property ID,FeatureName,FeatureExpiry,TotalCount,CurrentUsage -AutoSize
} else {
    return $LicencedFeatureDetails
}

Here is the PowerShell Output when you have 3 Licenses Active

WARNING: The "GRID-Virtual-PC" (ID: 1) license will expire in 46 days!
WARNING: The "GRID-Virtual-PC" (ID: 3) license will expire in 46 days!


ID                  : 1
FeatureName         : GRID-Virtual-PC
Version             : 2.0
TotalCount          : 30
Available           : 30
CurrentUsage        : 0
ReservedCount       : 0
VendorString        : GRID-Virtual-PC-1
FeatureExpiry       : 08.08.2021 00:00:00
FeatureDaysLeft     : 46
Uri                 : http://nexcomp01:8080/licserver/manageFeatureUsage_featur
                      eDetails.action?feature.featureId=1&page=1
CurrentUsageClients : @{ClientID=; ClientIDType=; ClientType=; 
                      TotalCountServed=0; Expiry=}

ID                  : 2
FeatureName         : GRID-Virtual-PC
Version             : 2.0
TotalCount          : 3
Available           : 1
CurrentUsage        : 2
ReservedCount       : 0
VendorString        : GRID-Virtual-PC-1
FeatureExpiry       : 11.03.2022 00:00:00
FeatureDaysLeft     : 261
Uri                 : http://nexcomp01:8080/licserver/manageFeatureUsage_featur
                      eDetails.action?feature.featureId=2&page=1
CurrentUsageClients : {@{ClientID=0050569236C3; ClientIDType=ETHERNET; 
                      ClientType=VIRTUAL; TotalCountServed=1; 
                      Expiry=23.06.2021 18:14:59}, @{ClientID=005056922CEB; 
                      ClientIDType=ETHERNET; ClientType=VIRTUAL; 
                      TotalCountServed=1; Expiry=23.06.2021 18:16:59}}

ID                  : 3
FeatureName         : GRID-Virtual-PC
Version             : 2.0
TotalCount          : 30
Available           : 0
CurrentUsage        : 30
ReservedCount       : 0
VendorString        : GRID-Virtual-PC-2
FeatureExpiry       : 08.08.2021 00:00:00
FeatureDaysLeft     : 46
Uri                 : http://nexcomp01:8080/licserver/manageFeatureUsage_featur
                      eDetails.action?feature.featureId=3&page=1
CurrentUsageClients : {@{ClientID=00505692A44A; ClientIDType=ETHERNET; 
                      ClientType=VIRTUAL; TotalCountServed=1; 
                      Expiry=23.06.2021 16:29:59}, @{ClientID=005056923DB2; 
                      ClientIDType=ETHERNET; ClientType=VIRTUAL; 
                      TotalCountServed=1; Expiry=23.06.2021 16:30:59}, 
                      @{ClientID=005056928421; ClientIDType=ETHERNET; 
                      ClientType=VIRTUAL; TotalCountServed=1; 
                      Expiry=23.06.2021 16:47:59}, @{ClientID=0050569242AF; 
                      ClientIDType=ETHERNET; ClientType=VIRTUAL; 
                      TotalCountServed=1; Expiry=23.06.2021 17:18:59}...}

The desired channels in PRTG would be:

License ID
Total Count
Available
Current Usage
FeatureExpiry
FeatureDaysLeft

I managed to get the output to PRTG for one license but I am a little ashamed to post the end of my script as it's not very "clean", oh well

Write-Host "<prtg>"
           "<text>Feature Name: GRID-Virtual-PC / Feature Expiry: $FeatureExpiry / Feature Days Left: $FeaturesDaysLeft / Available License(s):$Available</text>"
Write-Host "<result>"
           "<channel>Total Count</channel>"
           "<value>$TotalCount</value>"
           "</result>"
Write-Host "<result>"
           "<channel>Available</channel>"
           "<value>$Available</value>"
           "</result>"
Write-Host "<result>"
           "<channel>Feature Days Left</channel>"
           "<value>$FeaturesDaysLeft</value>"
           "</result>"
Write-Host "</prtg>" 

I would be very grateful if someone could help me further, I promise I'll get myself a crush course in Advanced PowerShell Scripting.

Thank you in advance for your help.

BR Greg

exexml nvidia powershell

Created on Jun 22, 2021 7:07:12 PM



1 Reply

Votes:

0

Hello Greg,

Thank you for your message.

To return the information in PRTG, I would recommend to use a Foreach loop on your variable $LicencedFeatureDetails which contains an object for each licence, and then return the data by using the following code:

$prtg        = '' | select prtg
$results     = @()

try {
    $channels = @("TotalCount","Available","CurrentUsage","FeatureExpiry", "FeatureDaysLeft")
    foreach ($obj in $LicencedFeatureDetails){
        foreach ($channel in $channels){
            $result = @{
                channel     = "$channel (ID $($obj.ID))"
                value       = $obj."$channel"
            }
            $results += $result
        }   
    }
    $prtg.prtg        = '' | select result
    $prtg.prtg.result = $results

}catch{
    $prtg.prtg        = '' | select error
    $prtg.prtg.error  = 1
    $prtg.prtg | Add-Member -MemberType NoteProperty -Name 'text' -Value $null
    $prtg.prtg.text   = '{0} at line : {1}' -f $_.Exception.Message, $_.InvocationInfo.PositionMessage
}finally{
    $prtgJson = $prtg | ConvertTo-Json -Depth 5
    $prtgJson
    if ($prtg.prtg.error) {
        Exit 1
    } else {
        Exit 0
    }
}

Please, note that the code might need to be adapted and we can't provide support for it.

Here is an example of output provided by it :

{
  "prtg": {
    "result": [
      {
        "value": 10,
        "channel": "TotalCount (ID 1)"
      },
      {
        "value": 1,
        "channel": "Available (ID 1)"
      },
      {
        "value": 9,
        "channel": "CurrentUsage (ID 1)"
      },
      {
        "value": 10,
        "channel": "FeatureExpiry (ID 1)"
      },
      {
        "value": 10,
        "channel": "FeatureDaysLeft (ID 1)"
      }
...
    ]
  }
}

Regards.

Created on Jun 23, 2021 2:16:07 PM by  Florian Lesage [Paessler Support]




Disclaimer: The information in the Paessler Knowledge Base comes without warranty of any kind. Use at your own risk. Before applying any instructions please exercise proper system administrator housekeeping. You must make sure that a proper backup of all your data is available.