SolarWinds Integration
Surface CertTracker monitor data in SolarWinds Server & Application Monitor (SAM) as a custom Application via a PowerShell Script Component Monitor. SolarWinds runs the script on its polling interval, parses the output, and shows statuses + statistics in the standard Application page.
Community-validated recipe. CertTracker doesn't run a SolarWinds install in-house — this guide is based on SolarWinds' documented Script Component Monitor format. Tested in concept, not on a live SAM deployment. Corrections welcome via the community forum.
Plan required. API access is a Business and Enterprise plan feature. See API access for token creation.
Architecture
+-------------------+ +-----------------------+
| SolarWinds SAM | | CertTracker |
| | HTTPS | |
| Custom App | +-------> /api/v1/monitors |
| Script Component | | | |
| PowerShell | | +-----------------------+
| | | |
| v | |
| Stats + Status --→ Web Console alerts + dashboards
+-------------------+
Step 1 — Mint a CertTracker API token
Administration → API Tokens → Create. Name it solarwinds-prod. Copy the value.
Step 2 — Save the PowerShell script on the SAM poller
The script needs to live on the polling engine that will run it (often the main SolarWinds server, or an additional polling engine). Default safe path:
C:\Program Files (x86)\SolarWinds\Orion\APM\check_certtracker.ps1
Drop this content in there:
# check_certtracker.ps1 — SAM Script Component Monitor
#
# Polls CertTracker's /api/v1/integrations/librenms/services endpoint
# and emits SAM statistic/message lines for each monitor.
#
# Required parameters (set on the Component Monitor):
# $args[0] CertTracker base URL e.g. https://certtracker.12squared.com
# $args[1] Path to token file e.g. C:\ProgramData\CertTracker\token.txt
#
# Returns exit code: 0 = Up, 1 = Warning, 2 = Down, 3 = Unknown.
param (
[string]$BaseUrl = "https://certtracker.12squared.com",
[string]$TokenPath = "C:\ProgramData\CertTracker\token.txt"
)
$ErrorActionPreference = 'Stop'
# Read token
try {
$token = (Get-Content -Path $TokenPath -Raw).Trim()
}
catch {
Write-Host "Message: Unable to read token from $TokenPath`: $($_.Exception.Message)"
exit 3
}
if ([string]::IsNullOrWhiteSpace($token)) {
Write-Host "Message: Token file is empty"
exit 3
}
# Hit the API
$BaseUrl = $BaseUrl.TrimEnd('/')
$uri = "$BaseUrl/api/v1/integrations/librenms/services"
try {
$resp = Invoke-RestMethod -Uri $uri `
-Headers @{ "Authorization" = "Bearer $token" } `
-TimeoutSec 30
}
catch {
Write-Host "Message: CertTracker API request failed: $($_.Exception.Message)"
exit 2
}
if (-not $resp.services) {
Write-Host "Message: No services returned (count=$($resp.count))"
exit 3
}
# Aggregate worst exit_code across all monitors as the overall component status
$worstCode = 0
$counts = @{ 0 = 0; 1 = 0; 2 = 0; 3 = 0 }
$crits = @()
$warns = @()
foreach ($svc in $resp.services) {
$code = [int]$svc.exit_code
$counts[$code]++
if ($code -gt $worstCode) { $worstCode = $code }
if ($code -eq 2) { $crits += $svc.label }
if ($code -eq 1) { $warns += $svc.label }
}
# SAM Script Component output format:
# Message.N: <message>
# Statistic.N: <numeric value>
# Statistic.Name.N: <metric label> (SAM 6.2+)
# Exit code drives the component's status: 0=Up, 1=Warning, 2=Down, 3=Unknown.
Write-Host "Message.1: $($resp.count) monitors - OK=$($counts[0]) WARN=$($counts[1]) CRIT=$($counts[2]) UNKNOWN=$($counts[3])"
Write-Host "Statistic.1: $($counts[0])"
Write-Host "Statistic.Name.1: OK Count"
Write-Host "Statistic.2: $($counts[1])"
Write-Host "Statistic.Name.2: WARN Count"
Write-Host "Statistic.3: $($counts[2])"
Write-Host "Statistic.Name.3: CRIT Count"
Write-Host "Statistic.4: $($counts[3])"
Write-Host "Statistic.Name.4: UNKNOWN Count"
# Top-level rollup status
if ($worstCode -ge 2) {
Write-Host "Message.2: CRITICAL on: $($crits -join ', ')"
exit 2
}
elseif ($worstCode -ge 1) {
Write-Host "Message.2: WARNING on: $($warns -join ', ')"
exit 1
}
else {
exit 0
}
Step 3 — Store the token (don't paste it in the SAM config)
SAM's Component Monitor configuration is stored in the SolarWinds DB and visible to other admins. Keep the token in a file instead:
# As Administrator on the polling engine
New-Item -ItemType Directory -Force -Path 'C:\ProgramData\CertTracker' | Out-Null
Set-Content -Path 'C:\ProgramData\CertTracker\token.txt' -Value 'ct_live_xxxxxxxxxxxxxxxxxxxxxxxx'
# Restrict to SYSTEM + Administrators
$acl = Get-Acl 'C:\ProgramData\CertTracker\token.txt'
$acl.SetAccessRuleProtection($true, $false)
$acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule('NT AUTHORITY\SYSTEM','FullControl','Allow')))
$acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule('BUILTIN\Administrators','FullControl','Allow')))
Set-Acl 'C:\ProgramData\CertTracker\token.txt' $acl
Step 4 — Create the Application Template in SAM
In the SolarWinds Web Console:
- Settings → All Settings → SAM Settings → Manage Templates → Create New Template
- Name:
CertTracker - Add Component Monitor → Script Component Monitor
- Configure:
| Field | Value |
|---|---|
| Name | CertTracker API |
| Script Engine | PowerShell |
| Script working directory | C:\Program Files (x86)\SolarWinds\Orion\APM |
| Script body | & '.\check_certtracker.ps1' "https://certtracker.12squared.com" "C:\ProgramData\CertTracker\token.txt" |
| Credentials | A service account with execute permission on the script + read on the token file |
| Number of statistics | 4 |
- Save the template.
Step 5 — Assign the template to a node
Pick any always-on node where SAM should run the check from — typically the SolarWinds server itself, or a dedicated monitoring node.
- Manage Nodes → pick node → Add Application Monitor
- Select the CertTracker template
- Assign + Test
If the test shows green with 4 numeric statistics and a message line summarizing OK/WARN/CRIT counts, you're wired up.
Step 6 — Alerts
Standard SAM alert flow:
Settings → Alerts & Reports → Alerts → Create New Alert
| Field | Value |
|---|---|
| Property to monitor | Application Status |
| Condition | is equal to Warning (or Down for critical) |
| Actions | Email / Teams / PagerDuty / whatever transport you already use |
Or alert on the individual statistic values if you want finer granularity:
| Statistic | Condition | Severity |
|---|---|---|
| CRIT Count | >= 1 |
Critical |
| WARN Count | >= 1 |
Warning |
| UNKNOWN Count | >= 5 |
Warning (config drift signal) |
Troubleshooting
| Symptom | Likely cause |
|---|---|
UNKNOWN — Unable to read token |
Token file path wrong, or the account SAM runs the script as can't read it. |
| All statistics are 0 | Token is valid but plan isn't Business/Enterprise — script gets {"error":"plan_required"} and the loop finds no services. Check the API response directly. |
DOWN — CertTracker API request failed |
Token revoked, network path down, or TLS verification fails. Run Invoke-RestMethod manually on the polling engine. |
| Output isn't parsed | Script Component Monitor format is strict — Statistic.N: and Message.N: lines must start at column 1 with no leading whitespace. |
What's not in this recipe
- NPM integration — Network Performance Monitor measures network device health, not certificates. SAM is the right SolarWinds module for this use case.
- Per-monitor component breakout — the current script aggregates OK/WARN/CRIT counts at the application level. If you want one row per cert, declare 1 statistic + 1 message per service in the script and bump
Number of statisticsto match. Reasonable up to ~20 services; gets unwieldy past that. - Auto-discovery — SAM doesn't auto-discover from external APIs. Service additions in CertTracker won't auto-appear in SolarWinds; re-running the template covers them via the aggregate counters.
Contributions via the community forum welcome — especially an exported .apm-template file for one-click import.