Key Points
- Build a complete Teams and channel inventory using native PowerShell cmdlets for accurate, real-time visibility.
- Extract channel creation and modification history from Microsoft Purview audit logs for compliance evidence.
- Analyze storage usage through the Graph API to identify data hotspots and growth patterns.
- Correlate inventory, audit, and storage data to flag high-risk issues like inactive large channels.
- Maintain automated scheduling and evidence retention to demonstrate continuous compliance monitoring.
- Operationalize findings by routing issues to remediation workflows and generating governance reports.
Uncontrolled Microsoft Teams growth can lead to security gaps and compliance issues when channels multiply without proper oversight. A systematic Teams audit using native PowerShell tools reveals these hidden risks while aligning your collaboration environment with retention policies.
This guide will walk you through building a repeatable audit process that combines channel inventory, activity logs, and storage analysis for ongoing governance.
Steps for using PowerShell to audit Microsoft Teams
Regular PowerShell audits provide essential visibility into your Teams environment for security and management.
📌Use case: Conduct audits during compliance reviews, after security incidents, before migrations, or when addressing channel sprawl. This is particularly valuable for MSPs managing multiple client tenants.
📌Prerequisites: Before proceeding, ensure you have the following requirements:
- Microsoft Teams PowerShell module with admin permissions
- Access to Microsoft Purview audit logs
- PowerShell 7 on Windows 11 and secure storage for exports
- Optional: Graph permissions for storage reporting
Once you have these ready, follow the steps below.
Step 1: Enumerate teams and channels
Start your Microsoft Teams audit by building a complete inventory of all teams and channels.
- Connect to Teams PowerShell and export all teams:
Connect-MicrosoftTeamsGet-Team | Select-Object DisplayName, GroupId, Visibility | Export-CSV "C:\TeamsAudit\AllTeams.csv" -NoTypeInformation
- This command connects to the Teams environment, retrieving all essential details, like team name, unique ID, and privacy settings, into a CSV file. Remember to replace the sample file path, C:\TeamsAudit\AllTeams.csv, with your own
- List all channels and classify types (e.g., standard, private, shared):
$AllTeams = Get-Teamforeach ($Team in $AllTeams) {Get-TeamChannel -GroupId $Team.GroupId | Select-Object TeamName, DisplayName, MembershipType, Description | Export-CSV "C:\TeamsAudit\AllChannels.csv" -Append -NoTypeInformation}
- For private channels, capture owners to identify orphaned spared using Get-TeamChannelUser.
This method uses native PowerShell cmdlets for accurate, real-time data on your Teams environment. Once complete, you’ll have a foundation for storage analysis and activity tracking.
Step 2: Pull channel activities from Microsoft Purview audit logs
Audit logs provide crucial evidence of who created, modified, or deleted Teams channels and when.
- Connect to Exchange Online and search Teams channel activities:
- Install module if not already installed:
Install-Module ExchangeOnlineManagement -Scope CurrentUser -Force
- Connect to Microsoft Purview (Compliance) PowerShell):
Connect -IPPSSession
- Pull Teams channel audit events from the past 30 days:
$AuditResults = Search-UnifiedAuditLog '-StartDate (Get-Date).AddDays (-30) '-EndDate (Get-Date) '-RecordType MicrosoftTeams '-Operations "ChannelCreated","ChannelUpdated","ChannelDeleted" '-ResultSize 5000
- Export results for the analysis:
$AuditResults |Select-Object CreationDate, UserIds, Operations, AuditData |Export-Csv "C:\TeamsAudit\ChannelActivities.csv" -NoTypeInformation
Write-Host "Audit export complete. File saved to "C:\TeamsAudit\ChannelActivities.csv"
- Export relevant audit data for analysis:
$AuditResults | Select-Object CreationDate, UserIds, Operations, AuditData | Export-CSV "C:\TeamsAudit\ChannelActivities.csv" -NoTypeInformation
- Document your search parameters, time range, and result counts for compliance evidence.
This method works by querying Microsoft’s unified audit log, which automatically records all channel lifecycle events across your tenant. Use this approach when investigating specific incidents or proving compliance with data governance policies.
After extraction, you’ll have a timestamped record of all channel changes, ready to correlate with your team inventory for complete audit trail documentation.
Step 3: Add storage context with Graph API
Understanding storage usage completes your Teams audit by revealing data hotspots and growth patterns.
- Create an Azure App Registration with Sites.Read.All application permissions.
- Connect to Microsoft Graph and retrieve storage metrics:
- Install Microsoft Graph module if not present:
if (-not (Get-Module -ListAvailable -Name Microsoft.Graph)) {Install-Module Microsoft.Graph -Scope CurrentUser -Force}
- Connect to Microsoft Graph (app-only, certificate):
Connect-MgGraph -ClientId "your-client-id" -TenantId "your-tenant-id" -CertificateThumbprint "your-cert-thumbprint" | Out-Null
- Get all Team-enabled Microsoft 365 groups:
$teams = Get-MgGroup -All | Where-Object { $_.ResourceProvisioningOptions -contains "Team" }$results = New-Object System.Collections.Generic.List[object]foreach ($team in $teams) {try {$drive = Get-MgGroupDrive -GroupId $team.Id$site = Get-MgGroupSite -GroupId $team.Id | Select-Object -First 1$usedPercent = if ($drive?.Quota?.Total) { [math]::Round(($drive.Quota.Used / $drive.Quota.Total) * 100, 2) } else { $null }$results.Add([PSCustomObject]@{TeamName = $team.DisplayNameSiteUrl = $site?.WebUrlTotalBytes = $drive?.Quota?.TotalUsedBytes = $drive?.Quota?.UsedUsedPercent = $usedPercentState = $drive?.Quota?.State})}catch {$results.Add([PSCustomObject]@{TeamName = $team.DisplayNameSiteUrl = $nullTotalBytes = $nullUsedBytes = $nullUsedPercent = $nullState = "error: $($_.Exception.Message)"})}}$exportFolder = "C:\TeamsAudit"if (-not (Test-Path $exportFolder)) { New-Item -Path $exportFolder -ItemType Directory | Out-Null }$csvPath = Join-Path $exportFolder "TeamStorage.csv"$results | Export-Csv -Path $csvPath -NoTypeInformation -Encoding UTF8Write-Host "Storage metrics export complete: $csvPath"
- Export channel storage data, including SharePoint URLs and usage metrics, to identify rapid growth or retention conflicts.
This method works by querying the underlying SharePoint storage that powers each Teams channel, providing accurate size data regardless of channel renaming. Use this approach when investigating storage costs, planning migrations, or identifying archives.
Combining storage metrics with your audit events creates a powerful prioritization system for review candidates, completing your comprehensive Teams channel reporting workflow.
Step 4: Correlate data and flag issues
Correlating your audit findings transforms raw data into actionable insights for Teams channel management.
- Combine your inventory, audit events, and storage data using Team ID and Channel Names as primary keys.
- Flag high-risk conditions using PowerShell filters:
- Find inactive channels with large storage:
$InactiveLargeChannels = $ChannelData | Where-Object {$_.LastActivity -lt (Get-Date).AddDays(-90) -and $_.StorageUsed -gt 1GB}
- This script identifies the channels that have been inactive over the last 90 days while still consuming more than 1GB of storage.
- Identify channels with frequent creation/deletion activity:
$VolatileChannels = $AuditResults | Group-Object ChannelId | Where-Object Count -gt 10
- This code groups audit events by channel and flags channels with more than 10 recorded events, highlighting channels with unusually frequent changes.
- Assign remediation owners and due dates for each flagged issue.
This correlation works by cross-referencing multiple data sources to reveal patterns that single-dimensional analysis would miss. Use this approach when preparing for compliance audits or implementing proactive governance.
After correlation, you’ll have a prioritized list of channel issues with clear ownership, enabling systematic remediation and ongoing Microsoft Teams audit compliance.
Step 5: Export, schedule, and retain evidence
Proper documentation transforms your audit from a one-time check into an ongoing compliance strategy.
- Export standardized reports containing tenant context, audit date, and findings:
$ExportData = [PSCustomObject]@{Tenant = "Contoso"AuditDate = Get-Date -Format "yyyy-MM-dd"TeamsCount = $AllTeams.CountChannelsCount = $AllChannels.CountIssuesFlagged = $FlaggedIssues.Count}$ExportData | Export-CSV "C:\TeamsAudit\AuditSummary_$(Get-Date -Format 'yyyyMMdd').csv" -NoTypeInformation
- This code creates a one-row audit summary (tenant name, audit date, number of teams, number of channels, and number of flagged issues) and stores it in the file C:\TeamsAudit\AuditSummary_YYYYMMDD.csv.
- Maintain execution logs tracking runtime, record counts, and errors.
- Schedule automated runs via Windows Task Scheduler or your RMM tool:
- Weekly inventory scans
- Monthly comprehensive audit pulls
- 12-month minimum retention for all artifacts
This systematic approach creates timestamped, versioned evidence that demonstrates continuous compliance monitoring. Use this method when preparing for regulatory audits or implementing long-term governance.
After implementation, you’ll have a verifiable audit trail that meets compliance requirements while providing historical data for trend analysis and capacity planning.
Step 6: Operate on audit outcomes
Transforming audit findings into actionable workflows ensures your Microsoft Teams channel management delivers real business value.
- Route flagged items to appropriate teams:
- Channel sprawl > Cleanup workflow
- Retention gaps > Policy review team
- Inactive large channels > Archival process
- Build a ticket creation process for ownerless channels, identifying critical issues.
- Document resolutions and exceptions in monthly governance reports for leadership review.
This operational phase integrates audit findings with existing IT workflows, ensuring issues are properly assigned and tracked rather than simply identified. Use this approach when establishing ongoing governance or demonstrating compliance to stakeholders.
After implementation, you’ll close the audit loop with documented resolutions, transforming raw data into measurable improvements in your Teams environment management.
Operationalize with NinjaOne for automated MS Teams audits
NinjaOne transforms your PowerShell audit workflow into an automated, enterprise-ready solution.
- Deploy and schedule audit scripts through NinjaOne’s Automation Library.
- Store secure credentials using NinjaOne’s credential management for service account access.
- Configure automated ticket triggers for:
- Ownerless channels requiring assignment
- Large inactive channels need to be archived
- Frequent configuration changes suggest instability
This integration works by leveraging NinjaOne’s ability to send scripts to endpoints and secure credential storage to eliminate manual intervention while maintaining audit trail integrity. Use this approach when scaling Teams management across multiple clients or requiring executive-level reporting.
Achieving continuous compliance with Microsoft Teams audit automation
A comprehensive Teams audit combines channel inventory, Purview activity logs, and storage analytics to transform chaotic sprawl into managed collaboration.
By automating this process with PowerShell and scheduling regular runs, you maintain continuous visibility that proactively addresses security risks and compliance requirements.
This disciplined approach ensures your Teams environment remains optimized for both productivity and governance long-term.
Related topics:
