Alerts mit PowerShell und Teams-WebHooks (2)
Teil zwei: Adaptive Cards und Zertifikats-Monitoring
Von: Philip Lorenz
Im ersten Teil dieser Reihe demonstrierte ich ich die grundsätzliche Verwendung von Teams-WebHooks mithilfe der PowerShell. Dabei habe ich mich jedoch auf die Informationsebene beschränkt, also die reine Übermittlung von textbasierten Alerts ohne zusätzliche Funktionalität. In diesem Teil gehen wir unter der Verwendung individueller Schaltflächen über den reinen Informationsgrad hinaus.
Teams Adaptive Cards: Am Beispiel von Zertifikats-Monitoring mit PowerShell
Falls du zu den Admins gehörst, die noch nie mit Problemen oder Ausfallzeiten aufgrund eines abgelaufenen Zertifikats zu kämpfen hatten, dann hattest du entweder außergewöhnliches Glück, oder du hast dein Zertifikatsmanagement hervorragend im Griff. In vielen Firmen treten gelegentlich Probleme mit abgelaufenen Zertifikaten auf, deren Gültigkeit oft erst überprüft wird, wenn sie bereits abgelaufen sind und der Service nicht mehr verfügbar ist.
Um zu verhindern, dass dir das (wieder) passiert, stelle ich dir ein PowerShell-Skript zur Verfügung, das Server auf ablaufende Zertifikate überprüft. Zugegeben: Das Skript zum Auslesen der Zertifikate ist eher unspektakulär, fast schon nebensächlich. Viel interessanter und relevanter ist die Methode, wie du über das Auslaufen der Zertifikate informiert wirst. In diesem Artikel möchte ich dir zeigen, wie du sogenannte Adaptive Cards versenden kannst. Diese bieten den Vorteil, dass du beispielsweise Buttons in die Nachrichten einfügen kannst, was ganz neue Möglichkeiten zur Reaktion auf Alarme eröffnet, zum Beispiel:
- Du möchtest Alerts automatisch in Tickets umwandeln? Füge dem WebHook-Alert einen Button hinzu, über den die Informationen an den Ticket-Dienst gesendet werden. Du kannst dies sogar von deinem Smartphone aus tun, während du im Fitnessstudio bist oder den Hund ausführst.
- Ein Dienst auf deinem Server hat unerwartet gestoppt? Lass dich darüber informieren und starte ihn mit einem Klick in Teams neu.
Wie du erkennen kannst, gibt es verschiedene Anwendungsfälle, bei denen eine unmittelbare Reaktion direkt aus der Nachricht heraus nützlich sein kann. In diesem Artikel erstellen wir ein Skript, das die Zertifikate auf verschiedenen Servern ausliest, überprüft, ob diese in den nächsten 100 Tagen ablaufen, und dabei eine Nachricht an Teams sendet. Diese Nachricht enthält einen Button, mit dem wir direkt zu den Zertifikatseinstellungen des jeweiligen Servers im Windows-Admin-Center gelangen können, um dort notwendige Änderungen vorzunehmen.
Die Nachricht, die wir gestalten werden, sieht folgendermaßen aus:
Die Vorbereitung
Natürlich brauchen wir wieder einen Teams-Kanal, der WebHooks empfangen kann. Wie du das einrichtest, habe ich dir im ersten Artikel dieser Serie erklärt. Da unsere Anforderungen hier recht einfach sind, können wir uns das Leben erleichtern: Das Modul PSTeams ermöglicht es dir, die Card mit einfachen PowerShell-Cmdlets zu gestalten, so dass du dich nicht mit JSON herumschlagen musst. In unserem Fall benötigen wir natürlich auch eine Installation des Windows-Admin-Centers. Du hast aber die Freiheit, selbst zu entscheiden, wie du auf den Alert über den Button reagieren möchtest, falls du das WAC nicht nutzt. Der Befehl, um alle Zertifikate auf einem Server anzeigen zu lassen, die in den nächsten 100 Tagen auslaufen, lautet:
Get-Childitem Cert: -Recurse -ExpiringInDays 100 | Select-Object FriendlyName, Issuer, Thumbprint, NotBefore, NotAfter, PSParentPath
Gefiltert habe ich den Befehl übrigens nach den Attributen, die mir wichtig erscheinen. Wir haben nun also alle Informationen, um mit der Gestaltung der Adaptive Card 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."
}
Zuerst werden sämtliche Ziel-Computer (welche später bezüglich der Zertifikate abgefragt werden) definiert. Anschließend musst du noch deine Teams-D für den WebHook angeben. Die WACURL entspricht der URL deines Windows-Admin-Centers. Anschließend prüfen wir noch, ob PSTeams installiert ist – wenn dieses noch nicht vorhanden ist, wird es installiert.
Gestaltung der Teams-Card mit PSTeams
Drei Elemente aus PSTeams sind für uns von Bedeutung: Facts, Sections und Buttons. Facts enthalten alle Informationen, die wir über Teams darstellen möchten. Diese Facts sind verschiedenen Sections zugeordnet. Diese Sections dienen der logischen und visuellen Trennung. Buttons sind ebenfalls einer Section zugeordnet und öffnen eine Webseite oder setzen andere HTTP-Anfragen ab.
In unserem Fall sind die Zertifikatsattribute jeweils Facts. Der Friendlyname eines Zertifikats, ebenso wie der Thumbprint usw., wird als Fact dargestellt und einer Section zugeordnet. Eine Section enthält dabei immer genau ein Zertifikat. Eine Teams-Nachricht bezieht sich immer nur auf einen Server, daher benötigen wir auch nur einen Button in der gesamten Card, der uns zum Servereintrag im Windows Admin Center führt. Dieser Button hat seine eigene Section.
Nun müssen wir alle Server aus dem Array $TargetComputers abfragen – dies tun wir mit einer Foreach-Schleife, sodass wir direkt danach die entsprechenden Zertifikatsdaten vom jeweiligen Server 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 beinhaltet nun alle Zertifikate, die in den nächsten 100 Tagen ablaufen. Nun müssen wir diese Informationen, wie zuvor beschrieben, auf die verschiedenen Sections verteilen. Dazu erstellen wir ein leeres Array, das wir nach und nach mit Sections befüllen. Innerhalb der bereits beschriebenen ForEach-Schleife erstellen wir eine weitere ForEach-Schleife, die über alle Zertifikate iteriert. Für jedes Zertifikat wird eine neue Section erstellt, diese Section mit den Facts (den Attributen des aktuellen Zertifikats) gefüllt und die neu erstellte Section dem Section-Array hinzugefügt. Am Ende haben wir also ein Array mit allen Informationen (in Sections unterteilt) und könnten dieses direkt an Teams senden. Bevor wir das tun, erstellen wir jedoch noch eine letzte Section, die den Button für das Windows-Admin-Center enthält. Den Link, den der Button aufruft, passen wir für jeden Server an, da in der URL festgelegt 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!" `
}
}
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!
Hinweis: Wenn in deiner Organisation alle Zertifikate von einer zentralen Zertifizierungsstelle (CA) ausgestellt wurden, ist es effizienter, eine zentrale Abfrage an die CA zu senden, anstatt jeden einzelnen Server auf seine Zertifikate zu überprüfen. Die genannten 100 Tage sind keine persönliche Empfehlung, da ich diesen Zeitraum für zu lang halte. Ich habe die 100 Tage nur zu Demonstrationszwecken gewählt, um sicherzustellen, dass wir einige Treffer erzielen. Meiner Meinung nach ist ein Zeitraum von 15 bis 30 Tagen für die Überwachung angemessen, obwohl dies natürlich je nach Umgebung variieren kann.