Entra / Microsoft 365 · SharePoint & OneDrive
Find SharePoint files with downgraded sensitivity labels
Find files in SharePoint Online where users removed or lowered the assigned sensitivity label, using unified audit log records.
Connect & set up
Run these once per session. All scopes are read-only unless the script makes changes.
Connect-ExchangeOnline -ShowBanner:$False -SkipLoadingCmdletHelpConnect-IPPSSession -ShowBanner:$False
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).AddDays(1))[array]$Modules = Get-Module | Select-Object -ExpandProperty NameIf ("ExchangeOnlineManagement" -notin $Modules) {Write-Host "Connecting to Exchange Online..."Connect-ExchangeOnline -ShowBanner:$False -SkipLoadingCmdletHelpConnect-IPPSSession -ShowBanner:$False}# Define the operations to look for[array]$Operations = 'FileSensitivityLabelRemoved', 'FileSensitivityLabelChanged'# Averahe rate of downgrades per day that is acceptable$DownGradeThreshold = 20Write-Host "Looking for audit records for sensitivity label changes in SharePoint Online..."[array]$Records = Search-UnifiedAuditLog -StartDate $StartDate -EndDate $EndDate -Formatted -Operations $Operations -ResultSize 5000 -SessionCommand ReturnLargeSetIf (!($Records)) {Write-Host "No audit records found"Break} Else {$Records = $Records | Sort-Object Identity -Unique | Sort-Object {$_.CreationDate -as [DateTime]}}# Get labelsWrite-Host "Retrieving sensitivity labels..."[array]$Labels = Get-Label | Where-Object {$_.ContentType -like "*File*"} | Select-Object DisplayName, ImmutableId, Priority$LabelDisplayNameHash = @{}$Labels.ForEach( {$LabelDisplayNameHash.Add([String]$_.ImmutableId, $_.DisplayName) } )$LabelPriorityHash = @{}$Labels.ForEach( {$LabelPriorityHash.Add([String]$_.ImmutableId, $_.Priority) } )# Output report$Report = [System.Collections.Generic.List[Object]]::new()Write-Host "Analyzing audit records..."ForEach ($Rec in $Records) {$LabelDisplayName = $null; $LabelAction = $null; $OldLabelDisplayName = $null; [int]$Priority = $null; [int]$OldPriority = $null$AuditData = $Rec.AuditData | ConvertFrom-Json# Figure out what happened... Note thatg the $AuditData.Sensitivitylabeleventdata.LabelEventType contains codes that are not documented# to indicate the kind of change. 1 = Upgraded, 2 = Downgraded, 3 = Removed. We use the priority of the labels to determine the changeSwitch ($Rec.Operations) {'FileSensitivityLabelRemoved' {$LabelAction = "Removed"$OldLabelDisplayName = $LabelDisplayNameHash[$AuditData.SensitivityLabelEventData.OldSensitivityLabelId]If ($null -eq $OldLabelDisplayName) {$OldLabelDisplayName = "Unknown"}}'FileSensitivityLabelChanged' {$LabelDisplayName = $LabelDisplayNameHash[$AuditData.SensitivityLabelEventData.SensitivityLabelId]$OldLabelDisplayName = $LabelDisplayNameHash[$AuditData.SensitivityLabelEventData.OldSensitivityLabelId][int]$Priority = $LabelPriorityHash[$AuditData.SensitivityLabelEventData.SensitivityLabelId][int]$OldPriority = $LabelPriorityHash[$AuditData.SensitivityLabelEventData.OldSensitivityLabelId]$LabelAction = $nullIf ($Priority -gt $OldPriority) {$LabelAction = "Upgraded"} ElseIf ($Priority -lt $OldPriority) {$LabelAction = "Downgraded"} ElseIf ($OldPriority -eq $Priority) {$LabelAction = "No change"}}}$ReportLine = [PSCustomObject]@{Timestamp = Get-Date $Rec.CreationDate -format 'dd-MMM-yyyy HH:mm:ss'User = $AuditData.UserIdOperation = $AuditData.OperationFile = $AuditData.SourceFileNameFolder = $AuditData.SourceRelativeUrlLabelAction = $LabelActionOldLabel = $OldLabelDisplayNameOldPriority = $OldPriorityNewLabel = $LabelDisplayNameNewPriority = $PriorityURL = $AuditData.ObjectIdEventCode = $AuditData.Sensitivitylabeleventdata.LabelEventType}$Report.Add($ReportLine)}$Report = $Report | Sort-Object {$_.TimeStamp -as [DateTime]} -Descending$EarliestRecord = $Report[-1].TimeStamp$LatestRecord = $Report[0].TimeStamp$ReviewPeriodDays = (New-TimeSpan -Start $EarliestRecord -End $LatestRecord).Days[array]$DowngradedFiles = $Report | Where-Object {$_.LabelAction -eq 'Downgraded'}[array]$UpgradedFiles = $Report | Where-Object {$_.LabelAction -eq 'Upgraded'}[array]$RemovedFiles = $Report | Where-Object {$_.LabelAction -eq 'Removed'}[array]$RemovedAndDowngraded = $RemovedFiles + $DowngradedFiles[array]$UsersWhoDowngrade = $DowngradedFiles | Where-Object {$_.User -ne 'SHAREPOINT\System'} | Group-Object User -NoElement | Sort-Object Count -Descending$AverageDowngradeRate = [Math]::Round($RemovedAndDowngraded.Count / $ReviewPeriodDays, 2)Write-Host ""Write-Host "The following accounts have downgraded or removed sensitivity labels applied to documents"Write-Host "-----------------------------------------------------------------------------------------"$UsersWhoDowngrade | Format-Table Name, Count -AutoSizeWrite-Host ""Write-Host ("Over the recorded period from {0} to {1}, {2} audit records found" -f $EarliestRecord, $LatestRecord, ($RemovedAndDowngraded.Count + $UpgradedFiles.count))Write-Host ("Audit records for sensitivity label changes found {0} downgrades, {1} removals, and {2} upgradeds" -f $DowngradedFiles.Count, $RemovedFiles.count, $UpgradedFiles.Count)If ($AverageDowngradeRate -lt $DowngradeThreshold) {Write-Host ("An average rate of {0} label downgrades and removals per day is not an issue" -f $AverageDowngradeRate)} Else {Write-Host ("An average rate of {0} labnel downgrades and removals per day is of some concern" -f $AverageDowngradeRate)}
Parameters
ParameterDefaultNotes
-LookbackDays180Number of days back to search for sensitivity label change audit records.-StartDate(Get-Date).AddDays(-180)Start of the audit log search window.-EndDate(Get-Date).AddDays(1)End of the audit log search window.Attribution
Author
Office365itpros