Monitoring Studio X REST API through TSPS: Global Monitoring Inventory

How to get a hardware/software asset using Monitoring Studio X and Hardware Sentry KM. Inventory scripts available on GitHub.

Related Topics

Introduction

Assessing the monitoring coverage of a large environment can be challenging. Luckily, Monitoring Studio X and Hardware Sentry KM offer a REST API that can be leveraged to build a monitoring inventory. In this article, you will learn how to create the inventoryFunctions.ps1 PowerShell script that reports the number of monitored systems (which can be useful to count the number of required licenses too).

PowerShell Script reports the number of monitored systems
The scripts below are designed for PowerShell version 5.1.
The corresponding inventoryFunctions PowerShell and bash scripts are available for download on GitHub.

Prerequisites

Before leveraging Sentry’s REST API to get your license usage, you will have to:

  • set the SSL certificate verification
  • collect the required TSPS information
  • get an authentication token
  • get the list of all PATROL Agents attached to your server.

Setting the SSL Certificate Verification

If your TrueSight Presentation Server does not have a recognized SSL certificate, add the following line at the top of your script:

[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}

Collecting the Required TSPS Information

To collect the Username, Password, TSPS HostName and TSPS Port and allow the HTTP query timeout to be configurable,

  • either use the following command line arguments:
# Assign Arguments to variables
$username=$args[0]
$hostname=$args[1]
$port=$args[2]
$timeout=$args[3]
  • or set arguments in the script:
# Pre-set Arguments instead
# TSPS Rest Credentials
$username="admin"
$password="admin"
$hostname="pub-tsps113"
$port="8043"
$timeout="10"

Getting an Authentication Token

To get an authentication token from TSPS, create a Get-Token function that queries the TrueSight Web Service (TSWS) login API /tsws/10.0/api/authenticate/login using Invoke-RestMethod. This function should be listed first in any script as it will be referenced by other functions to request a new token should the query fails.

# Get-Token Function
# Used by functions so should be first in script
function Get-Token
{
$body = @{ 
  'username'=$username
  'password'=$password
  'tenantName'='*'
  }
$tokenJSON = Invoke-RestMethod -TimeoutSec $timeout -Method Post -Uri "https://${hostname}:${port}/tsws/10.0/api/authenticate/login" -Body $body 
if($?) {
  $Script:token = $tokenJSON.response.authToken
  }
}

Example Result:

The authentication token is stored in the $token variable: $token = _9315a572-a9e4-42ff-9352-325834c4f900

Getting the List of PATROL Agents Attached to a Server

Because the list of PATROL Agents is not available from TSPS, you need to create the Get-ListOfAgents function that will query the PATROL Agents via TSPS and Integration Services using /tsws/10.0/api/unifiedadmin/Server/details. The full DNS address and ports, as listed in Configuration > Managed Devices in TSPS, are required for all PATROL Agents you want to query.

Example:

pc-isabelle2.internal.sentrysoftware.net/3181
pptagent.internal.sentrysoftware.net/3600
pub-pa95.internal.sentrysoftware.net/3185

To query all PATROL Agents attached to the server, you can run the following query and extract the PATROL Agent list from the JSON response:

# Get a List of Agents
# Requires Get-Token to be run first
function Get-ListOfAgents {
$patrolAgentJSON = Invoke-RestMethod -TimeoutSec $timeout -Method Post -Uri "https://${hostname}:${port}/tsws/10.0/api/unifiedadmin/Server/details" -Headers @{Authorization = "authToken $token"}  -ContentType "application/json" -Body "{}" 
if($?) {
  $Script:patrolAgentList = foreach($patrolAgent in $patrolAgentJSON.response.serverList.integrationServiceDetails.patrolAgentDetails) {
    if ( $patrolAgent ) {
	  echo "$($patrolAgent.hostname)/$($patrolAgent.agentPort)" 
      }
    }
  }
}

Example Results:

The list of PATROL Agents is stored in the $patrolAgentList variable:

$patrolAgentList = 
pc-isabelle2.internal.sentrysoftware.net/3181
pptagent.internal.sentrysoftware.net/3600
pub-pa95.internal.sentrysoftware.net/3185

Leveraging Sentry’s REST API

Now that all prerequisites are met, you can leverage Sentry’s REST API to get your license usage for Monitoring Studio X and Hardware Sentry KM, i.e the number of hosts being monitored by both products.

Number of Hosts Being Monitored by Monitoring Studio X

To know how many hosts are being monitored by Monitoring Studio X, create the Get-MonitoringStudioLicenseCount function that will query the following URL for all PATROL Agents listed in $patrolAgentList:

