Files
linux-scripts/windows-scom-exporter.ps1
T
chiefgeek a1a17e81a1 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.
2026-05-25 03:31:08 +02:00

596 lines
24 KiB
PowerShell

<#
.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
}
}