Jetzt testen

Teams-Webhooks per PowerShell – modernes Alerting (Teil 3/3)

Inhaltsverzeichnis

Post Featured Image

Teams Adaptive Cards:
Am Beispiel von Zertifikats-Monitoring mit PowerShell

Wenn du zu dem Teil der Admins gehörst, welche noch nie Probleme oder Downtimes wegen eins abgelaufenen Zertifikats hatten, dann hattest du entweder extrem viel Glück oder du hast dein Zertifikatsmanagement verdammt gut im Griff. In vielen Unternehmen gibt es hin und wieder Probleme mit abgelaufen Zertifikaten, deren Gültigkeit erst geprüft wird, sobald diese bereits ausgelaufen sind und der Service nicht mehr erreichbar ist.

Damit dir das nicht (mehr) passiert, gebe ich dir ein PowerShell-Script mit an die Hand, das Server auf ablaufende Zertifikate prüft. Zugegebenermaßen ist das Script zum Auslesen der Zertifikate recht uninteressant, schon fast nebensächlich. Denn viel spannender und wichtiger ist die Art und Weise wie du über das Auslaufen der Zertifikate benachrichtigt wirst. In den vorangegangenen Teilen dieser Reihe habe ich dir gezeigt, wie du Benachrichtigungen oder Alarme ganz einfach per PowerShell an Teams senden kannst (Das kannst du hier nachlesen: Teil 1, Teil 2). Dabei haben wir uns aber immer nur auf die reine Informationsebene konzentriert, was in vielen Fällen auch ausreicht. In diesem Artikel möchte ich dir zeigen, wie du sogenannte "Adaptive Cards" versenden kannst. Diese haben den Vorteil, dass du unter anderem Buttons in die Nachrichten einfügen kannst, was ganz neue Möglichkeiten ergibt z.B. auf Alarme zu reagieren.

  • Dein Serverspeicher läuft voll? Kein Problem! Lasse dich per PowerShell benachrichtigen und implementiere einen Button zum Erweitern des Speichers! Diesen kannst du dann auch vom Smartphone betätigen, während du an der Kaffeemaschine wartest oder das Kind in die Schule bringst.

  • Du willst Alerts automatisch in Tickets umwandeln? Füge einen Button in die Teams-Card ein, über welchen du per HTTP-Request neue Einträge in deinem Ticket-System erstellen und die Informationen aus der Teams-Nachricht hinzufügen kannst.
  • Ein Server in Azure wurde unerwartet beendet? Lasse dich darüber benachrichtigen und starte diesen über einen Klick in Teams neu.

Wie du siehst, gibt es verschiedene Use Cases, bei denen eine direkte Reaktion aus der Nachricht heraus sinnvoll sein kann. Wir bauen in diesem Artikel ein Script, das die Zertifikate auf verschiedenen Servern ausliest und prüft, ob diese in den nächsten 100 Tagen ablaufen, und senden dabei eine Nachricht an Teams. Diese Nachricht besitzt einen Button, über welchen wir direkt in die Zertifikatseinstellungen des jeweiligen Servers im Windows-Admin-Center gelangen, um somit Änderungen durchzuführen.

Die Nachricht, die wir gestalten werden, sieht folgendermaßen aus:
So soll unsere Nachricht aussehen - expiration alert

Nachricht mit Button 

Vorbereitung

Wir benötigen wieder einen Teams-Channel, welcher WebHooks empfangen kann. (In den vorangegangenen Teilen dieser Artikelserie wurde die Konfiguration genauer beschrieben). Wenn du hartgesotten bist, kannst du die Teams-Nachricht natürlich über JSON gestalten. Da es sich hier um eine recht simple Anforderung handelt, können wir uns das Leben aber viel einfacher machen: Das Modul "PSTeams" ermöglicht dir die Gestaltung der Card mit einfachen PowerShell-Cmdlets, sodass du dich nicht mit JSON quälen musst. In unserem Fall wird natürlich noch eine Installation des Windows-Admin-Centers benötigt; du bist aber natürlich frei darin mit welcher Aktion du auf den Alert über den Button reagieren willst, falls du das WAC nicht nutzt. Der Befehl, um uns alle Zertifikate auf einem Server ausgeben zu lassen, welche in den nächsten 100 Tagen auslaufen, lautet:

Get-Childitem Cert: -Recurse -ExpiringInDays 100 | Select-Object FriendlyName, Issuer, Thumbprint, NotBefore, NotAfter, PSParentPath

Wir haben nun also alle Informationen, um mit der Gestaltung der AdaptiveCard zu beginnen. Der Code am Beginn des Scripts sieht folgendermaßen aus:

# Array with Computers, that should be monitored
$TargetComputers = @("Server01")
# TeamsID - URL generated by Teams
$TeamsID = ""
# URL of Windows Admin Center
$WACURL = "<https://localhost:6516/>"

# ModuleCheck: Installs PSTeams if not available
if(-not (Get-Module -ListAvailable PSTeams)) {
Install-Module -Name PSTeams -Force
}
else {
Write-Verbose "PSTeams is already installed."
}

 

Gestaltung der Teams-Card mit PSTeams

Für uns relevant sind drei Objekte aus PSTeams: Sections, Facts und Buttons. Sections dienen der logischen und visuellen Abgrenzung, ihnen untergeordnet sind sowohl Facts als auch Buttons. Facts enthalten sämtliche Informationen, die wir über Teams anzeigen wollen. Buttons öffnen Websites oder setzen anderweitige HTTP-Requests ab.