https://$hostname:$port/tsws/10.0/api/studio/$patrolAgent/rest/namespace/X_HOST/numInstances

where

  • $hostname and $port are the hostname and port of TSPS
  • $patrolAgent is the PATROL Agent name and port obtained by the Get-ListOfAgents function described above

The Get-MonitoringStudioLicenseCount requires the PATROL Agent fqdn/port ( $patrolAgent) as the first argument.

# Get Monitoring Studio License Count
# Requires Get-ListOfAgents and Get-Token to be run first
function Get-MonitoringStudioLicenseCount {
$ErrorActionPreference = 'SilentlyContinue'
$monitoringStudioLicenseCountTotal = 0
ForEach ($patrolAgent in $patrolAgentList){
  $monitoringStudioLicenseCount = ""
  $monitoringStudioLicenseCount = Invoke-RestMethod -TimeoutSec $timeout -Method Get -Uri "https://${hostname}:${port}/tsws/10.0/api/studio/${patrolAgent}/rest/namespace/X_HOST/numInstances" -Headers @{Authorization = "authToken $token"}
  if($?) { 
    if ( $monitoringStudioLicenseCount.value ) {
	  # We got a license count, so print
	  echo "$patrolAgent $($monitoringStudioLicenseCount.value)" 
	  $monitoringStudioLicenseCountTotal = $monitoringStudioLicenseCountTotal + $($monitoringStudioLicenseCount.value)
	  }
	else {
		echo "$patrolAgent Monitoring Studio GUI Not Installed"
      }
	}
  else {
    echo "$patrolAgent Monitoring Studio KM Not Responding" 
	# If a query fails, we have to go back and get a new token
    Get-Token
	}
  }
echo "Total Monitoring Studio License Count: $monitoringStudioLicenseCountTotal"
}

The Get-MonitoringStudioLicenseCount function returns:

  • the number of licenses used if the Monitoring Studio X is installed
  • “null” otherwise.

Example result:

License usage for Monitoring Studio X

Number of Hosts Being Monitored by Hardware Sentry KM

To know how many hosts are being monitored by Hardware Sentry KM, you can:

  • either retrieve the value of the Count-Host parameter
  • or get the full hardware inventory directly from the PATROL Agent.

Retrieving the Value of the Count-Host Parameter

If you opt for this solution, create the Get-HardwareLicenseCount function that will query $hostname:$port/tsws/10.0/api/studio/$patrolAgent/rest/namespace/MS_HW_KM/HardwareSentry/Count-Host

where

  • $hostname and $port are the hostname and port of TSPS
  • $patrolAgent is the PATROL Agent name and port obtained by the Get-ListOfAgents function described above

The Get-HardwareLicenseCount function requires the PATROL Agent fqdn/port (see $patrolAgent) as the first argument:

# Get Hardware License Count
# Requires Get-ListOfAgents and Get-Token to be run first
function Get-HardwareLicenseCount {
$ErrorActionPreference = 'SilentlyContinue'
$hardwareLicenseCountTotal = 0
ForEach ($patrolAgent in $patrolAgentList){
  $hardwareLicenseCount = ""
  $hardwareCount = Invoke-RestMethod -TimeoutSec $timeout -Method Get -Uri "https://${hostname}:${port}/tsws/10.0/api/studio/${patrolAgent}/rest/namespace/MS_HW_KM/HardwareSentry/Count-Host" -Headers @{Authorization = "authToken $token"}
  if($?) { 
    echo "$patrolAgent $($hardwareCount.value)" 
	$hardwareLicenseCountTotal = $hardwareLicenseCountTotal + $($hardwareCount.value)
	}
  else {
    echo "$patrolAgent Hardware KM Not Installed or Not Responding" 
	# If a query fails, we have to go back and get a new token
    Get-Token
	}
  }
echo "Total Monitoring Studio License Count: $hardwareLicenseCountTotal"
}

The Get-HardwareLicenseCount function returns:

  • the number of licenses used if Hardware Sentry KM is installed
  • “null” otherwise.

Example result:

License usage for Hardware Sentry KM

Getting a Full Hardware Inventory Directly from the PATROL Agent

If you opt for this solution, create the Get-HardwareInventories function.

This function requires:

The Get-HardwareInventories function relies on a token ($token) and a PATROL Agent List ($patrolAgentList) in the format fqdn/port.

