Provisionieren von Teams über PowerShell, Azure Automation Services und SharePoint

Kaum ist die Übersicht gebloggt, entfernt Microsoft ein Baustellenschild und stellt einen Tag später das Modul für die PowerShell-Unterstützung von Microsoft Teams bereit. Damit haben wir neben der Beta-API erstmals eine Möglichkeit, Provisionierung und Einstellungen von Teams außerhalb des Clients zu erledigen. Um das nicht über die Konsole bewerkstelligen zu müssen, kann man beispielsweise mit den Azure Automation Services, Webhooks und ein bisschen JavaScript im SharePoint eine Brücke bauen.

Das Powershellmodul ist unter https://www.powershellgallery.com/packages/MicrosoftTeams/0.9.0 herunterladbar, in der PowerShell selbst kann mit npm auch mit

Install-Module -Name MicrosoftTeams

innerhalb von Sekunden auf dem eigenen Client bereitgestellt werden. Insgesamt haben wir 23 Cmdlets, die alle mehr oder weniger nach dem bekannten Office 365 Muster arbeiten und wenig Überraschendes bieten. Auch hier muss sich mit Connect-MicrosoftTeams grundsätzlich mit Credentials verbunden werden, bevor die anderen Befehle genutzt werden können. Als kleine Kostprobe hier einmal das Erstellen eines neuen Teams:

PowerShell Cmdlets für Teams
Neues Team erstellen – PowerShell Cmdlets für Teams
Das Team wurde erstellt, der Account, unter dem der Befehl durchgeführt wurde, hinzugefügt.
Das Team wurde erstellt, der Account, unter dem der Befehl durchgeführt wurde, hinzugefügt.
Einige der Einstellungen werden aufgelistet.
Einige der Einstellungen werden aufgelistet.

Azure Automation Services

Neben dem schnöden blauen Bildschirm gibt es noch eine weitaus spannendere Sache, die Mechanik in Gang zu setzen. Am Beispiel von Teams lässt sich nämlich recht nett darstellen, wie man die Azure Automation Services in Verbindung mit den PowerShell Modulen verwenden kann. Thomy Goelles hat so etwas in der Richtung bereits gemacht, wir setzen darauf auf und polieren den Aufruf noch etwas auf.

Der Plan

Unser Anwendungsfall soll sein, dass wir ein neues Team über ein kleines Formular auf einer SharePoint Page anlegen. Durch einen Klick soll dann ein Webhook in den Azure Automation Services getriggert werden, der dann ein Runbook laufen lässt, welches die Teams PowerShell Cmdlets mit in Azure hinterlegten Credentials eines Serviceaccounts verwendet, der schlussendlich das neue Team provisioniert.

Im echten Leben ließe sich so außerhalb des Clients ohne administrativen Zugriff das Provisionieren realisieren, außerdem wäre es möglich, über einen POST von einem beliebigen System einen Webhook aufzurufen, der das macht. Hier könnte beispielsweise wieder einmal Flow ins Spiel kommen.

PowerShell Module in Azure deployen

Man muss schon fast willentlich verbeigucken um den Button für das Deployen nach Azure in der PowerShell Gallery nicht zu sehen:

PowerShell in Azure deployen
PowerShell in Azure deployen

Man wird zur Anmeldung in Azure weitergeleitet und nach kurzer Zeit steht das Modul in der Liste der PowerShell Versatzstücke zur Verfügung. Damit es hier ein Zuhause findet, wählt man einen Ziel-Automation Account aus oder erstellt einen neuen. In diesem Beispiel starten wir von ganz vorne:

Nach dem Anlegen kann man die zur Verfügung stehenden Module sehen und voila – Teams ist da und einsatzbereit.

Schaut man sich die Details des Moduls an, kann man alle Cmdlets sehen, die hier inbegriffen sind. Die kleine Warnung in der Beschreibung sollte man übrigens ernst nehmen, da komme ich aber später noch einmal zu.

Das Runbook

Das Runbook kann man sich in diesem Szenario als den Platz vorstellen, an dem der eigentliche PowerShell Skripting Code geschrieben wird. Diese Skripte werden dann serverless ausgeführt – konkrete Beschreibungen sowie die dazugehörigen Funktionen dazu sind erstaunlich gut bei Microsoft dokumentiert. Für ein solches Runbook wählt man als erstes den Typ aus – für uns wird es ein einfaches PowerShell richten. Das hat den Vorteil, dass es sehr simpel ist, allerdings auch einige Nachteile. Weiterführende Details dazu hier.

Wenn das Runbook grundsätzlich erstellt wurde und erster Code gespeichert worden ist (wichtig, sonst sind die Optionen ausgegraut), kann ein Webhook über die Kontext-Aktionen erstellt werden. Dieser Webhook ist ein Aufruf einer Adresse mit einem speziellen Token in der URL. Nur, wer dieses Token kennt, kann den Webhook triggern.

Daher ist die Warnung, die recht prominent ins Gesichtsfeld geschoben wird, entsprechend wichtig: Der konkrete Link zum Webhook wird nur ein einziges Mal angezeigt. Verliert man die Adresse, muss man einen neuen bauen.

Die Credentials

Ein Problem, wenn man sich nicht in seiner eigenen Session auf dem Desktop befindet, ist die Identität, unter der die Befehle später abgefeuert werden dürfen. Wie alle anderen Services auch, verlangen die PowerShell Cmdlets, dass die Person, unter deren Identität man sich konnektiert hat, auch die notwendigen Berechtigungen hat, um die Operationen ausführen zu dürfen. Da in unserem Fall die Anfragen aus verschiedenen Quellen kommen und der Aufruf der Webhook-URL keine Rechte per se mitgeben kann, benötigen wir einen hinterlegten Account, mit dem später im Skript die Verbindung aufgebaut wird.

Hierzu lassen sich in Azure die gewünschten Credentials hinterlegen und mit einer Kennung versehen, sodass sie später in der PowerShell einfach wieder geladen und verwendet werden können.

Credentials in Azure Automation Services
Credentials in Azure Automation Services

Damit sind wir bestens vorbereitet, das Skripting zu beginnen.

Das PowerShell Skript

Im Grunde ist das Skripting zum Anlegen eines Teams so straight forward wie es eigentlich geht. Verbinden, Team anlegen, Verbindung schließen, fertig. Damit wir es nicht ganz so einfach haben, wollen wir dem Webhook noch zwei Parameter mitgeben:

  • Der Name des Teams
  • Eine Beschreibung für das Team.

Das sind die beiden Standardfelder, die man auch in der Maske des Teams Client präsentiert bekommt.

Der Webhook bekommt die beiden Parameter serialisiert im JSON-Format. Für die Webentwicklungsfüchse: Wenn wir ihn später von außen aufrufen, entspricht das einem POST-Call mit entsprechenden Daten im RequestBody. Hier muss man einmal wissen, dass man die Variable unbedingt $WebHookData nennen sollte. Ansonsten gehen diese Daten auf dem Weg bis zum Skript förmlich verloren. Damit wissen wir auch, dass das Skript von einem Webhook aufgerufen worden ist.

Dann suchen wir uns durch Deserialisieren und Zugriff auf die hinterlegten Objekte die Daten raus. Beim Testing direkt in Azure und beim Aufruf durch einen Webhook kann es passieren, dass die Daten im RequestBody entweder schon gleich mit-deserialisiert werden können oder das später noch einmal explizit getan werden muss. Daher gibt es hier noch ein kleines Extra-If.

Für die Anmeldung müssen wir uns wie beschrieben unsere Credentials holen, die wir vorher hinterlegt haben. Das geht dank passender Cmdlets sehr stressfrei von der Hand.

Der Rest ist dann das Anlegen des Teams, wo wir schon einmal dabei sind, gibt es gleich drei Kanäle hinterher und eine Einstellung schrauben wir auch noch rein.

Damit hätten wir dann alles eingefügt. Wichtig ist das Veröffentlichen, damit die Änderungen auch an der Front ankommen.

PowerShell in Azure Automation Service
PowerShell in Azure Automation Service

Hier noch einmal alles zusammengefasst als Code. Dieser kann sicherlich noch an diversen Stellen optimiert und verbessert werden, für diese kleine Demo sollte aber der Anspruch reichen.

Der Aufruf des Webhooks – SharePoint und JavaScript

Als Quelle der Aufrufe haben wir in unserem Szenario eine SharePoint Seite definiert, die mit einem kleinen Webformular und einem Button versehen und dort den Aufruf hinterlegen. Unter normalen Umständen würde man hier nun mit dem SharePoint Framework eine moderne Lösung bauen.

Um den Artikel nicht noch länger werden zu lassen, begnügen wir uns hier mit der richtig hässlichen Lösung und packen das notwendige JavaScript kurzerhand in ein Skript Editor WebPart. Da CSS generell überbewertet ist, muss es blankes HTML tun.

