Back to script library
Entra / Microsoft 365 · SharePoint & OneDrive

Find last accessed date for SharePoint documents

Find the last accessed date for documents in a SharePoint Online site 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

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 Name
If ("ExchangeOnlineManagement" -notin $Modules ) {
Write-Host "Connecting to Exchange Online..."
Connect-ExchangeOnline -ShowBanner:$false
}
# Change the site URL here to match your tenant and the site you want to search
[string]$TargetSite = Read-Host "Enter the URL of the SharePoint site to search. An example is https://yourtenant.sharepoint.com/sites/confidentialstuff/"
[string]$TargetSearchSite = $TargetSite + "*"
Write-Host ("Searching for SharePoint file operations in the {0} site between {1} and {2}" -f $TargetSite, $StartDate, $EndDate)
[array]$Records = Search-UnifiedAuditLog -StartDate $StartDate -EndDate $EndDate -RecordType "SharePointFileOperation" `
-ResultSize 5000 -SessionCommand ReturnLargeSet -Formatted -ObjectIds $TargetSearchSite
If (!($Records)) {
Write-Host "No audit records found"
Break
}
# Remove any duplicates
$Records = $Records | Sort-Object Identity -Unique | Sort-Object {$_.CreationDate -as [DateTime]}
Write-Host ("{0} SharePoint Online file operations audit records found" -f $Records.Count)
$Report = [System.Collections.Generic.List[Object]]::new()
ForEach ($Rec in $Records) {
$AuditData = $Rec.AuditData | ConvertFrom-Json
$ReportLine = [PSCustomObject]@{
Timestamp = Get-Date $Rec.CreationDate -format 'dd-MMM-yyyy HH:mm:ss'
User = $AuditData.UserId
Operation = $AuditData.Operation
File = $AuditData.SourceFileName
Folder = $AuditData.SourceRelativeUrl
URL = $AuditData.ObjectId
}
$Report.Add($ReportLine)
}
# Filter to find the operations performed by real users
[array]$UserFileOperations = $Report | Where-Object {
$_.Folder -ne 'SiteAssets' -and
$_.Folder -notlike '*PreservationHoldLibrary/SharedVersions*' -and
$_.Folder -notlike '*Shared Documents/Forms*'
}
# Eliminate events for AllItems.aspx
$UserFileOperations = $UserFileOperations | Where-Object {$_.File -ne 'AllItems.aspx'}
# Eliminate odd entries for SharePoint background operations and the SharePoint app
$UserFileOperations = $UserFileOperations | Where-Object {$_.User -ne 'eba15bfd-c28e-4433-a20e-0278888c5825'}
$UserFileOperations = $UserFileOperations | Where-Object {$_.User -ne 'bdc6105c-4e11-4050-82e6-6549f9b99b89'}
$UserFileOperations = $UserFileOperations | Where-Object {$_.User -ne '5fe32787-b1cf-46b2-a569-5cb8fe643755'}
$UserFileOperations = $UserFileOperations | Where-Object {$_.User -ne 'd3223827-5d85-4bd7-96d2-2579d3d0bf7a'}
$UserFileOperations = $UserFileOperations | Where-Object {$_.User -ne 'app@sharepoint'}
Write-Host "Files found with audit records for file operations"
$UserFileOperations | Group-Object File -NoElement | Sort-Object Count -Descending | Format-Table -AutoSize
Write-Host ""
Write-Host "Users who accessed files"
$UserFileOperations | Group-Object User -NoElement | Sort-Object Count -Descending | Format-Table -AutoSize
Write-Host ""
Write-Host "Latest file access for each file"
[array]$FilesAccessed = $UserFileOperations | Where-Object {$_.Operation -eq 'FileAccessed' -or $_.Operation -eq 'FileModified'} | Sort-Object File, {$_.Timestamp -as [DateTime]} -Descending
# Find set of unique files
[array]$UniqueFiles = $FilesAccessed | Sort-Object File -Unique | Select-Object -ExpandProperty File
$LastAccessReport = [System.Collections.Generic.List[Object]]::new()
ForEach ($File in $UniqueFiles) {
$FileAccessInfo = $FilesAccessed | Where-Object {$_.File -eq $File} | Sort-Object {$_.TimeStamp -as [datetime]} -Descending | Select-Object -First 1
$ReportLine2 = [PSCustomObject]@{
File = $FileAccessInfo.File
User = $FileAccessInfo.User
TimeStamp = $FileAccessInfo.Timestamp
}
$LastAccessReport.Add($ReportLine2)
}
$LastAccessReport | Format-Table File, User, TimeStamp -AutoSize
$FilesAccessed | Out-GridView -Title "SharePoint Files Accessed"

Parameters

ParameterDefaultNotes
-LookbackDays180Number of days back to search SharePoint file access 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