Entra / Microsoft 365 · Teams
Audit Teams meeting records
Shows how to find and interpret audit records captured for Teams meetings using advanced auditing.
Connect & set up
Run these once per session. All scopes are read-only unless the script makes changes.
Connect-MgGraph -NoWelcome -Scopes User.Read.All
Run it
The main script. Copy it, or download the .ps1 and run it from your console.
param([int] $LookbackDays = 90,[string] $StartDate = (Get-Date).AddDays(-$LookbackDays); $EndDate = (Get-Date).AddDays(1) # Set your own date span here!,[string] $EndDate = (Get-Date))$ModulesLoaded = Get-Module | Select-Object -ExpandProperty NameIf (!($ModulesLoaded -match "ExchangeOnlineManagement")) {Write-Host "Please connect to the Exchange Online Management module and then restart the script"; break}Connect-MgGraph -NoWelcome -Scopes User.Read.All# Start and end date for the audit scan. By default, we look for 90 days, but you can choose any value you like up to 365 (if you have Office 365 E5)$OutputCSVFile = "C:\temp\AuditEventsTeamsMeetings.csv"# Find the audit recordsWrite-Host "Looking for Teams meeting audit records..."[array]$Records = Search-UnifiedAuditLog -Operations MeetingDetail, MeetingParticipantDetail -StartDate $StartDate -EndDate $EndDate -Formatted `-ResultSize 5000 -SessionCommand ReturnLargeSetIf (!($Records)) {Write-Host "No audit records found - exiting!"; break} Else {$Records = $Records | Sort-Object Identity -Unique | Sort-Object { $_.CreationDate -as [datetime]} -Descending}Write-Host "Processing" $Records.Count "Teams meeting audit records..."# Process the records$MeetingRecords = [System.Collections.Generic.List[Object]]::new()ForEach ($Rec in $Records) {$AuditData = $Rec.AuditData | ConvertFrom-Json$User = $Null; $Organizer = $NullSwitch ($Rec.Operations) {"MeetingDetail" { # A meeting record[datetime]$StartTime = Get-Date($AuditData.StartTime)[datetime]$EndTime = Get-Date($AuditData.EndTime)$TimeSpent = $EndTime - $StartTime$MeetingDuration = ("{0:hh\:mm\:ss}" -f $TimeSpent)$Organizer = (Get-MgUser -UserId $AuditData.Organizer.UserObjectId).DisplayName$DataLine = [PSCustomObject] @{'Audit timestamp' = Get-Date($Rec.CreationDate).ToLocalTime()User = $Rec.UserIdsMeetingId = $AuditData.IdStart = Get-Date($AuditData.StartTime).ToLocalTime()End = Get-Date($AuditData.EndTime).ToLocalTime()'Meeting duration' = $MeetingDuration.ToString()Organizer = $OrganizerModalities = $AuditData.Modalities'Meeting type' = $AuditData.CommunicationSubTypeType = "Meeting"MeetingURL = $AuditData.MeetingURLOperation = $Rec.Operations}}"MeetingParticipantDetail" { # A meeting participant record# Resolve user name from the object identifier logged for participant[datetime]$StartTime = Get-Date($AuditData.JoinTime)[datetime]$EndTime = Get-Date($AuditData.LeaveTime)$TimeSpent = $EndTime - $StartTime$MeetingDuration = ("{0:hh\:mm\:ss}" -f $TimeSpent)If ($AuditData.Attendees.RecipientType -eq "User") {$User = (Get-MgUser -UserId $AuditData.Attendees.UserObjectid).UserPrincipalName }Else {$User = $AuditData.Attendees.DisplayName }If ($User -eq "b1902c3e-b9f7-4650-9b23-5772bd429747") {$User = "Teams Meeting Recording Bot"}$DataLine = [PSCustomObject] @{'Audit timestamp' = $Rec.CreationDateUser = $UserMeetingId = $AuditData.MeetingDetailIdStart = Get-Date($AuditData.JoinTime).ToLocalTime()End = Get-Date($AuditData.LeaveTime).ToLocalTime()Duration = $MeetingDuration.ToString()Role = $AuditData.Attendees.RoleDetailId = $AuditData.MeetingDetailIdArtifacts = $AuditData.ArtifactsShared.ArtifactSharedName -join ", "UserInfo = $AuditData.ExtraProperties.ValueType = "Participant"Operation = $Rec.Operations }}} # End Switch$MeetingRecords.Add($DataLine)} #End For$MeetingRecords | Sort-Object {$_.Date -as [datetime]}, MeetingId, Operation | `Select-Object Start, End, User, MeetingType, Organizer, Type, MeetingId | Out-GridView$MeetingRecords | Sort-Object {$_.Date -as [datetime]}, MeetingId, Operation | Export-CSV -NoTypeInformation $OutputCSVFile
Parameters
ParameterDefaultNotes
-LookbackDays90How many days back to search for newly created mailboxes or recent activity.-StartDate(Get-Date).AddDays(-90); $EndDate = (Get-Date).AddDays(1) # Set your own date span here!Start of the reporting window.-EndDate(Get-Date)End of the reporting window.Attribution
Author
Office365itpros