Skript Editor WebPart in SharePoint
Skript Editor WebPart in SharePoint

Der Code ist dadurch aber sehr übersichtlich. Wir brauchen lediglich die Input Controls für die Abfrage von Titel und Beschreibung sowie einen Linkbutton. Dazu gesellt sich dann bei Klick auf den Link im aufgerufenen JavaScript ein AJAX-Call, der die beiden Felder ausliest und an die Adresse des Webhooks posted. Das kann dann in etwa wie folgt aussehen.

Falls MarkH. hier mitliest: Extra nur für Dich habe ich den Linkbutton so fies daneben gesetzt. Weil ich Dein schlimmster Albtraum bin! 🙂

Alles zusammen durchlaufen lassen

Nach all der Arbeit probieren wir doch nun einmal das ganze Gebilde aus. Nach Eingabe eines Namens für das neue Team und einer Beschreibung klicken wir in SharePoint auf unseren unansehnlichen Link. Macht man die Devtools auf, sieht man sehr schön, wie die Adresse des Webhooks aufgerufen wird und die Daten serialisiert mitgeschickt werden.

Dieser Call kommt natürlich in Azure an. Auf dem nächsten Screenshot in der Aktivitätenverfolgung kann man dann verfolgen, von wo mit welchen Parametern der Aufruf geschieht.

Webhook Inputparameter
Webhook Inputparameter

Analog kann man sich auf der Konsole anschauen, was das Skript denn so macht. Da wir ein paar Ausgaben auf die Konsole geworfen haben, werden diese im Verlauf der Abarbeitung sichtbar.

Das Endergebnis

Nach all dem beschriebenen Zauber ist das Endergebnis recht unspektakulär, denn es besteht lediglich aus dem neuen Team, welches nach kurzem Moment im Client auftaucht.

Wer sich tatsächlich den oben dokumentierten Code angeschaut hat, wird die drei Kanäle vermissen, die eigentlich mit dem Skript angelegt werden sollten. Dieses korrespondiert mit den drei Fehlern, die das Skript noch wirft und ebenfalls mit den Versuchen, per normaler PowerShell auf die Kanäle und Get-Team Cmdlets zuzugreifen. Aktuell scheint in einigen Tenants noch eine alte Version der Graph API ausgerollt zu sein, sodass einige der Befehle aktuell noch nicht erfolgreich ausgeführt werden können. Exemplarisch hier eine der typischen Rückmeldungen. Man ahnt in etwa, was da falsch laufen könnte.

Fazit

Der Artikel hat gezeigt, wie man mit den Komponenten PowerShell, Azure Automation Services, Webhooks und JavaScript in SharePoint Teams fernsteuern kann. Dieses Beispiel ist natürlich nur exemplarisch für viele denkbare Anwendungsfälle, wie oben bereits erwähnt können weitere Dienste wie Flow ebenfalls hilfreich sein, Administration und Automatisierung mit Microsoft Teams zu realisieren. Die Kombination ermöglicht eine weitreichende Flexibilität mit einem Minimum an händischer Arbeit. Auch die Verwendung komplexerer Runbooks als die hier verwendete PowerShell-Option sind denkbar. Unsere Implementierung sendet beispielsweise keine Response in Form einer Benachrichtigung an den Benutzer zurück. In der oben verlinkten Übersicht der Runbooktypen gibt es Hinweise auf Möglichkeiten, das weitaus besser zu machen.

Der Umfang der PowerShell Cmdlets lässt derzeit allerdings noch etwas zu wünschen übrig: Mehr als grundlegende Strukturen und Einstellungen lassen sich noch nicht handhaben: Keine Registerkarten, Bot-Registrierungen, nichts in Richtung der Skype-Funktionalitäten in Teams oder Einfluss auf die Chats. Dennoch ein netter Start und dringend benötigt.

 

Titelbildhttps://pixabay.com/p-997249/

One thought on “Provisionieren von Teams über PowerShell, Azure Automation Services und SharePoint

  1. Cooler Beitrag! Nur die Geschichte mit den hinterlegten Credentials in Azure gefällt mir noch nicht so richtig. Wenn ich irgendwann mal Berechtigung auf der Seite hatte, von der der WebHook angesprochen wird, kann ich den WebHook theoretisch von überall triggern. Du hast ja selbst den Call mit den DevTools ausgelesen 😉

    Antworten

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.