Plusieurs modules Powershell développés par la communauté autour du besoin d’exporter des métriques au format Prometheus depuis des scripts Powershell existent déjà mais aucun ne répondait précisément à mon besoin, faire le strict minimum à l’aide de la syntaxe la plus simple et claire possible:
- Créer des métriques
- Leur ajouter une ou plusieurs valeurs avec ou sans labels
- Formater le résultat au format Prometheus
- Exporter le résultat dans le terminal (StdOut), vers un fichier texte (avec écriture atomique) qui puisse être lu par un Node Exporter Prometheus local ou enfin vers une PushGateway.
Nul besoin d’ajouter la gestion de l’affichage des métriques directement en http local dans ce module : cela rajoute une forte couche de complexité non liée au besoin initial et de vrais risques de sécurité, alors ce rôle peut très bien être assumé par un module dédié comme le très complet Pode combiné à la sortie en StdOut comme nous le verrons plus loin.
J’ajouterais qu’il s’agissait aussi d’un bon prétexte pour tester plus sérieusement les classes de Powershell.
Trève de bavardages, commençons par le lien vers le repo GitHub du module (pas encore disponible sur la PSGallery) : https://github.com/Cyr-Az/poshtorch
Voyons maintenant comment fonctionne le module :
Avant d’exporter les données, il est nécessaire de créer les objets correspondants en et de leur assigner des valeurs. Le module s’appuie sur deux commandes principales pour ces opérations :
- New-PrometheusMetric : Initialise l’objet métrique avec ses métadonnées de base (nom, description et type). Le nom de la métrique est automatiquement validé pour respecter les standards de Prometheus (caractères alphanumériques et underscores uniquement). Cette commande supporte les paramètres suivants :
- Name : le nom technique de la métrique
- Help : une description textuelle lisible par un humain
- Type : le type de métrique, limité aux valeurs conformes à Prometheus (counter, gauge, histogram ou summary).
- Add-PrometheusMetricValue : Attache une valeur numérique à une métrique préalablement créée. Cette fonction peut être appelée plusieurs fois sur la même métrique pour générer des séries temporelles multiples (Time Series). Elle supporte les paramètres suivants :
- Metric : l’objet métrique à modifier, généralement passé via le pipeline
- Value : la valeur numérique
- Labels : paramètre optionnel acceptant une hashtable @{ clé = « valeur » } pour définir les étiquettes associées à cette valeur.
Une fois les objets métriques créés via New-PrometheusMetric et Add-PrometheusMetricValue, le module propose trois fonctions distinctes pour restituer (exporter) la donnée selon vos besoins :
- Out-PrometheusMetric : Convertit l’objet PowerShell en une chaîne de caractères (texte brut) respectant le format d’exposition Prometheus (version 0.0.4). Elle est utilisée pour le debug dans la console ou pour transmettre le texte à un serveur HTTP. Elle supporte les paramètres suivants :
- Metric : accepte un ou plusieurs objets de métriques, généralement via le pipeline.
- Export-PrometheusFile : Sauvegarde les métriques dans un fichier texte (souvent avec l’extension .prom). Cette méthode est conçue pour être couplée au Textfile Collector de l’agent Node Exporter. La fonction utilise un fichier temporaire qu’elle remplace de manière atomique (uniquement en Powershell 7+) afin d’éviter que Prometheus ne scrape un fichier en cours d’écriture. Elle supporte les paramètres suivants :
- Metric : accepte un ou plusieurs objets de métriques, généralement via le pipeline.
- Path : le chemin complet du fichier de destination .
- Export-PrometheusPushgateway : Envoie directement les métriques à une instance Prometheus Pushgateway via une requête http(s). C’est l’approche recommandée pour les scripts éphémères (ex: tâches planifiées ou scripts de sauvegarde) qui ne peuvent pas être interrogés activement par Prometheus. Elle supporte les paramètres suivants :
- Metric : accepte un ou plusieurs objets de métriques, généralement via le pipeline.
- GatewayUrl : l’adresse de la Pushgateway, ex: http://localhost:9091
- Job : le nom du job ciblé
- Instance : optionnel, pour spécifier le nom de l’instance
- Method : PUT pour remplacer le précédent batch de métriques recu par la PushGateway (valeur par défaut) ou POST pour ajouter les données au précédent batch de métriques.
Terminons enfin cet article par quelques exemples d’utilisation illustrant le fonctionnement du module dans des scénarios d’administration courants :
Utilisation avec le pipeline PowerShell
Les fonctions du module sont conçues pour supporter le pipeline. Cela permet d’enchaîner la création de la métrique, l’ajout de la valeur et l’export sans nécessiter de variables intermédiaires, ce qui est particulièrement adapté pour l’export de métriques simples, pour une seule instance/un seul objet ou sans label particulier.
Dans l’exemple ci-dessous, le script récupère le nombre de comptes Active Directory verrouillés et l’écrit directement dans un fichier .prom destiné à être lu par le Textfile Collector d’un Node Exporter :
Import-Module -Name ActiveDirectory
Import-Module -Name PoshTorch
# Récupération de la donnée
$lockedAccounts = (Get-ADUser -Filter {LockedOut -eq $true}).Count
# Création, ajout de la valeur et export vers le fichier
New-PrometheusMetric -Name 'ad_locked_accounts_total' -Help 'Comptes AD verrouillés' -Type gauge |
Add-PrometheusMetricValue -Value $lockedAccounts |
Export-PrometheusFile -Path 'C:\Metrics\ad_health.prom'
Gestion des labels et des séries multiples
Prometheus utilise des labels pour ajouter de la dimension aux métriques, ce qui permet de stocker plusieurs séries temporelles (Time Series) sous un même nom. PoshTorch gère ces labels via les hashtables standards de PowerShell.
L’exemple suivant vérifie l’état de plusieurs services Windows. La métrique est créée une seule fois, puis alimentée itérativement avant d’être envoyée à une PushGateway :
Import-Module -Name PoshTorch
$criticalServices = @("wuauserv", "Spooler", "WinRM")
# Initialisation de l'objet métrique
$serviceMetric = New-PrometheusMetric -Name 'windows_service_status' `
-Help '1 si en cours, 0 si arrêté' `
-Type gauge
foreach ($serviceName in $criticalServices)
{
$service = Get-Service -Name $serviceName -ErrorAction SilentlyContinue
$isUp = if ($service.Status -eq 'Running') { 1 } else { 0 }
# Définition des labels pour l'itération courante
$serviceLabels = @{
service_name = $serviceName
start_type = $service.StartType.ToString()
host = $env:COMPUTERNAME
}
# Ajout de la valeur à la métrique
$serviceMetric = $serviceMetric | Add-PrometheusMetricValue -Value $isUp -Labels $serviceLabels
}
# Envoi de la métrique contenant les données des trois services
$serviceMetric | Export-PrometheusPushgateway -GatewayUrl 'http://pushgateway.corp.local:9091' `
-Job 'service_monitoring'
Exposer les métriques en HTTP avec Pode
Si l’architecture de supervision nécessite que le script s’exécute comme un exporter classique interrogeable par Prometheus (modèle pull), la fonction Out-PrometheusMetric permet de récupérer les données formatées en texte brut.
Il suffit ensuite de lier ce flux à un module de serveur web dédié comme Pode.
Déléguer l’écoute HTTP à Pode permet de conserver un module de métriques strictement limité à la mise en forme des données, tout en laissant l’opportunité de s’appuyer sur les fonctionnalités d’un vrai serveur web (HTTPS, gestion des certificats, authentification, logs de requêtes) si le besoin s’en fait sentir.
L’exemple suivant expose la consommation de mémoire vive sur un endpoint /metrics :
Import-Module Pode
Import-Module PoshTorch
Start-PodeServer {
# Listen on port 8080
Add-PodeEndpoint -Address * -Port 8080 -Protocol Http
# Define the /metrics route that Prometheus will scrape
Add-PodeRoute -Method Get -Path '/metrics' -ScriptBlock {
# Generate your metrics
$metric = New-PrometheusMetric -Name 'ps_script_duration_seconds' `
-Help 'Execution time of the backup script' `
-Type gauge
$metric | Add-PrometheusMetricValue -Value 45.2 -Labels @{ status = "success"; task = "db_backup" }
$metric | Add-PrometheusMetricValue -Value 12.0 -Labels @{ status = "failed"; task = "log_cleanup" }
# Génération du format texte Prometheus via StdOut
$payload = $metric | Out-PrometheusMetric
# Renvoi de la réponse HTTP avec l'en-tête attendu par Prometheus
Write-PodeTextResponse -Value $payload -ContentType 'text/plain; version=0.0.4'
}
}
Au fait, vous vous demandez peut-être pourquoi le nom PoshTorch ? Direction le readme du repo Github pour la réponse !



