I am searching for a definitive solution to accurately identify which sites (and the data contained in those sites) within my SharePoint Online tenant have not been accessed on interacted with by any user for x amount of time, and then generate an Excel report with a list of those sites.

I have been trying to find the solution to this problem for several months to no avail. I see that this question or similar has been asked here before but I do not believe that the correct solution was identified, at least for my circumstances.

Thus far, I have tried developing scripts to access the LastItemUserModifiedDate property for all sites with both the SharePoint Online Management Shell, and the PnP management shell. No matter what I do, I either get incorrect results or errors.

I have tried using all the methods described in the SharePoint Dictionary blog, and I have tried using the browser centre, which I have found to display inaccurate results. Either I get a result which is skewed by automated system actions, or SharePoint is reporting an actively used site as completely unused.

We have Multifactor Authentication enabled across O365 and I have found in some instances this seems to cause issues with certain scripts, even though I modify them to use the interactive web login.

Can anyone provide me with some advice about how I should approach this please? Any anecdotes on how you manage unused sites within your own setup would also be helpful.

2 Answers 2


PnP PowerShell to Get Unused Site Collections in the past 30 days

$TenantAdminURL = "https://Crescent-Admin.SharePoint.com"
$TenantURL = "https://Crescent.SharePoint.com"
$DaysInActive = 30 # number of days to check since last modified
$CSVPath = "C:\Temp\InactiveSites.csv"
#Connect to Admin Center
Connect-PnPOnline -Url $TenantAdminURL -Credentials $Cred
#Get All Site collections - Exclude BOT, Video Portals and MySites
$SiteCollections = Get-PnPTenantSite -Filter "Url -like $TenantURL -and Url -notlike '-my.sharepoint.com/' -and Url -notlike '/portals/'"
#Calculate the Date
$Date = (Get-Date).AddDays(-$DaysInActive).ToString("MM/dd/yyyy")
#Get All Site collections where the content modified
$InActiveSites = $SiteCollections | Where {$_.LastContentModifiedDate -le $Date} | Select Title, Url, LastContentModifiedDate, Template, StorageMaximumLevel
#Export to CSV
$InActiveSites | Export-Csv -Path $CSVPath -NoTypeInformation

enter image description here

enter image description here

More information, please view the below post.

  • I have tried this script, unfortunately the results returned are inaccurate due to automated system actions causing false positives. the LastItemModifiedDate returns a timestamp of reflecting changes made by the system, where as I want to know if any user has accessed the site or files within it.
    – Bosco
    Commented May 4, 2021 at 11:13
  • 1
    EDIT: I have changed lastItemModifiedDate to LastItemUserModifiedDate and I am getting better results although the date function doesn't work as I am getting results from all sites whether I input 1 day or 1000 days
    – Bosco
    Commented May 4, 2021 at 11:34
  • Hi, Bosco. Thanks for your reply. I'm glad to hear that your problem has been solved. Have a nice day! Commented May 14, 2021 at 7:52

In the article above author use LastContentModifiedDate Site property, but actually there are also

  • LastItemModifiedDate Web property
  • LastItemUserModifiedDate Web property
  • LastModifiedDateTime MS Graph site property

Here are the differences

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.