# Get Hardware Inventories
# Requires Get-ListOfAgents and Get-Token to be run first
function Get-HardwareInventories {
$ErrorActionPreference = 'SilentlyContinue'
ForEach ($patrolAgent in $patrolAgentList){
  # Get the Monitoring Studio KM Version (To ensure it's installed)
  $monitoringStudioVersion = ""
  $monitoringStudioVersion = Invoke-RestMethod -TimeoutSec $timeout -Method Get -Uri "https://${hostname}:${port}/tsws/10.0/api/studio/${patrolAgent}/rest/agent" -Headers @{Authorization = "authToken $token"} 
  # If a query fails, we have to go back and get a new token
  if(!$?) { 
     Get-Token
    }
  if( $monitoringStudioVersion.studioVersion.string -match '^1' ) {
    echo "$patrolAgent has Monitoring Studio GUI $($monitoringStudioVersion.studioVersion.string) installed"
    } else {
	echo "$patrolAgent does not have Monitoring Studio GUI installed or is not responding $($monitoringStudioVersion.studioVersion.string)"
	# skip everything else for this Patrol Agent
	continue
	}
  # Get the Hardware KM Version (To ensure it's compatible.)
  $hardwareVersion = ""
  $hardwareVersion = Invoke-RestMethod -TimeoutSec $timeout -Method Get -Uri "https://${hostname}:${port}/tsws/10.0/api/studio/${patrolAgent}/rest/config/SENTRY/HARDWARE/currentVersion" -Headers @{Authorization = "authToken $token"; "accept"="application/json" }
  # If a query fails, we have to go back and get a new token
  if(!$?) { 
     Get-Token
    }
  if ( $hardwareVersion.value -eq "" ) {
    echo "$patrolAgent does not have Hardware KM installed"
	# skip everything else for this Patrol Agent
	continue	
    } 
  elseif ( $hardwareVersion.value -match '^10.[2-9]' -Or $hardwareVersion.value -match '^1[1-9]' ) {
	echo "$patrolAgent has Hardware KM $($hardwareVersion.value) installed"
    }
  else {
    echo "$patrolAgent has Hardware KM $($hardwareVersion.value) installed, which is not compatible"
	# skip everything else for this Patrol Agent
	continue
    }
	
  # Ok, we're happy suitable versions of the Monitoring Studio KM and Hardware KM are installed.
  # Get a Monitored Host List
  if(!(test-path .\Hardware-Inventories )) { New-Item -ItemType Directory -Force -Path ./Hardware-Inventories | Out-Null }
  $hardwareHostListCSV = ""
  $hardwareHostListCSV = Invoke-RestMethod -TimeoutSec $timeout -Method Get -Uri "https://${hostname}:${port}/tsws/10.0/api/studio/${patrolAgent}/rest/namespace/MS_HW_MAIN/instances" -Headers @{Authorization = "authToken $token"; "accept"="application/json" }
  # If a query fails, we have to go back and get a new token
  if(!$?) { 
    Get-Token
    }
  if ($hardwareHostListCSV.value -eq "") { 
    echo "$patrolAgent is not monitoring any hardware hosts"
	# skip everything else for this Patrol Agent
	continue	
    }
  # The hostlist is a list inside the value, so we need to convert it to an object list PowerShell likes
  $hardwareHostList = $hardwareHostListCSV.value  |  ConvertFrom-Csv -Header 'value'
  ForEach ( $hardwareHost in $hardwareHostList ) { 
    if ($hardwareHost.value -eq "") { continue }
    $hardwareHostValue = $hardwareHost.value
	$hardwareHostInventory=Invoke-RestMethod -TimeoutSec $timeout -Method Get -Uri "https://${hostname}:${port}/tsws/10.0/api/studio/${patrolAgent}/rest/mshw/report/$hardwareHostValue" -Headers @{Authorization = "authToken $token"}
	# If a query fails, we have to go back and get a new token
    if(!$?) { 
       Get-Token
      }    
	# Create a folder for this Agent Instance and Output json Inventory File
	if(!(test-path .\Hardware-Inventories\$patrolAgent )) { New-Item -ItemType Directory -Force -Path ./Hardware-Inventories/$patrolAgent | Out-Null }
	$hardwareHostInventory | ConvertTo-Json | Out-File .\Hardware-Inventories\$hardwareHostValue.json
	$hardwareName = $hardwareHostInventory | Where-Object className -eq "MS_HW_ENCLOSURE" | ForEach-Object {$_.name}
	if ($hardwareName) {
	  echo "$patrolAgent Monitors $hardwareHostValue which is a $hardwareName"
	  }
	else {
	  echo "$patrolAgent Monitors $hardwareHostValue does not have an enclosure.  Suspect monitoring not working correctly."
	  }
    }
  }
}

Example result:

Getting a full hardware inventory directly from the PATROL Agent

Additional Resources

For more information about Sentry’s REST APIs, refer to: