TP N°9 : Notifier une alerte critique via un webhook, et exposer le rapport via une mini-API

Sophie ferme la boucle de cette section avec deux tickets liés : “D’abord, je veux une alerte instantanée dans notre salon Teams dès qu’un serveur tombe sous 20 % d’espace disque — un email, c’est trop lent pour une urgence. Ensuite, je veux que l’équipe puisse consulter l’état du parc à tout moment, sans attendre le rapport du matin.”

Objectif

Combiner Invoke-RestMethod (9.1), la gestion d’erreurs API (9.3) et le module Pode (9.4) pour construire deux automatisations complémentaires, toutes deux appuyées sur le script de supervision déjà écrit au TP N°7 de la section 7.

Un webhook Teams (ou Slack) est une simple URL fournie par une intégration configurée sur le salon cible ; à défaut d’en disposer pour ce TP, remplacez l’appel par un Write-Output simulant l’envoi, la logique du script reste identique.

Partie 1 : le webhook d’alerte

Étape 1 — Reprenez le script de supervision du TP N°7 (section 7), et isolez uniquement les serveurs sous 20 % d’espace disque libre dans une variable $serveursCritiques.

Étape 2 — Construisez le corps JSON attendu par un webhook Teams (format simplifié) et envoyez-le avec Invoke-RestMethod en méthode POST.
Indice : revoyez la leçon 9.1, section “Les verbes HTTP”, pour la structure -Method Post -Body ... -ContentType "application/json".

Étape 3 — N’envoyez le webhook que si $serveursCritiques contient au moins un élément (pas de notification si tout va bien).

Étape 4 — Entourez l’appel au webhook d’un try/catch, pour que l’échec de la notification elle-même n’interrompe pas le reste du script.

Partie 2 : la mini-API de consultation

Étape 5 — Créez un script api-supervision.ps1 qui démarre un serveur Pode sur le port 8080, avec une route GET /api/supervision renvoyant le rapport complet en JSON.

Étape 6 (bonus) — Ajoutez une seconde route GET /api/supervision/critiques qui ne renvoie que les serveurs sous le seuil de 20 %.

Solution commentée

Voir la solutionMasquer la solution

Partie 1 — webhook d’alerte :

$serveurs = Get-Content -Path ".\serveurs.txt"

$resultats = Invoke-Command -ComputerName $serveurs -ScriptBlock {
    $volume = Get-Volume -DriveLetter C
    [PSCustomObject]@{
        EspaceLibrePourcent = [math]::Round(($volume.SizeRemaining / $volume.Size) * 100, 1)
    }
} -ErrorAction SilentlyContinue

$serveursCritiques = $resultats | Where-Object { $_.EspaceLibrePourcent -lt 20 }

if ($serveursCritiques) {
    $listeServeurs = ($serveursCritiques | ForEach-Object { "$($_.PSComputerName) : $($_.EspaceLibrePourcent)%" }) -join "`n"

    $corpsMessage = @{
        text = "⚠️ Alerte espace disque Nordika`n$listeServeurs"
    } | ConvertTo-Json

    try {
        Invoke-RestMethod -Uri $env:NORDIKA_WEBHOOK_TEAMS -Method Post -Body $corpsMessage -ContentType "application/json"
        Write-Output "Alerte envoyée pour $($serveursCritiques.Count) serveur(s)"
    } catch {
        Write-Warning "Échec de l'envoi du webhook : $($_.Exception.Message)"
    }
} else {
    Write-Output "Aucun serveur critique, pas de notification envoyée"
}

Partie 2 — api-supervision.ps1 :

Start-PodeServer {
    Add-PodeEndpoint -Address localhost -Port 8080 -Protocol Http

    Add-PodeRoute -Method Get -Path '/api/supervision' -ScriptBlock {
        $serveurs = Get-Content -Path "C:\Nordika\Scripts\serveurs.txt"

        $resultats = Invoke-Command -ComputerName $serveurs -ScriptBlock {
            $volume = Get-Volume -DriveLetter C
            [PSCustomObject]@{
                Serveur             = $env:COMPUTERNAME
                EspaceLibrePourcent = [math]::Round(($volume.SizeRemaining / $volume.Size) * 100, 1)
            }
        } -ErrorAction SilentlyContinue

        Write-PodeJsonResponse -Value $resultats
    }

    # Étape 6 (bonus)
    Add-PodeRoute -Method Get -Path '/api/supervision/critiques' -ScriptBlock {
        $serveurs = Get-Content -Path "C:\Nordika\Scripts\serveurs.txt"

        $resultats = Invoke-Command -ComputerName $serveurs -ScriptBlock {
            $volume = Get-Volume -DriveLetter C
            [PSCustomObject]@{
                Serveur             = $env:COMPUTERNAME
                EspaceLibrePourcent = [math]::Round(($volume.SizeRemaining / $volume.Size) * 100, 1)
            }
        } -ErrorAction SilentlyContinue

        $critiques = $resultats | Where-Object { $_.EspaceLibrePourcent -lt 20 }
        Write-PodeJsonResponse -Value $critiques
    }
}

Points clés à retenir :

  • $env:NORDIKA_WEBHOOK_TEAMS : l’URL du webhook, considérée comme un secret (elle permet à quiconque de poster dans le salon), n’est jamais codée en dur — cohérent avec le principe posé dès la leçon 9.2.
  • Le try/catch autour du webhook garantit qu’une notification Teams en échec (service indisponible, URL expirée) ne fait pas planter tout le script de supervision.
  • La route bonus /api/supervision/critiques réutilise exactement la même logique Where-Object que la Partie 1 — une belle illustration que les mêmes réflexes de filtrage, vus dès la section 2, s’appliquent aussi bien à un script de notification qu’à une route d’API.

Retour d’expérience terrain : ce TP correspond presque exactement à ce que beaucoup de services IT finissent par construire en interne, une fois les bases solides : un webhook pour l’urgence immédiate, une API légère pour la consultation à la demande, et un rapport planifié (section 8) pour l’archive quotidienne. Trois canaux différents, un seul script de supervision sous-jacent — la même logique que vous avez patiemment construite depuis la section 7.