14 min read
Microsoft Teams – 3. Teil der Graph PowerShell Reihe
MVP Damien Scoles berichtet über seine Erfahrungen mit Microsoft Graph. In seinem dritten Artikel geht er näher auf...
ScriptRunner Blog
Möchtest du mehr über die Überwachung von Microsoft Teams mit PowerShell erfahren? Lies, wie du die Einstellungen im Laufe der Zeit auf Änderungen überprüfen kannst. Verhindere (oder korrigiere) Konfigurationsabweichungen.
Bei Teams kann es zu unterschiedlichen Formen des "Wildwuchs" kommen. Hinter Teams sprawl verbirgt sich ein Ausufern oder Aufblähen von Teams, wenn z.B. für ein Projekt dezentral und unkoordiniert neue Teams angelegt werden, aber am Ende des Projektes nicht wieder gelöscht werden. Mit Creep wird die langsame Ausweitung von Umfang, Funktionalitäten, Rechten oder Konfiguration bezeichnet.
Scope Creep, Configuration Creep, und Teams Sprawl haben alle ein gemeinsames Grundproblem – das Fehlen von Überwachung oder Kontrolle, um diese Änderungen zu verhindern. In diesem Artikel wird gezeigt, wie mit Hilfe von PowerShell Teams und Teams-Konfigurationen überwacht und Änderungen erkannt werden können. Aufgrund der Größe und Komplexität von Teams werden wir nicht jeden einzelnen Konfigurationsaspekt behandeln, sondern Administratoren einige Beispielen für die Verwendung von PowerShell an die Hand geben. Ein Musterbeispiel dafür findest du im Sicherheitscenter, dem Configuration Analyzer, der über eine Registerkarte "Drift Analysis" und "History" verfügt.
Wie bei jeder Verwendung von PowerShell-Skripten oder -Tools musst du sicherstellen, dass dein Microsoft Teams PowerShell-Modul mit der neuesten Version läuft:
Update-Module MicrosoftTeams
TSchließe dann deine PowerShell-Sitzung, denn so wird sichergestellt, dass das PowerShell-Modul beim nächsten Mal mit der neuesten Version geladen wird.
Stelle sicher, dass deine Version die neueste ist:
Import-Module MicrosoftTeams
Get-Module MicrosoftTeams
Auch hier vergleichst du die Versionsnummer mit der verfügbaren Version (hier).
Die Erstellung eines benutzerdefinierten Skripts zur Überprüfung einer Microsoft Teams-Konfiguration kann ausschließlich mit Get-*-Cmdlets erfolgen, da es sich hierbei um Discovery PowerShell-Cmdlets handelt, die Einstellungen und Objekte abfragen und die benötigten Details bereitstellen. Eine schnelle Liste dieser Cmdlets findest du mit diesem Einzeiler (sobald du mit dem Microsoft Teams PowerShell Endpunkt verbunden bist):
Get-Command Get-* |
Where Source -eq MicrosoftTeams |
Sort Name |
ft Name
Wir werden nicht auf jedes einzelne der verfügbaren Cmdlets eingehen, da es über 150 davon gibt, aber wir werden einige ausgewählte Beispiele durchgehen, die dabei helfen, wichtige Elemente in Teams zur Überprüfung, also ein 'Audit' der Einstellungen zu finden.
Die Anzahl und die Art der Teams ist ein wichtiger Aspekt bei der Überprüfung einer Teams-Konfiguration, denn Teams können sich über das hinaus ausbreiten, was eine Organisation erstellen oder pflegen wollte. Indem wir die Anzahl der Teams überprüfen, können wir das Wachstum und die Nutzung erkennen, bevor die Zahlen aus dem Ruder laufen. Zuerst wird die Anzahl der Teams abgefragt:
(Get-Team).Count
Das Ergebnis könnte so aussehen:
Get-Team |
ft DisplayName,Visibility,Archived,GroupId
Jedes Team kann einen oder mehrere Kanäle haben, über die es den Überblick behält:
Get-Team |
ForEach-Object {Write-Host $_.DisplayName -ForegroundColor Yellow ;Get-TeamChannel -GroupID $_.GroupID |
ft DisplayName,Membership*,Description}
Mit den obigen PowerShell Cmdlets konnten wir eine Menge Daten und Einstellungen über unsere Teams-Umgebung sammeln. Wie können wir diese Daten nutzen, um eine Umgebung wirklich zu überprüfen? Wir können beispielsweise Teams und Teams Channel Sprawl überwachen. In dem folgenden Beispiel überprüfen wir Teams und Teams-Kanäle jeden Monat, um zu sehen, was sich geändert hat:
Wenn die Anzahl der Teams und Channels zum ersten Mal überprüft wird, gibt es vielleicht 35 Teams und 56 Channels. Wenn die Cmdlets dann beispielsweise nach einem Monat erneut ausgeführt werden, existieren bereits 40 Teams und 65 Channels. Wir können die ursprüngliche Anzahl wie folgt abrufen:
# Team count (Anzahl Teams)
(Get-Team).Count
# Teams channel count (Anzahl Channels)
Get-Team |
Foreach-Object {$Channels = (Get-TeamChannel -GroupID $_.GroupID).Count;$TeamsChannelCount=$TotalChannels+$Channels}
Wir können diese Zahlen zu einem späteren Zeitpunkt planmäßig überprüfen:
$TeamsCount = (Get-Team).Count
Get-Team |
Foreach-Object {$Channels = (Get-TeamChannel -GroupID $_.GroupID).Count;$TeamsChannelCount=$TotalChannels+$Channels}
Wenn wir die Anzahl der Teams und Team-Kanäle überprüfen wollen, brauchen wir eine Möglichkeit, die Werte zu speichern und sie mit den aktuellen Zahlen in Teams zu vergleichen.
Erster Durchlauf:
# Date column (Datumsspalte)
$CurrentMonth = Get-Date -Format "MM.yyyy"
# File header (Kopf)
"Date,TeamsCount,TeamsChannelCount" |
Out-File 'TeamsAndChannelCounts.csv'
# First month counts (Anzahl des ersten Monats)
$TeamsCount = (Get-Team).Count
Get-Team |
Foreach-Object {$Channels = (Get-TeamChannel -GroupID $_.GroupID).Count;$TeamsChannelCount=$TotalChannels+$Channels}
$Output = "$CurrentMonth,$TeamsCount,$TeamsChannelCount" |
Out-File 'TeamsAndChannelCounts.csv' -Append
Planmäßige Läufe, bei denen wir Datenreihen haben, die wir auf Unterschiede untersucht wollen:
# Import data (Daten importieren)
$TeamsData = Import-Csv .\TeamsAndChannelCounts.csv
# Last line (letzte Zeile)
$CurrentMonth = $TeamsData[-1]
# Next to last line to compare (vorletzte Zeile zum Vergleich)
$LastMonth = $TeamsData[-2]
# Check each Teams data point for change (überprüfe jeden Datensatz aus Teams auf Änderungen)
If ($CurrentMonth.TeamsCount -gt $LastMonth.TeamsCount) {Write-Host 'There are new Teams present.'}
If ($CurrentMonth.TeamsChannelCount -gt $LastMonth.TeamsChannelCount) {Write-Host 'There are new Teams Channels present.'}
Wenn wir etwas tiefer in die Trickkiste greifen wollen, können wir auch überprüfen, welche Teams seit dem letzten Mal neu hinzugekommen sind. Dazu können wir dies das erste Mal ausführen:
Get-Team |
select DisplayName,Visibility,GroupId,Archived,Description |
Export-Csv -Path HistoricalTeams.csv
Wir können jeden Monat nach Änderungen suchen:
Get-Team |
select DisplayName,Visibility,GroupId,Archived,Description |
Export-Csv -Path CurrentTeams.csv
Dann können wir diese beiden Dateien mit Compare-Object vergleichen:
$Historical = Get-Content .\HistoricalTeams.csv
$Current = Get-Content .\CurrentTeams.csv
Compare-Object -ReferenceObject $Historical -DifferenceObject $Current
In diesem Beispiel sehen wir, dass es zwei verschiedene Gruppen gibt, die neu sind, da der SideIndicator-Wert auf die Dateidaten in der Variable $Current verweist.
Ein weiterer Schritt, den wir mit der PowerShell ausführen können, ist das Ersetzen der Teams-Dateien aus der History durch die aktuellen, damit wir immer die neuesten Zahlen zum Vergleich haben:
Remote-Item HistoricalTeams.csv
Rename-Item CurrentTeams.csv HistoricalTeams.csv
Innerhalb von Teams gibt es Kontrollen dafür, worauf ein Gast Zugriff hat, und wir können diese Einstellungen mit der PowerShell kontrollieren. Die Überwachung der Teams-Konfigurationsaspekte für Nutzer ist ein wichtiger Aspekt der Sicherheit deiner Teams-Konfiguration im Allgemeinen. Wir können dies mit der PowerShell untersuchen, um zu sehen, was wir entdecken und überwachen können.
Zuerst die PowerShell Cmdlets:
Get-Command Get-*team*guest*
Das liefert diese Cmdlets:
Get-CsTeamsGuestCallingConfiguration
Get-CsTeamsGuestMeetingConfiguration
Get-CsTeamsGuestMessagingConfiguration
Jedes dieser Cmdlets gibt Aufschluss über einen anderen Aspekt der Konfiguration. Mit der PowerShell können wir die Einstellungen dokumentieren und dann auf Änderungen hin vergleichen, genau wie wir es bei Teams und Channels gemacht haben.
Nehmen wir zunächst die grundlegende Konfiguration zum Anrufen von Gast-Accounts in Angriff:
$CurrentMonth = Get-Date -Format "MM.yyyy"
$GuestCallingCfg = (Get-CsTeamsGuestCallingConfiguration).AllowPrivateCalling
$FileHeader = "Date,AllowPrivateCalling" |
Out-File 'GuestCallingConfiguration.csv'
$Output = "$CurrentMonth,$GuestCallingCfg" |
Out-File 'GuestCallingConfiguration.csv' -append
Hier gibt es nur einen wichtigen Wert. Wir können überprüfen, ob sich dieser Wert im Laufe der Zeit geändert hat und können das dann monatlich, vierteljährlich oder so wiederholen:
$CurrentMonth = Get-Date -Format "MM.yyyy"
$GuestCallingCfg = (Get-CsTeamsGuestCallingConfiguration).AllowPrivateCalling
$FileHeader = "Date,AllowPrivateCalling" |
Out-File 'GuestCallingConfiguration.csv'
$Output = "$CurrentMonth,$GuestCallingCfg" |
Out-File 'GuestCallingConfiguration-current.csv' -append
Dann können wir die beiden Ausgabedateien wie folgt vergleichen:
$Historical = Import-Csv GuestCallingConfiguration.csv
$Current = Import-Csv GuestCallingConfiguration-current.csv
$Historical.AllowPrivateCalling -eq $Current.AllowPrivateCalling
Bei einer Änderung würde das Ergebnis folgendermaßen aussehen:
Als Nächstes haben wir die Konfiguration für Gastbesprechungen, die einige weitere Einstellungen enthält, die wir verwalten müssen. Zuerst müssen wir eine Baseline erstellen oder feststellen, was wir heute konfiguriert haben:
Erster Lauf:
# Discover current configuration (aktuelle Konfiguration ermitteln)
$GuestMeeting = Get-CsTeamsGuestMeetingConfiguration |
Select AllowIPVideo,ScreenSharingMode,AllowMeetNow,LiveCaptionsEnabledType,AllowTranscription
# Create a Hash table output to be exported (Erstelle eine Hash-Tabelle, die exportiert werden soll)
$Hashtable = New-Object System.Collections.Hashtable
$Hashtable['AllowIPVideo'] = $GuestMeeting.AllowIPVideo
$Hashtable['ScreenSharingMode'] = $GuestMeeting.ScreenSharingMode
$Hashtable['AllowMeetNow'] = $GuestMeeting.AllowMeetNow
$Hashtable['LiveCaptionsEnabledType'] = $GuestMeeting.LiveCaptionsEnabledType
$Hashtable['AllowTranscription'] = $GuestMeeting.AllowTranscription
# Export $Hashtable variable to a CSV for comparison (Exportiere die Variable $Hashtable in eine CSV-Datei zum Vergleich)
$HashTable.GetEnumerator() |
Select-Object -Property Key,Value |
Export-Csv -NoTypeInformation -Path GuestMeeting.csv
Dann können wir im Laufe der Zeit weitere Durchläufe [monatlich, vierteljährlich, jährlich] machen, die den gleichen Code wie oben verwenden, aber die Ausgabedatei in "GuestMeeting-Current.csv" ändern:
$HashTable.GetEnumerator() |
Select-Object -Property Key,Value |
Export-Csv -NoTypeInformation -Path GuestMeeting-Current.csv
Vergleiche die beiden Konfigurationen:
# Compare the original and current CSV files (Vergleiche die ursprüngliche mit der aktuellen CSV-Datei)
$CSV1 = Get-Content .\GuestMeeting.csv
$CSV2 = Get-Content .\GuestMeeting-Current.csv
Compare-Object $CSV1 $CSV2
Wenn ein Unterschied festgestellt wird, sollten wir etwas Ähnliches wie das hier sehen:
Derselbe Prozess kann auch mit der Guest Messaging Configuration durchgeführt werden. Für unseren ersten Durchlauf können wir diesen Code verwenden:
# Discover current configuration (Aktuelle Konfiguration ermitteln)
$GuestMessaging = Get-CsTeamsGuestMessagingConfiguration |
Select AllowUserEditMessage,AllowUserDeleteMessage,AllowUserDeleteChat,AllowUserChat,AllowGiphy,GiphyRatingType,AllowMemes,AllowImmersiveReader,AllowStickers
# Create a Hash table output to be exported (Erstelle eine Hash-Tabelle, die exportiert werden soll)
$Hashtable = New-Object System.Collections.Hashtable
$Hashtable['AllowUserEditMessage'] = $GuestMessaging.AllowUserEditMessage
$Hashtable['AllowUserDeleteMessage'] = $GuestMessaging.AllowUserDeleteMessage
$Hashtable['AllowUserDeleteChat'] = $GuestMessaging.AllowUserDeleteChat
$Hashtable['AllowUserChat'] = $GuestMessaging.AllowUserChat
$Hashtable['AllowGiphy'] = $GuestMessaging.AllowGiphy
$Hashtable['GiphyRatingType'] = $GuestMessaging.GiphyRatingType
$Hashtable['AllowMemes'] = $GuestMessaging.AllowMemes
$Hashtable['AllowImmersiveReader'] = $GuestMessaging.AllowImmersiveReader
$Hashtable['AllowStickers'] = $GuestMessaging.AllowStickers
# Export $Hashtable variable to a CSV for comparison (Exportiere die Variable $Hashtable in eine CSV-Datei zum Vergleich)
$HashTable.GetEnumerator() |
Select-Object -Property Key,Value |
Export-Csv -NoTypeInformation -Path GuestMessaging.csv
Nachfolgende Durchläufe: [Monatlich, Vierteljährlich, Jährlich]
Verwende den gleichen Code wie oben, aber ändere die Ausgabedatei in 'GuestMessaging-Current.csv':
$HashTable.GetEnumerator() |
Select-Object -Property Key,Value |
Export-Csv -NoTypeInformation -Path GuestMessaging-Current.csv
Vergleich:
# Compare the original and current CSV files (Vergleiche die ursprüngliche und die aktuelle CSV-Datei)
$CSV1 = Get-Content .\GuestMessaging.csv
$CSV2 = Get-Content .\GuestMessaging-Current.csv
Compare-Object $CSV1 $CSV2
Wenn ein Unterschied festgestellt wird, sollten wir etwas wie das hier sehen:
Beachte, dass sich in dem obigen Vergleich zwei Werte geändert haben: AllowMemes und AllowStickers, und durch die Indikatoren (==>) ist die neue Konfiguration jetzt für beide Einstellungen 'True', während in der ursprünglichen Konfiguration (<==) beide auf 'False' gesetzt waren.
Bei jedem Audit-Prozess müssen Organisationen entscheiden, was sie im Auge behalten wollen, und das gilt auch für Teams-Konfigurationen. Die erforderlichen Tools hast du jetzt kennengelernt und kannst dir analog dazu deinen eigenen Audit-Prozess aufbauen. Jedes Unternehmen ist anders, und eine vollständige Abdeckung aller Einstellungen würde diesen Artikel zu lang machen – und die Wiederholung ist unnötig.
Wenn es nötig ist, die Konfiguration über einen längeren Zeitraum zu verfolgen, können wir auch historische Diagramme zur Überprüfung erstellen. Dazu exportieren wir die aktuellen Einstellungen und notieren ein Datum/Zeitstempel zu diesem Datensatz. Eine Beispieldatei, wann der jeweilige Datensatz wahr (true) war, könnte etwa so aussehen:
Month,AllowIPVideo,ScreenSharingMode,AllowMeetNow,LiveCaptionsEnabledType,AllowTranscription
07.2023,True,SingleApplication,True,DisabledUserOverride,False
08.2023,True,SingleApplication,False,DisabledUserOverride,False
09.2023,True,SingleApplication,False,DisabledUserOverride,False
10.2023,True,SingleApplication,True,DisabledUserOverride,False
11.2023,True,SingleApplication,True,DisabledUserOverride,False
12.2023,True,SingleApplication,False,DisabledUserOverride,False
01.2024,True,SingleApplication,True,DisabledUserOverride,False
Je nach den internen Abläufen in einer Organisation kann dies auf einer zentralen IT-Freigabe, in SharePoint oder per E-Mail an einen Verteiler geschickt werden, um die Aufmerksamkeit zu erhöhen.
Eine häufige Aufgabe von Administratoren ist das Auditing von Aktivitäten oder Aktionen. Dabei werden Protokolle und andere Daten untersucht, um die Ursache für ein Problem zu ermitteln und das Problem zu beheben. Außerdem kann das Auditing auch dazu verwendet werden, eine Aktivität von Microsoft Teams abzufragen. Dies kann dabei helfen, das allgemeine Aktivitätsniveau zu ermitteln oder festzustellen, wann ein bestimmter Dienst genutzt wurde. Im Hintergrund verwendet Microsoft ein Unified Log, das Informationen über die auf der Teams-Plattform durchgeführten Aktionen speichert: PowerShell und die Microsoft Defender Schnittstelle (Link zum PowerShell & Microsoft Defender interface).
Warum in der PowerShell? PowerShell bietet eine Flexibilität, die du in der grafischen Benutzeroberfläche vielleicht nicht findest. Wir können dies entweder in einer Jumpbox planen, die PowerShell-Skripte vor Ort ausführt, oder wir können dies in einem Azure Runbook tun, um die Ressourcen vor Ort zu minimieren. Oder wir können dies innerhalb von ScriptRunner als Teil einer Reihe von Administrationsaufgaben tun.
# First, connect to Exchange Online PowerShell (v3) (Verbinde dich zunächst mit der Exchange Online PowerShell (v3))
Connect-ExchangeOnline
# Retrieve Teams events - stored in the Unified Audit Log (Abrufen von Teams-Events - gespeichert im Unified Audit Log)
# Timeframe: Past 48 hours (Zeitrahmen: Letzte 48 Stunden)
$EndDate = Get-Date
$StartDate = $EndDate.AddDays(-2)
# All Teams events (Alle Teams-Ereignisse)
Search-UnifiedAuditLog -StartDate $StartDate -EndDate $EndDate -RecordType MicrosoftTeams
# Teams channels added (Hinzugefügte Teams-Kanäle)
Search-UnifiedAuditLog -StartDate $StartDate -EndDate $EndDate -RecordType MicrosoftTeams -Operations ChannelAdded
# Sensitivity Label changes (Änderungen an Sensitivity-Labeln)
Search-UnifiedAuditLog -StartDate $StartDate -EndDate $EndDate -RecordType MicrosoftTeams -Operations SensitivityLabelChanged
# Teams are deleted (gelöschte Teams)
Search-UnifiedAuditLog -StartDate $StartDate -EndDate $EndDate -RecordType MicrosoftTeams -Operations TeamDeleted
Als Verweis (Microsoft Learn Seiten): Teams activities
Wenn wir diese Cmdlets ausführen, sollten wir die folgende Ausgabe sehen:
Beachte, dass dies nur einer von vielen Einträgen ist und zufällig der protokollierte Beginn einer Teams-Sitzung ist.
Neben diesen Vorgängen gibt es noch weitere Teams-Vorgänge, für die wir Daten abrufen können:
TeamsSessionStarted
MeetingParticipantDetail
MessageReadReceiptReceived
ReactedToMessage
MeetingDetail
PowerShell bietet Administratoren die Möglichkeit, ihre eigenen Umgebungen zu überwachen, wenn andere Tools nicht vorhanden sind. In diesem Fall konnten wir die PowerShell nutzen, um die Einstellungen im Laufe der Zeit auf Änderungen zu überprüfen und sicherzustellen, dass es keine Konfigurationsabweichungen gibt. Falls doch, können wir mit einem groben Datumsstempel feststellen, wann die Änderung vorgenommen wurde. Mit der richtigen Kodierung können alle Konfigurationsaspekte von Microsoft Teams mit der PowerShell im Laufe der Zeit überwacht werden, sodass sich die Administratoren auf andere Aufgaben konzentrieren können.
Vereinfache und automatisiere deine Microsoft Teams-Verwaltung mit unserem 8-seitigen PowerShell Cheat Sheet für Microsoft Teams. Dieser praktische Leitfaden bietet dir Quick-Reference-Cmdlets und Codeschnipsel zur einfachen Verwaltung von Benutzern, Kanälen, Richtlinien und mehr. Ideal sowohl für Anfänger als auch für erfahrene Administratoren.
Hole dir auch das andere CheatSheet und entfalte das volle Potential von PowerShell mit unserem praktischen Poster. Egal ob Anfänger oder erfahrener Profi, dieses Cheat Sheet ist darauf ausgelegt, dein Anlaufpunkt für die wichtigsten und am häufigsten verwendeten Cmdlets zu sein.
Das Poster gibt es zum Download und in Papierform.
Kennst du schon unsere Webinare? Zum Beispiel das hier:
Die Verwaltung von Teams kann sehr zeitaufwendig sein. Hast du dich schon einmal gefragt, wie du die entstehende Arbeitslast optimieren und reduzieren kannst?
Das PowerShell-Modul für Microsoft Teams ist dein Schlüssel dazu: Es ermöglicht dir, viele sich wiederholende Aufgaben zu standardisieren und zu automatisieren.
Zum Beispiel:
Dieses Webinar richtet sich an Administratoren, IT- und DevOps-Professionals, PowerShell-Entwickler und IT-Leiter.
Wir freuen uns darauf, dich als Webinar-Teilnehmer begrüßen zu dürfen!
Klicke hier für das Teams Webinar
Okt 30, 2024 by Damian Scoles
MVP Damien Scoles berichtet über seine Erfahrungen mit Microsoft Graph. In seinem dritten Artikel geht er näher auf...
Mai 22, 2024 by Damian Scoles
Möchtest du mehr über die Überwachung von Microsoft Teams mit PowerShell erfahren? Lies, wie du die Einstellungen im...
Dez 22, 2023 by Damian Scoles
Du administrierst Microsoft Teams? Dann kommen hier einige sehr hilfreiche Cmdlets und entsprechende Erklärungen. Wie...
Damian Scoles ist ein zehnfacher Microsoft MVP mit Spezialisierung auf Exchange, Office 365 und PowerShell, der über 25 Jahre Erfahrung in der IT-Branche mitbringt. Er ist im Großraum Chicago ansässig und begann mit der Verwaltung von Exchange 5.5 und Windows NT. Im Laufe der Jahre hat er mit Office 365 seit BPOS gearbeitet und darüber hinaus Erfahrung mit Azure AD, Security and Compliance Admin Centers und Exchange Online. Zu seinem Engagement in der Community gehören Beiträge in TechNet-Foren, die Erstellung von PowerShell-Skripten, die in seinen Blogs zu finden sind, das Schreiben von ausführlichen PowerShell/Office365/Exchange-Blogartikeln, Tweets und die Erstellung von PowerShell-Videos auf YouTube. Er hat fünf PowerShell-Bücher geschrieben und arbeitet außerdem aktiv an dem Buch "Microsoft 365 Security for IT Pros".