In unserem Fall sind die Zertifikatsattribute jeweils Facts. Der Friendlyname eines Zertifikats, wie auch der Thumbprint, etc. wird als Fact dargestellt und einer Section untergeordnet. Eine Section beinhaltet dabei immer genau ein Zertifikat. Eine Teams-Nachricht bezieht sich immer nur auf einen Server, deshalb benötigen wir auch nur einen Button in der gesamten Card, welcher uns zum Server-Eintrag im Windows Admin Center führt. Dieser Button hat seine eigene Section.
Wir müssen nun also sämtliche Server aus dem Array "$TargetComputers" abfragen - dies machen wir mit einer Foreach-Schleife, sodass wir direkt danach von dem jeweiligen Server die entsprechenden Zertifikatsdaten erhalten können:

foreach ($computer in $TargetComputers) {
# Getting all certificates of specified computer, that will expire in the next 100 days
[array]$ExpiringCerts = Invoke-Command -ComputerName $computer -Credential $cred -ScriptBlock {
Get-ChildItem Cert:\\LocalMachine -Recurse -ExpiringInDays 100 |
Select-Object FriendlyName, Issuer, Thumbprint, NotBefore, NotAfter, PSParentPath
}
}

Die Variable $ExpiringCertificates enthält nun alle Zertifikate, die in den kommenden 100 Tagen ablaufen. Jetzt gilt es diese Informationen wie oben beschrieben auf die verschiedenen Sections aufzuteilen. Erstelle dazu ein leeres Array, welches wir Stück für Stück mit Sections füllen. Innerhalb der bereits beschreiben ForEach-Schleife erstellen wir eine weitere ForEach-Schleife, welche über alle Zertifikate iteriert, pro Zertifikat eine neue Section erstellt, diese Section mit den Facts (also den Attributen des aktuellen Zertifikats) füllt und die neu erstellte Section dann dem Section-Array hinzufügt. Am Ende haben wir nun also ein Array mit allen Informationen (in Sections unterteilt) und könnten dieses direkt an Teams senden. Zuvor wird aber noch eine letzte Section erstellt, die den Button für das Windows-Admin-Center enthält. Den Link, den der Button aufruft, modifizieren wir für jeden Server, da in der URL definiert werden kann, welcher Computer/Server im Admin Center geöffnet werden soll. Unser Code sieht nun also folgendermaßen aus:

 

# Array with Computers, that should be monitored
$TargetComputers = @("Server01")
# TeamsID - URL generated by Teams
$TeamsID = ""
# URL of Windows Admin Center
$WACURL = "<https://localhost:6516/>"


# ModuleCheck: Installs PSTeams if not available
if(-not (Get-Module -ListAvailable PSTeams)) {
    Install-Module -Name PSTeams -Force
}
else {
    Write-Verbose "PSTeams is already installed."
}


# Iterating through every computer in $TargetComputers
foreach ($computer in $TargetComputers) {
# Getting all certificates of specified computer, that will expire in the next 100 days
    [array]$ExpiringCerts = Invoke-Command -ComputerName $computer -Credential $cred -ScriptBlock {
        Get-ChildItem Cert:\\LocalMachine -Recurse -ExpiringInDays 100 |
        Select-Object FriendlyName, Issuer, Thumbprint, NotBefore, NotAfter, PSParentPath
    }


    # Checking, whether there are any certificates expiring in the specified timespan before proceeding
    if ($ExpiringCerts.Count -gt 0){


        # Creating Sections with embedded Facts (Certificate Information) for Teams
        $Sections = @()
        foreach ($cert in $ExpiringCerts) {
            $facts = @()
        $cert |
                Get-Member |
                Where-Object MemberType -eq NoteProperty |
                ForEach-Object {
                    $facts += New-TeamsFact -Name $_.Name -Value "**$($cert.($_.Name))**"
                }
            $Sections += New-TeamsSection -ActivityDetails $facts
        }


        # Gets server-URL within Windows Admin Center and Teams-Button to access it
        $WACURLServer = $WACURL + "servermanager/connections/server/" + $computer + "/tools/certificates"
        $Button = New-TeamsButton -Name 'Edit Certificates' -Link $WACURLServer -Type 'ViewAction'
        $Section = New-TeamsSection -Buttons $Button


        # Send Card
        $Sections += $Section
        $Count = $ExpiringCerts.count
        Send-TeamsMessage -URI $TeamsID -Color Red -Sections $Sections `
        -MessageTitle "Alert: $count Certificates on $computer expire within the next 100 days!" `
    }


}

 

Fazit 

Wenn wir nun also diesen Code ausführen und sich auslaufende Zertifikate auf den Maschinen befinden, erhalten wir die oben gezeigte Teams-Card. Du hast nun in wenigen Minuten ein eigenes Alerting für deine Zertifikate erstellt 😉


Zusätzliche Hinweise:
Falls in deiner Organisation sämtliche Zertifikate über eine zentrale CA ausgestellt wurden, ist es sinnvoller, nicht jeden einzelnen Server auf seine Zertifikate abzufragen, sondern eine zentrale Abfrage auf die CA zu starten. Die angegebenen 100 Tage sind keine Empfehlung meinerseits, da diese Anzahl in meinen Augen viel zu groß ist. Ich habe die 100 Tage lediglich aus Demonstrationszwecken gewählt, um auf jeden Fall ein paar Treffer zu haben. Meiner Ansicht nach empfiehlt sich ein Zeitraum von 15-30 Tagen für die Überwachung, wobei dies natürlich von Umgebung zu Umgebung anders zu bewerten ist.

 


Weiterführende Links


Über den Autor: