Entra / Microsoft 365 · Teams
Report teams chat info
Report Teams chat threads for the user signed into an interactive Microsoft Graph PowerShell session.
Connect & set up
Run these once per session. All scopes are read-only unless the script makes changes.
Connect-MgGraph -Scopes Chat.ReadWrite, Chat.ManageDeletion.All -NoWelcome# Find the object identifier for the signed-in user
Run it
The main script. Copy it, or download the .ps1 and run it from your console.
Connect-MgGraph -Scopes Chat.ReadWrite, Chat.ManageDeletion.All -NoWelcome# Find the object identifier for the signed-in user$Account = (Get-MgContext).Account$UserId = (Get-MgUser -UserId $Account).Id# Get chats for the userWrite-Host ("Fetching chat threads for user {0}" -f $Account)[array]$Chats = Get-MgUserChat -Userid $UserId -All -Filter "chattype eq 'group' or chattype eq 'oneonone' or chattype eq 'Meeting'" | Sort-Object LastUpdatedDateTime -Descending# Extract the identifiers for the tenants that chat threads belong to so that we can resolve them to a tenant nameWrite-Host "Finding tenant information for chats..."$TenantList = [System.Collections.Generic.List[Object]]::new()ForEach ($Chat in $Chats) {$TenantList.Add($Chat.TenantId)}$TenantsCount = @{}$TenantList = $TenantList | Sort-Object$TenantList | ForEach-Object {$TenantsCount[$_]++}$TenantsCount = $TenantsCount.GetEnumerator() | Sort-Object -Property Value -Descending$TenantsCount# Now build a hash table of tenant identifiers and names that we can use to look up tenantsWrite-Host "Resolving tenant identifiers..."$TenantsHash = @{}ForEach ($Tenant in $TenantsCount) {$Uri = ("https://graph.microsoft.com/V1.0/tenantRelationships/findTenantInformationByTenantId(tenantId='{0}')" -f $Tenant.Name.ToString())$ExternalTenantData = Invoke-MgGraphRequest -Uri $Uri -Method Get$TenantsHash.Add([string]$Tenant.Name.toString(), [string]$ExternalTenantData.displayName)}# Create output report$ChatReport = [System.Collections.Generic.List[Object]]::new()# Extract information for each chat thread and write it out to the report fileWrite-Host "Analyzing chat threads..."ForEach($Chat in $Chats) {# Get members of the chat threadTry {[array]$Members = Get-MgUserChatMember -UserId $UserId -ChatId $Chat.Id -ErrorAction Stop# Extract the member display names and remove any blanks (accounts that no longer exist)[array]$MemberNames = $Members.displayName | Sort-Object -Unique$NumberOfParticipants = $MemberNames.CountIf ($MemberNames.Count -gt 0) {$MemberNamesOutput = $MemberNames -Join ", "}} Catch {Write-Host ("Error getting members for chat {0}: {1}" -f $Chat.Id, $_.Exception.Message) -ForegroundColor Red$MemberNamesOutput = "Error retrieving members"$NumberOfParticipants = 0Continue}# Get tenant display name$TenantDisplayName = "Unknown"$TenantDisplayName = $TenantsHash[$Chat.TenantId]$ChatReportLine = [PSCustomObject][Ordered]@{ChatType = $Chat.ChatTypeTopic = $Chat.TopicCreated = Get-Date $Chat.CreatedDateTime -format 'dd-MMM-yyyy HH:mm:ss'LastUpdated = Get-Date $Chat.LastUpdatedDateTime -format 'dd-MMM-yyyy HH:mm:ss'NumberOfParticipants = $NumberOfParticipantsParticipants = $MemberNamesOutputTenantId = $Chat.TenantIdTenant = $TenantDisplayNameId = $Chat.IdWebUrl = $Chat.WebUrl}$ChatReport.Add($ChatReportLine)} # End ForEach chats# Tenant analysisWrite-Host ""Write-Host "Analysis of chat threads by tenant"Write-Host "----------------------------------"$ChatReport | Group-Object Tenant -NoElement | Sort-Object Count -Descending | Format-Table @{expression={$_.Name}; label = "Host Tenant"}, CountWrite-Host ""Write-Host "Analysis of chat threads by type"Write-Host "--------------------------------"$ChatReport | Group-Object ChatType -NoElement | Sort-Object Count -Descending | Format-Table @{expression={$_.Name}; label = "Host Tenant"}, CountWrite-Host ""# And here's what we found sorted by the last updated date$ChatReport | Select-Object ChatType, Tenant, Topic, Created, LastUpdated, NumberOfParticipants, Participants | Sort-Object LastUpdated -Descending | Out-GridView# Generate reportsIf (Get-Module ImportExcel -ListAvailable) {$ExcelGenerated = $True$ExcelTitle = ("Teams Chats for {0}" -f $Account)Import-Module ImportExcel -ErrorAction SilentlyContinue$OutputXLSXFile = ((New-Object -ComObject Shell.Application).Namespace('shell:Downloads').Self.Path) + "\TeamsChatListing.xlsx"If (Test-Path $OutputXLSXFile) {Remove-Item $OutputXLSXFile -ErrorAction SilentlyContinue}$ChatReport | Export-Excel -Path $OutputXLSXFile -WorksheetName "Teams Chats" -Title $ExcelTitle -TitleBold -TableName "TeamsChat"} Else {$OutputCSVFile = ((New-Object -ComObject Shell.Application).Namespace('shell:Downloads').Self.Path) + "\TeamsChatListing.csv"$ChatReport | Export-Csv -Path $OutputCSVFile -NoTypeInformation -Encoding Utf8}If ($ExcelGenerated) {Write-Host ("An Excel worksheet containing the report data is available in {0}" -f $OutputXLSXFile)} Else {Write-Host ("A CSV file containing the report data is available in {0}" -f $OutputCSVFile)}
Attribution
Author
Office365itpros