Simplify user tasks like bulk creation, updates, password resets, deletions, license checks & more — all from one place.
🚀 Launch ToolkitA short description on a Team can save hours of confusion later—especially in large tenants where names like “Project Phoenix” or “Ops” don’t tell the full story. But descriptions are easy to skip during creation, and over time you end up with a lot of mystery Teams. This script gives admins quick visibility by listing all Teams missing a description, exporting the details to CSV, and emailing the report to the administrator.
# ===== Teams Without Description -> CSV -> Email to Admin =====
# Requires: Microsoft.Graph module
# Scopes: Group.Read.All, Mail.Send
# --- Email variables ---
$FromUser = "admin@contoso.com" # Sender (must have mailbox)
$To = "it-ops@contoso.com" # Recipient
$Subject = "Teams Without Description report"
$CsvOutDir = "$env:TEMP"
# --- Connect to Microsoft Graph ---
Import-Module Microsoft.Graph -ErrorAction Stop
Connect-MgGraph -Scopes "Group.Read.All","Mail.Send"
# --- Get all Teams-backed groups (M365 groups where resourceProvisioningOptions includes 'Team') ---
$allTeams = Get-MgGroup -All -Filter "resourceProvisioningOptions/Any(x:x eq 'Team')" `
-Property "id,displayName,description,visibility,createdDateTime,mailNickname"
# --- Filter Teams with missing/blank description ---
$teamsNoDesc = $allTeams | Where-Object { [string]::IsNullOrWhiteSpace($_.Description) }
# --- Shape rows for CSV ---
$rows = $teamsNoDesc | ForEach-Object {
[PSCustomObject]@{
TeamId = $_.Id
TeamName = $_.DisplayName
Visibility = $_.Visibility
CreatedDate = $_.CreatedDateTime
MailNickname = $_.MailNickname
Description = "" # explicitly blank
}
}
# --- Export to CSV ---
if (-not (Test-Path -Path $CsvOutDir)) { New-Item -ItemType Directory -Path $CsvOutDir | Out-Null }
$ts = Get-Date -Format "yyyyMMdd_HHmmss"
$csvPath = Join-Path $CsvOutDir ("Teams_Without_Description_{0}.csv" -f $ts)
$rows | Sort-Object TeamName | Export-Csv -Path $csvPath -NoTypeInformation -Encoding UTF8
# --- Prepare HTML Body ---
$totalTeams = $allTeams.Count
$totalNoDesc = $rows.Count
$summaryHtml = @"
<html>
<body style='font-family:Segoe UI,Arial,sans-serif'>
<h3>Teams Without Description Report</h3>
<p>Total Teams scanned <b>$totalTeams</b></p>
<p>Teams missing description: <b>$totalNoDesc</b></p>
<p>The full list (TeamId, Name, Visibility, CreatedDate, MailNickname) is attached as a CSV.</p>
</body>
</html>
"@
# --- Prepare Attachment ---
$fileBytes = [System.IO.File]::ReadAllBytes($csvPath)
$base64Content = [System.Convert]::ToBase64String($fileBytes)
$csvFileName = [System.IO.Path]::GetFileName($csvPath)
$attachment = @{
"@odata.type" = "#microsoft.graph.fileAttachment"
name = $csvFileName
contentBytes = $base64Content
contentType = "text/csv"
}
# --- Prepare and Send Email ---
$mail = @{
message = @{
subject = "$Subject"
body = @{
contentType = "HTML"
content = $summaryHtml
}
toRecipients = @(@{ emailAddress = @{ address = $To } })
attachments = @($attachment)
}
saveToSentItems = $true
}
Send-MgUserMail -UserId $FromUser -BodyParameter $mail
Write-Host "Done. CSV saved at: $csvPath" -ForegroundColor Green
Signs in with Group.Read.All (read Teams-backed groups) and Mail.Send (send the report).
Uses the filter resourceProvisioningOptions/Any(x:x eq 'Team') so we only process Microsoft 365 groups that back Teams.
Filters client-side for Teams where Description is null/empty/whitespace.
Outputs TeamId, TeamName, Visibility, CreatedDate, MailNickname, Description (blank) for easy remediation.
Exports a timestamped CSV, attaches it to an HTML summary, and sends it to the administrator.
Error | Cause | Solution |
---|---|---|
Authorization_RequestDenied | Missing scopes or consent | Reconnect with Group.Read.All and Mail.Send; ensure admin consent. |
Get-MgGroup not recognized | Microsoft Graph module not installed | Install-Module Microsoft.Graph -Scope CurrentUser then Import-Module. |
CSV empty | No Teams without descriptions | Validate base Teams with Get-MgGroup and confirm descriptions exist. |
Email not sent | $FromUser lacks mailbox | Use a licensed mailbox-enabled sender. |
Large tenants run slow | Many Teams retrieved | Acceptable tradeoff; consider paging or scoping by created date if needed. |
Short, clear descriptions make Teams discoverable and manageable. This script gives you a fast, repeatable way to find Teams missing descriptions and ship a CSV to your inbox for action. Schedule it, add owners, and trigger reminders—you’ll lift collaboration quality and reduce confusion across your Microsoft 365 tenant.
© m365corner.com. All Rights Reserved. Design by HTML Codex