Entra / Microsoft 365 · Teams
Audit Teams meeting recording uploads
Uses Office 365 audit log records to track uploads of Teams meeting recordings to SharePoint or OneDrive.
Connect & set up
Run these once per session. All scopes are read-only unless the script makes changes.
Import-Module Microsoft.Online.SharePoint.PowerShell -UseWindowsPowerShell# Make sure that you use the right URL for your tenant hereConnect-SPOService -Url https://office365itpros-admin.sharepoint.com
Run it
The main script. Copy it, or download the .ps1 and run it from your console.
param([int] $LookbackDays = 180,[string] $StartDate = (Get-Date).AddDays(-$LookbackDays),[string] $EndDate = "Get-Date")Write-Host "Connecting to SharePoint Online to fetch details of OneDrive for Business sites..."# This part is to generate a hash table of OneDrive sites that we can use to look up for audit recordsImport-Module Microsoft.Online.SharePoint.PowerShell -UseWindowsPowerShell# Make sure that you use the right URL for your tenant hereConnect-SPOService -Url https://office365itpros-admin.sharepoint.com[array]$OneDriveSites = Get-SPOSite -IncludePersonalSite $true -Limit All `-Filter "Url -like '-my.sharepoint.com/personal/'" | Select-Object URL, Owner# Build the hash table$OneDriveHashTable = @{}ForEach ($Site in $OneDriveSites) {[string]$SiteKey = $Site.URL + "/"$OneDriveHashTable.Add($SiteKey, $Site.Owner)}# Connect to Exchange Online, if we're not already connected$Modules = Get-Module | Select-Object -ExpandProperty NameIf ("ExchangeOnlineManagement" -notin $Modules) {Write-Host "Connecting to Exchange Online..."Connect-ExchangeOnline -SkipLoadingCmdletHelp}Write-Host "Searching for Teams recordings upload audit records..."[array]$Records = Search-UnifiedAuditLog -Operations FileUploaded, FileModified `-StartDate $StartDate -EndDate $EndDate -Formatted -ResultSize 5000 -SessionCommand ReturnLargeSet `-UserIds "app@sharepoint" -RecordType SharePointFileOperationIf (!($Records)) {Write-Host "No audit records found - exiting!"; break}# Remove duplicates and make sure that we have a set sorted by date$Records = $Records | Sort-Object Identity -Unique | Sort-Object {$_.CreationDate -as [datetime]} -Descending$TaggedRecordings = [System.Collections.Generic.List[Object]]::new()ForEach ($Rec in $Records) {$AuditData = $Rec.AuditData | ConvertFrom-JsonIf (($AuditData.SourceFileExtension -eq "mp4") -and ($AuditData.SourceRelativeUrl -like "*/Recordings") `-and $AuditData.SourceFileName.Substring(0,4) -ne "~tmp") {$RecordingFileName = $AuditData.SourceFileName$DateLoc = $RecordingFileName.IndexOf("-202")If ($DateLoc -eq -1) {$Topic = $RecordingFileName} Else {$Topic = $RecordingFileName.SubString(0,$DateLoc)}# All uploads are performed by the app@sharepoint account, so we try to use the hash table# to figure out the owner of the target OneDrive for Business account$User = $OneDriveHashTable[$AuditData.SiteURL]If ($null -eq $User) {$User = "SharePoint app"}$CreationDate = Get-Date $Rec.CreationDate -format 'dd-MMM-yyyy HH:mm:ss'$DataLine = [PSCustomObject] @{Workload = $AuditData.WorkloadOperation = $Rec.OperationsDate = $CreationDateUser = $UserRecording = $RecordingFileName"Meeting title" = $TopicSite = $AuditData.SiteURLFullURL = $AuditData.ObjectIdFolder = $AuditData.SourceRelativeURL}$TaggedRecordings.Add($DataLine)} #End If} #End For$TaggedRecordings = $TaggedRecordings | Sort-Object {$_.Date -as [datetime]} -Descending$CSVOutputFile = ((New-Object -ComObject Shell.Application).Namespace('shell:Downloads').Self.Path) + "\TeamsRecordings.csv"$TaggedRecordings | Out-GridView -Title 'Teams Recordings Uploads'$TaggedRecordings | Export-CSV -NoTypeInformation $CSVOutputFile -Encoding utf8
Parameters
ParameterDefaultNotes
-LookbackDays180How many days back to search for newly created mailboxes or recent activity.-StartDate(Get-Date).AddDays(-180)Start of the reporting window.-EndDateGet-DateEnd of the reporting window.Attribution
Author
Office365itpros