Sync all scripts from website downloads — 352 scripts total
Includes updated JS challenge scripts with Claude-User whitelist, same-site referer bypass, Blackbox-Exporter allowed bot, and all new exporters, cheat sheets, and automation scripts.
This commit is contained in:
@@ -0,0 +1,595 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
SCOM Prometheus Metrics Exporter
|
||||
.DESCRIPTION
|
||||
Prometheus exporter for System Center Operations Manager - management server
|
||||
health, agent status, open alerts by severity, resolution state counts,
|
||||
management pack and monitor counts, override counts, pending actions,
|
||||
database sizes, stale agents, and alert age statistics. Exports metrics as
|
||||
Prometheus-compatible text format.
|
||||
.PARAMETER Mode
|
||||
Output mode: 'stdout' (default), 'textfile', or 'http'
|
||||
.PARAMETER Port
|
||||
HTTP port for http mode (default: 9650)
|
||||
.PARAMETER TextfileDir
|
||||
Directory for textfile collector output (default: C:\ProgramData\node_exporter)
|
||||
.PARAMETER InstallScheduledTask
|
||||
Switch to create a scheduled task for auto-start on system boot
|
||||
.PARAMETER TaskIntervalMinutes
|
||||
Interval in minutes for the scheduled task (default: 2)
|
||||
.NOTES
|
||||
Author: Phil Connor
|
||||
Contact: contact@mylinux.work
|
||||
Website: https://mylinux.work
|
||||
License: MIT
|
||||
Version: 1.0
|
||||
|
||||
Metrics Exported:
|
||||
Core Status:
|
||||
- scom_up
|
||||
- scom_exporter_info{version}
|
||||
|
||||
Management Servers:
|
||||
- scom_management_server_health{server,health_state}
|
||||
|
||||
Agents:
|
||||
- scom_agent_total
|
||||
- scom_agent_healthy
|
||||
- scom_agent_warning
|
||||
- scom_agent_critical
|
||||
- scom_agent_unmonitored
|
||||
- scom_agent_pending_actions
|
||||
|
||||
Alerts:
|
||||
- scom_alerts_open_total
|
||||
- scom_alerts_by_severity{severity}
|
||||
- scom_alerts_by_resolution_state{resolution_state}
|
||||
- scom_alert_age_oldest_hours
|
||||
- scom_alert_age_average_hours
|
||||
|
||||
Stale Agents:
|
||||
- scom_agent_stale_total
|
||||
|
||||
Management Packs:
|
||||
- scom_management_pack_total
|
||||
|
||||
Monitors:
|
||||
- scom_monitor_total
|
||||
- scom_monitor_healthy
|
||||
- scom_monitor_error
|
||||
- scom_monitor_warning
|
||||
|
||||
Management Group:
|
||||
- scom_management_group_total
|
||||
|
||||
Overrides:
|
||||
- scom_override_total
|
||||
|
||||
Databases:
|
||||
- scom_database_size_bytes{database}
|
||||
|
||||
Exporter:
|
||||
- scom_exporter_duration_seconds
|
||||
- scom_exporter_last_run_timestamp
|
||||
#>
|
||||
|
||||
param(
|
||||
[ValidateSet('stdout', 'textfile', 'http')]
|
||||
[string]$Mode = 'stdout',
|
||||
|
||||
[int]$Port = 9650,
|
||||
|
||||
[string]$TextfileDir = 'C:\ProgramData\node_exporter',
|
||||
|
||||
[switch]$InstallScheduledTask,
|
||||
|
||||
[int]$TaskIntervalMinutes = 2
|
||||
)
|
||||
|
||||
# Create a scheduled task to run this script every $TaskIntervalMinutes minutes
|
||||
if ($InstallScheduledTask) {
|
||||
$taskName = "ScomMetricsExporter"
|
||||
$existingTask = Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue
|
||||
|
||||
if (-not $existingTask) {
|
||||
$taskAction = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File `"$($MyInvocation.MyCommand.Path)`" -Mode textfile"
|
||||
|
||||
if (-not $TaskIntervalMinutes -or $TaskIntervalMinutes -le 0) {
|
||||
throw "TaskIntervalMinutes must be a positive integer"
|
||||
}
|
||||
|
||||
$taskTrigger = New-ScheduledTaskTrigger -Once -At (Get-Date).AddMinutes(1) -RepetitionInterval (New-TimeSpan -Minutes $TaskIntervalMinutes) -RepetitionDuration (New-TimeSpan -Days 365)
|
||||
$taskPrincipal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
|
||||
|
||||
try {
|
||||
Write-Host "Creating scheduled task: $taskName"
|
||||
Register-ScheduledTask -TaskName $taskName -Action $taskAction -Trigger $taskTrigger -Principal $taskPrincipal -Description "Exports SCOM metrics for Prometheus every $TaskIntervalMinutes minutes"
|
||||
|
||||
$createdTask = Get-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue
|
||||
if (-not $createdTask) {
|
||||
throw "Failed to verify scheduled task creation"
|
||||
}
|
||||
Write-Host "Successfully created scheduled task: $taskName" -ForegroundColor Green
|
||||
} catch {
|
||||
Write-Error "Failed to create scheduled task: $($_.Exception.Message)"
|
||||
throw
|
||||
}
|
||||
} else {
|
||||
Write-Host "Scheduled task '$taskName' already exists, skipping creation"
|
||||
}
|
||||
}
|
||||
|
||||
$ErrorActionPreference = 'SilentlyContinue'
|
||||
|
||||
# ============================================================================
|
||||
# HELPER FUNCTIONS
|
||||
# ============================================================================
|
||||
|
||||
function Get-UnixTimestamp {
|
||||
[int][double]::Parse((Get-Date -UFormat '%s'))
|
||||
}
|
||||
|
||||
function Format-MetricValue {
|
||||
param([double]$Value, [int]$Decimals = 2)
|
||||
[math]::Round($Value, $Decimals)
|
||||
}
|
||||
|
||||
function Test-ScomModule {
|
||||
try {
|
||||
Import-Module OperationsManager -ErrorAction Stop
|
||||
return $true
|
||||
} catch {
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# SCOM METRICS
|
||||
# ============================================================================
|
||||
|
||||
function Get-ScomMetrics {
|
||||
$sb = [System.Text.StringBuilder]::new()
|
||||
|
||||
# --- Management Server Health ---
|
||||
[void]$sb.AppendLine('# HELP scom_management_server_health Management server health (1=healthy, 0=unhealthy)')
|
||||
[void]$sb.AppendLine('# TYPE scom_management_server_health gauge')
|
||||
try {
|
||||
$mgmtServers = Get-SCOMManagementServer
|
||||
if ($mgmtServers) {
|
||||
foreach ($ms in $mgmtServers) {
|
||||
$serverName = $ms.Name -replace '["]', ''
|
||||
$healthVal = switch ($ms.HealthState) {
|
||||
'Success' { 1 }
|
||||
default { 0 }
|
||||
}
|
||||
$stateLabel = "$($ms.HealthState)"
|
||||
[void]$sb.AppendLine("scom_management_server_health{server=`"$serverName`",health_state=`"$stateLabel`"} $healthVal")
|
||||
}
|
||||
}
|
||||
} catch { }
|
||||
[void]$sb.AppendLine('')
|
||||
|
||||
# --- Agent Counts ---
|
||||
[void]$sb.AppendLine('# HELP scom_agent_total Total number of SCOM agents')
|
||||
[void]$sb.AppendLine('# TYPE scom_agent_total gauge')
|
||||
[void]$sb.AppendLine('')
|
||||
[void]$sb.AppendLine('# HELP scom_agent_healthy Number of healthy agents')
|
||||
[void]$sb.AppendLine('# TYPE scom_agent_healthy gauge')
|
||||
[void]$sb.AppendLine('')
|
||||
[void]$sb.AppendLine('# HELP scom_agent_warning Number of agents in warning state')
|
||||
[void]$sb.AppendLine('# TYPE scom_agent_warning gauge')
|
||||
[void]$sb.AppendLine('')
|
||||
[void]$sb.AppendLine('# HELP scom_agent_critical Number of agents in critical state')
|
||||
[void]$sb.AppendLine('# TYPE scom_agent_critical gauge')
|
||||
[void]$sb.AppendLine('')
|
||||
[void]$sb.AppendLine('# HELP scom_agent_unmonitored Number of unmonitored agents')
|
||||
[void]$sb.AppendLine('# TYPE scom_agent_unmonitored gauge')
|
||||
try {
|
||||
$agents = Get-SCOMAgent
|
||||
$agentTotal = if ($agents) { @($agents).Count } else { 0 }
|
||||
$agentHealthy = if ($agents) { @($agents | Where-Object { $_.HealthState -eq 'Success' }).Count } else { 0 }
|
||||
$agentWarning = if ($agents) { @($agents | Where-Object { $_.HealthState -eq 'Warning' }).Count } else { 0 }
|
||||
$agentCritical = if ($agents) { @($agents | Where-Object { $_.HealthState -eq 'Error' }).Count } else { 0 }
|
||||
$agentUnmonitored = if ($agents) { @($agents | Where-Object { $_.HealthState -eq 'Uninitialized' -or $_.HealthState -eq 'NotMonitored' }).Count } else { 0 }
|
||||
[void]$sb.AppendLine("scom_agent_total $agentTotal")
|
||||
[void]$sb.AppendLine("scom_agent_healthy $agentHealthy")
|
||||
[void]$sb.AppendLine("scom_agent_warning $agentWarning")
|
||||
[void]$sb.AppendLine("scom_agent_critical $agentCritical")
|
||||
[void]$sb.AppendLine("scom_agent_unmonitored $agentUnmonitored")
|
||||
} catch {
|
||||
[void]$sb.AppendLine("scom_agent_total 0")
|
||||
[void]$sb.AppendLine("scom_agent_healthy 0")
|
||||
[void]$sb.AppendLine("scom_agent_warning 0")
|
||||
[void]$sb.AppendLine("scom_agent_critical 0")
|
||||
[void]$sb.AppendLine("scom_agent_unmonitored 0")
|
||||
}
|
||||
[void]$sb.AppendLine('')
|
||||
|
||||
# --- Stale / Grayed-Out Agents ---
|
||||
[void]$sb.AppendLine('# HELP scom_agent_stale_total Number of stale or grayed-out agents')
|
||||
[void]$sb.AppendLine('# TYPE scom_agent_stale_total gauge')
|
||||
try {
|
||||
$staleAgents = @(Get-SCOMAgent | Where-Object { $_.HealthState -eq 'Uninitialized' }).Count
|
||||
[void]$sb.AppendLine("scom_agent_stale_total $staleAgents")
|
||||
} catch {
|
||||
[void]$sb.AppendLine("scom_agent_stale_total 0")
|
||||
}
|
||||
[void]$sb.AppendLine('')
|
||||
|
||||
# --- Agent Pending Actions ---
|
||||
[void]$sb.AppendLine('# HELP scom_agent_pending_actions Number of agents with pending actions')
|
||||
[void]$sb.AppendLine('# TYPE scom_agent_pending_actions gauge')
|
||||
try {
|
||||
$pendingAgents = @(Get-SCOMPendingManagement).Count
|
||||
[void]$sb.AppendLine("scom_agent_pending_actions $pendingAgents")
|
||||
} catch {
|
||||
[void]$sb.AppendLine("scom_agent_pending_actions 0")
|
||||
}
|
||||
[void]$sb.AppendLine('')
|
||||
|
||||
# --- Open Alerts Total ---
|
||||
[void]$sb.AppendLine('# HELP scom_alerts_open_total Total number of open alerts')
|
||||
[void]$sb.AppendLine('# TYPE scom_alerts_open_total gauge')
|
||||
try {
|
||||
$alerts = Get-SCOMAlert -ResolutionState 0
|
||||
$alertCount = if ($alerts) { @($alerts).Count } else { 0 }
|
||||
[void]$sb.AppendLine("scom_alerts_open_total $alertCount")
|
||||
} catch {
|
||||
[void]$sb.AppendLine("scom_alerts_open_total 0")
|
||||
}
|
||||
[void]$sb.AppendLine('')
|
||||
|
||||
# --- Alerts by Severity ---
|
||||
[void]$sb.AppendLine('# HELP scom_alerts_by_severity Open alerts grouped by severity')
|
||||
[void]$sb.AppendLine('# TYPE scom_alerts_by_severity gauge')
|
||||
try {
|
||||
$allAlerts = Get-SCOMAlert -ResolutionState 0
|
||||
if ($allAlerts) {
|
||||
$critAlerts = @($allAlerts | Where-Object { $_.Severity -eq 'Error' }).Count
|
||||
$warnAlerts = @($allAlerts | Where-Object { $_.Severity -eq 'Warning' }).Count
|
||||
$infoAlerts = @($allAlerts | Where-Object { $_.Severity -eq 'Information' }).Count
|
||||
[void]$sb.AppendLine("scom_alerts_by_severity{severity=`"critical`"} $critAlerts")
|
||||
[void]$sb.AppendLine("scom_alerts_by_severity{severity=`"warning`"} $warnAlerts")
|
||||
[void]$sb.AppendLine("scom_alerts_by_severity{severity=`"information`"} $infoAlerts")
|
||||
} else {
|
||||
[void]$sb.AppendLine("scom_alerts_by_severity{severity=`"critical`"} 0")
|
||||
[void]$sb.AppendLine("scom_alerts_by_severity{severity=`"warning`"} 0")
|
||||
[void]$sb.AppendLine("scom_alerts_by_severity{severity=`"information`"} 0")
|
||||
}
|
||||
} catch {
|
||||
[void]$sb.AppendLine("scom_alerts_by_severity{severity=`"critical`"} 0")
|
||||
[void]$sb.AppendLine("scom_alerts_by_severity{severity=`"warning`"} 0")
|
||||
[void]$sb.AppendLine("scom_alerts_by_severity{severity=`"information`"} 0")
|
||||
}
|
||||
[void]$sb.AppendLine('')
|
||||
|
||||
# --- Alerts by Resolution State ---
|
||||
[void]$sb.AppendLine('# HELP scom_alerts_by_resolution_state Alert count grouped by resolution state')
|
||||
[void]$sb.AppendLine('# TYPE scom_alerts_by_resolution_state gauge')
|
||||
try {
|
||||
$allResAlerts = Get-SCOMAlert
|
||||
if ($allResAlerts) {
|
||||
$grouped = $allResAlerts | Group-Object ResolutionState
|
||||
foreach ($group in $grouped) {
|
||||
$state = $group.Name
|
||||
[void]$sb.AppendLine("scom_alerts_by_resolution_state{resolution_state=`"$state`"} $($group.Count)")
|
||||
}
|
||||
}
|
||||
} catch { }
|
||||
[void]$sb.AppendLine('')
|
||||
|
||||
# --- Alert Age Stats ---
|
||||
[void]$sb.AppendLine('# HELP scom_alert_age_oldest_hours Age of the oldest open alert in hours')
|
||||
[void]$sb.AppendLine('# TYPE scom_alert_age_oldest_hours gauge')
|
||||
[void]$sb.AppendLine('')
|
||||
[void]$sb.AppendLine('# HELP scom_alert_age_average_hours Average age of open alerts in hours')
|
||||
[void]$sb.AppendLine('# TYPE scom_alert_age_average_hours gauge')
|
||||
try {
|
||||
$openAlerts = Get-SCOMAlert -ResolutionState 0
|
||||
if ($openAlerts -and @($openAlerts).Count -gt 0) {
|
||||
$now = Get-Date
|
||||
$ages = @($openAlerts | ForEach-Object { ($now - $_.TimeRaised).TotalHours })
|
||||
$oldest = Format-MetricValue ($ages | Measure-Object -Maximum).Maximum
|
||||
$average = Format-MetricValue ($ages | Measure-Object -Average).Average
|
||||
[void]$sb.AppendLine("scom_alert_age_oldest_hours $oldest")
|
||||
[void]$sb.AppendLine("scom_alert_age_average_hours $average")
|
||||
} else {
|
||||
[void]$sb.AppendLine("scom_alert_age_oldest_hours 0")
|
||||
[void]$sb.AppendLine("scom_alert_age_average_hours 0")
|
||||
}
|
||||
} catch {
|
||||
[void]$sb.AppendLine("scom_alert_age_oldest_hours 0")
|
||||
[void]$sb.AppendLine("scom_alert_age_average_hours 0")
|
||||
}
|
||||
[void]$sb.AppendLine('')
|
||||
|
||||
# --- Management Pack Count ---
|
||||
[void]$sb.AppendLine('# HELP scom_management_pack_total Total number of management packs')
|
||||
[void]$sb.AppendLine('# TYPE scom_management_pack_total gauge')
|
||||
try {
|
||||
$mpCount = @(Get-SCOMManagementPack).Count
|
||||
[void]$sb.AppendLine("scom_management_pack_total $mpCount")
|
||||
} catch {
|
||||
[void]$sb.AppendLine("scom_management_pack_total 0")
|
||||
}
|
||||
[void]$sb.AppendLine('')
|
||||
|
||||
# --- Monitor Counts ---
|
||||
[void]$sb.AppendLine('# HELP scom_monitor_total Total number of monitors')
|
||||
[void]$sb.AppendLine('# TYPE scom_monitor_total gauge')
|
||||
[void]$sb.AppendLine('')
|
||||
[void]$sb.AppendLine('# HELP scom_monitor_healthy Number of monitors in healthy state')
|
||||
[void]$sb.AppendLine('# TYPE scom_monitor_healthy gauge')
|
||||
[void]$sb.AppendLine('')
|
||||
[void]$sb.AppendLine('# HELP scom_monitor_error Number of monitors in error state')
|
||||
[void]$sb.AppendLine('# TYPE scom_monitor_error gauge')
|
||||
[void]$sb.AppendLine('')
|
||||
[void]$sb.AppendLine('# HELP scom_monitor_warning Number of monitors in warning state')
|
||||
[void]$sb.AppendLine('# TYPE scom_monitor_warning gauge')
|
||||
try {
|
||||
$monitors = Get-SCOMMonitor
|
||||
$monTotal = if ($monitors) { @($monitors).Count } else { 0 }
|
||||
[void]$sb.AppendLine("scom_monitor_total $monTotal")
|
||||
|
||||
$monitoringObjects = Get-SCOMClassInstance | Where-Object { $_.HealthState }
|
||||
if ($monitoringObjects) {
|
||||
$monHealthy = @($monitoringObjects | Where-Object { $_.HealthState -eq 'Success' }).Count
|
||||
$monError = @($monitoringObjects | Where-Object { $_.HealthState -eq 'Error' }).Count
|
||||
$monWarning = @($monitoringObjects | Where-Object { $_.HealthState -eq 'Warning' }).Count
|
||||
[void]$sb.AppendLine("scom_monitor_healthy $monHealthy")
|
||||
[void]$sb.AppendLine("scom_monitor_error $monError")
|
||||
[void]$sb.AppendLine("scom_monitor_warning $monWarning")
|
||||
} else {
|
||||
[void]$sb.AppendLine("scom_monitor_healthy 0")
|
||||
[void]$sb.AppendLine("scom_monitor_error 0")
|
||||
[void]$sb.AppendLine("scom_monitor_warning 0")
|
||||
}
|
||||
} catch {
|
||||
[void]$sb.AppendLine("scom_monitor_total 0")
|
||||
[void]$sb.AppendLine("scom_monitor_healthy 0")
|
||||
[void]$sb.AppendLine("scom_monitor_error 0")
|
||||
[void]$sb.AppendLine("scom_monitor_warning 0")
|
||||
}
|
||||
[void]$sb.AppendLine('')
|
||||
|
||||
# --- Management Group Count ---
|
||||
[void]$sb.AppendLine('# HELP scom_management_group_total Number of management groups')
|
||||
[void]$sb.AppendLine('# TYPE scom_management_group_total gauge')
|
||||
try {
|
||||
$mgCount = @(Get-SCOMManagementGroup).Count
|
||||
[void]$sb.AppendLine("scom_management_group_total $mgCount")
|
||||
} catch {
|
||||
[void]$sb.AppendLine("scom_management_group_total 0")
|
||||
}
|
||||
[void]$sb.AppendLine('')
|
||||
|
||||
# --- Override Count ---
|
||||
[void]$sb.AppendLine('# HELP scom_override_total Total number of overrides')
|
||||
[void]$sb.AppendLine('# TYPE scom_override_total gauge')
|
||||
try {
|
||||
$overrides = Get-SCOMOverride
|
||||
$overrideCount = if ($overrides) { @($overrides).Count } else { 0 }
|
||||
[void]$sb.AppendLine("scom_override_total $overrideCount")
|
||||
} catch {
|
||||
[void]$sb.AppendLine("scom_override_total 0")
|
||||
}
|
||||
[void]$sb.AppendLine('')
|
||||
|
||||
# --- Database Sizes ---
|
||||
[void]$sb.AppendLine('# HELP scom_database_size_bytes SCOM database size in bytes')
|
||||
[void]$sb.AppendLine('# TYPE scom_database_size_bytes gauge')
|
||||
try {
|
||||
$dbQuery = @"
|
||||
SELECT
|
||||
DB_NAME(database_id) AS db_name,
|
||||
SUM(size) * 8192 AS size_bytes
|
||||
FROM sys.master_files
|
||||
WHERE DB_NAME(database_id) IN ('OperationsManager', 'OperationsManagerDW')
|
||||
GROUP BY database_id
|
||||
"@
|
||||
$sqlModule = Get-Module -Name SqlServer -ListAvailable -ErrorAction SilentlyContinue
|
||||
$scomMgmt = Get-SCOMManagementGroup
|
||||
if ($sqlModule) {
|
||||
Import-Module SqlServer -ErrorAction SilentlyContinue
|
||||
$dbSettings = $scomMgmt | ForEach-Object {
|
||||
try { $_.GetSettings() } catch { $null }
|
||||
}
|
||||
$sqlInstance = if ($dbSettings) { $dbSettings.DefaultDataWarehouseServer } else { 'localhost' }
|
||||
$dbSizes = Invoke-Sqlcmd -ServerInstance $sqlInstance -Database 'master' -Query $dbQuery -ErrorAction Stop -QueryTimeout 10
|
||||
if ($dbSizes) {
|
||||
foreach ($row in $dbSizes) {
|
||||
$dbName = $row.db_name -replace '["]', ''
|
||||
[void]$sb.AppendLine("scom_database_size_bytes{database=`"$dbName`"} $($row.size_bytes)")
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch { }
|
||||
[void]$sb.AppendLine('')
|
||||
|
||||
$sb.ToString()
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# COLLECT ALL METRICS
|
||||
# ============================================================================
|
||||
|
||||
function Get-AllMetrics {
|
||||
$scriptStart = Get-Date
|
||||
$sb = [System.Text.StringBuilder]::new()
|
||||
|
||||
# Exporter up - test OperationsManager module availability
|
||||
[void]$sb.AppendLine('# HELP scom_up SCOM reachability (1=up, 0=down)')
|
||||
[void]$sb.AppendLine('# TYPE scom_up gauge')
|
||||
try {
|
||||
$moduleAvailable = Test-ScomModule
|
||||
if (-not $moduleAvailable) {
|
||||
[void]$sb.AppendLine("scom_up 0")
|
||||
$scriptEnd = Get-Date
|
||||
$duration = Format-MetricValue ($scriptEnd - $scriptStart).TotalSeconds
|
||||
[void]$sb.AppendLine('')
|
||||
[void]$sb.AppendLine('# HELP scom_exporter_duration_seconds Time to generate all metrics')
|
||||
[void]$sb.AppendLine('# TYPE scom_exporter_duration_seconds gauge')
|
||||
[void]$sb.AppendLine("scom_exporter_duration_seconds $duration")
|
||||
[void]$sb.AppendLine('')
|
||||
[void]$sb.AppendLine('# HELP scom_exporter_last_run_timestamp Unix timestamp of last run')
|
||||
[void]$sb.AppendLine('# TYPE scom_exporter_last_run_timestamp gauge')
|
||||
[void]$sb.AppendLine("scom_exporter_last_run_timestamp $(Get-UnixTimestamp)")
|
||||
return $sb.ToString()
|
||||
}
|
||||
|
||||
$testMs = Get-SCOMManagementServer -ErrorAction Stop
|
||||
$upVal = if ($testMs) { 1 } else { 0 }
|
||||
[void]$sb.AppendLine("scom_up $upVal")
|
||||
} catch {
|
||||
[void]$sb.AppendLine("scom_up 0")
|
||||
$scriptEnd = Get-Date
|
||||
$duration = Format-MetricValue ($scriptEnd - $scriptStart).TotalSeconds
|
||||
[void]$sb.AppendLine('')
|
||||
[void]$sb.AppendLine('# HELP scom_exporter_duration_seconds Time to generate all metrics')
|
||||
[void]$sb.AppendLine('# TYPE scom_exporter_duration_seconds gauge')
|
||||
[void]$sb.AppendLine("scom_exporter_duration_seconds $duration")
|
||||
[void]$sb.AppendLine('')
|
||||
[void]$sb.AppendLine('# HELP scom_exporter_last_run_timestamp Unix timestamp of last run')
|
||||
[void]$sb.AppendLine('# TYPE scom_exporter_last_run_timestamp gauge')
|
||||
[void]$sb.AppendLine("scom_exporter_last_run_timestamp $(Get-UnixTimestamp)")
|
||||
return $sb.ToString()
|
||||
}
|
||||
[void]$sb.AppendLine('')
|
||||
|
||||
# Exporter info
|
||||
[void]$sb.AppendLine('# HELP scom_exporter_info Exporter version information')
|
||||
[void]$sb.AppendLine('# TYPE scom_exporter_info gauge')
|
||||
[void]$sb.AppendLine('scom_exporter_info{version="1.0"} 1')
|
||||
[void]$sb.AppendLine('')
|
||||
|
||||
# Collect SCOM metrics
|
||||
[void]$sb.Append((Get-ScomMetrics))
|
||||
|
||||
# Exporter runtime
|
||||
$scriptEnd = Get-Date
|
||||
$duration = Format-MetricValue ($scriptEnd - $scriptStart).TotalSeconds
|
||||
$timestamp = Get-UnixTimestamp
|
||||
|
||||
[void]$sb.AppendLine('# HELP scom_exporter_duration_seconds Time to generate all metrics')
|
||||
[void]$sb.AppendLine('# TYPE scom_exporter_duration_seconds gauge')
|
||||
[void]$sb.AppendLine("scom_exporter_duration_seconds $duration")
|
||||
[void]$sb.AppendLine('')
|
||||
[void]$sb.AppendLine('# HELP scom_exporter_last_run_timestamp Unix timestamp of last successful run')
|
||||
[void]$sb.AppendLine('# TYPE scom_exporter_last_run_timestamp gauge')
|
||||
[void]$sb.AppendLine("scom_exporter_last_run_timestamp $timestamp")
|
||||
[void]$sb.AppendLine('')
|
||||
|
||||
$sb.ToString()
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# HTTP SERVER MODE
|
||||
# ============================================================================
|
||||
|
||||
function Start-HttpServer {
|
||||
param([int]$ListenPort)
|
||||
|
||||
$prefix = "http://+:$ListenPort/"
|
||||
$listener = [System.Net.HttpListener]::new()
|
||||
$listener.Prefixes.Add($prefix)
|
||||
|
||||
try {
|
||||
$listener.Start()
|
||||
Write-Host "Starting SCOM metrics exporter on port $ListenPort..." -ForegroundColor Green
|
||||
Write-Host "Metrics available at http://localhost:$ListenPort/metrics"
|
||||
|
||||
while ($listener.IsListening) {
|
||||
$context = $listener.GetContext()
|
||||
$request = $context.Request
|
||||
$response = $context.Response
|
||||
|
||||
if ($request.Url.AbsolutePath -eq '/metrics') {
|
||||
$metrics = Get-AllMetrics
|
||||
$buffer = [System.Text.Encoding]::UTF8.GetBytes($metrics)
|
||||
$response.ContentType = 'text/plain; version=0.0.4; charset=utf-8'
|
||||
}
|
||||
else {
|
||||
$html = @"
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head><title>SCOM Metrics Exporter v1.0</title></head>
|
||||
<body>
|
||||
<h1>SCOM Metrics Exporter v1.0</h1>
|
||||
<p><a href="/metrics">Metrics</a></p>
|
||||
<h2>Metrics</h2>
|
||||
<ul>
|
||||
<li>Management server health status</li>
|
||||
<li>Agent totals and health breakdown</li>
|
||||
<li>Open alerts by severity and resolution state</li>
|
||||
<li>Alert age statistics</li>
|
||||
<li>Management pack and monitor counts</li>
|
||||
<li>Override count</li>
|
||||
<li>Pending agent actions</li>
|
||||
<li>Stale/grayed-out agent count</li>
|
||||
<li>Database sizes (OperationsManager, OperationsManagerDW)</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
"@
|
||||
$buffer = [System.Text.Encoding]::UTF8.GetBytes($html)
|
||||
$response.ContentType = 'text/html; charset=utf-8'
|
||||
}
|
||||
|
||||
$response.ContentLength64 = $buffer.Length
|
||||
$response.OutputStream.Write($buffer, 0, $buffer.Length)
|
||||
$response.OutputStream.Close()
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Error "HTTP server error: $_"
|
||||
Write-Error "If access denied, run: netsh http add urlacl url=http://+:$ListenPort/ user=Everyone"
|
||||
}
|
||||
finally {
|
||||
if ($listener.IsListening) {
|
||||
$listener.Stop()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
# MAIN EXECUTION
|
||||
# ============================================================================
|
||||
|
||||
switch ($Mode) {
|
||||
'http' {
|
||||
Start-HttpServer -ListenPort $Port
|
||||
}
|
||||
'textfile' {
|
||||
$OutputFile = Join-Path $TextfileDir 'scom_metrics.prom'
|
||||
|
||||
$outputDir = Split-Path $OutputFile -Parent
|
||||
if (-not (Test-Path $outputDir)) {
|
||||
New-Item -Path $outputDir -ItemType Directory -Force | Out-Null
|
||||
}
|
||||
|
||||
$tempFile = Join-Path $outputDir ".scom_metrics.$PID.tmp"
|
||||
|
||||
try {
|
||||
$metrics = Get-AllMetrics
|
||||
$metrics | Out-File -FilePath $tempFile -Encoding utf8 -NoNewline
|
||||
|
||||
$lineCount = ($metrics -split "`n").Count
|
||||
if ($lineCount -lt 10) {
|
||||
Remove-Item -Path $tempFile -Force -ErrorAction SilentlyContinue
|
||||
Write-Error "Metrics file too small ($lineCount lines), keeping previous"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Move-Item -Path $tempFile -Destination $OutputFile -Force
|
||||
Write-Host "Metrics written to $OutputFile ($lineCount lines)" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Remove-Item -Path $tempFile -Force -ErrorAction SilentlyContinue
|
||||
Write-Error "Failed to generate metrics: $_"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
default {
|
||||
Get-AllMetrics | Write-Output
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user