Setting SharePoint Online site collection to Read Only state based on Last Activity Date

In my last post I showed how to get SharePoint Online Site Collection Last Activity Date with Microsoft Graph API.

In this post I will demonstrate how to use last activity date and set site collection to Read Only -mode using SharePoint Online Site Policy Feature.

Create Site Policy and publish it to site collections from a Content Type Hub

First we need to create a Site Policy. You can create site policy for individual site collection at site collection level or all site collections in a Content Type Hub. I choose the later one and create site policies in a Content Type Hub.

SharePoint Online Content Type Hub can be found from address https://<tenantURL>/sites/ContentTypeHub.

There is a Site Policies -link in a Site Settings > Site Collection Administration.

In Site Policies you can create policy you like. I created policy which closes the site and deletes it after 3 years. When the site collection is closed it is set to read only mode.

After you have created the policy, you need to publish it to the site collections. This can be done clicking “manage publishing for this policy”.

In a Content Type Publishing Settings you can Publish, Unpublish or Republish your site policy to SharePoint Online site collections.

Activate Site Policy to site collection manually or using PowerShell

When you have created and published Site Policy in a Content Type Hub, you can use it in a Site Collection. You can activate Site Policy manually from Site Settings or you can use PnP PowerShell Set-PnPSitePolicy command to activate site policy with PowerShell.

Activate Site Policy manually
You can activate site policy to site collection from Site Settings. There is Site Closure and Deletion -link in Site Administration.

Note! If you don’t see Site Closure and Deletion in a Site Administration, the reason is that Site Policy Feature is not Activated on the site collection level. Go to Site Settings and Site collection features to Active Site Policy Feature.

Here you can see settings for Site Closure and Deletion. In picture below you can see that Site Policy named “Set site read only” was applied to the site collection and information message “This site is read only at the site collection administrator’s request” is displayed in top of the browser window.

Activate Site Policy using PnP PowerShell
I made PowerShell script for getting all Site Collection’s Last Activity Date from Graph API and then set Site Policy for site collection’s using Set-PnPSitePolicy command if site last activity date is older than 120 days.

Firsth we use Invoke-RestMethod to get SharePoint Site Collection usage details from Microsoft Graph API.

If Site’s Last Activity Date is older than 120 days and Site Template is Team Site or Group, we call function Set-SitePolicyPnP for activating the Site Policy named “ReadOnlyCTHubAuto” for the Site Collection.

#Get SharePoint site activity from Graph Api
$String = "https://graph.microsoft.com/beta/reports/getSharePointSiteUsageDetail`(`period=`'`D180`'`)?`$format=application/json"

$Results = Invoke-RestMethod -Headers @{Authorization = "Bearer $accessToken"} -Method Get -Uri $String 

Write-Host "Number of sites found:" $Results.value.Count.ToString() -ForegroundColor Green 
$Today = Get-Date 
write-Host "Current date:" $Today
$ExpDate = $Today.AddDays(-120)
write-Host "Expiration date:" $ExpDate

$Results.value | Sort-Object -Property lastActivityDate | Select-Object -Property siteUrl, lastActivityDate, rootWebTemplate | ForEach-Object {
    write-Host "------" 
    $_.siteUrl
    write-Host "Last activity date:" $_.lastActivityDate
    $_.rootWebTemplate
        #If lastActivityDate is null or empty
        if (!$_.lastActivityDate) {write-host "Last activity date not found" -ForegroundColor Yellow }
        #If lastActivityDate is older than 120 days and site template is classic Team Site or Group
        elseif(([datetime]$_.lastActivityDate -lt $ExpDate -and $_.rootWebTemplate -eq "Group") -or ([datetime]$_.lastActivityDate -lt $ExpDate -and $_.rootWebTemplate -eq "Team Site")) {
            write-host "Site is out of the date" -ForegroundColor Red
            write-host "Setting Site Policy with PnP" -ForegroundColor Blue
            Set-SitePolicyPnP -siteUrl $_.siteUrl -rootWebTemplate $_.rootWebTemplate
         }
        #If lastActivityDate is newer than 30 days
        elseif ([datetime]$_.lastActivityDate -ge $ExpDate) {write-host "Site is okay" -ForegroundColor Green } 
} 

Here is the Function to Setting the Site Policy with Set-PnPSitePolicy.
Note!: Because Group based Site Collection don’t have Site Policy Feature already activated, I made check for that and activate feature using Enable-PnPFeature -Identity 2fcd5f8a-26b7-4a6a-9755-918566dba90a (this is guide for SharePoint Site Policy feature).

function Set-SitePolicyPnP ($siteUrl, $rootWebTemplate)
{
    #Connect to the site 
    $Connection = Connect-PnPOnline -Url $siteUrl -UseWebLogin
    write-Host $siteUrl -ForegroundColor Blue
    write-Host $rootWebTemplate -ForegroundColor Yellow

   #check if site is based on Team Site or Group template then activate site policy feature
     if (($rootWebTemplate -eq "Team Site") -or ($rootWebTemplate -eq "Group"))  {
 
        write-Host "Enabling feature and policy for site closure" -ForegroundColor Green
        $SitePolicyFeatureActivated = ""
        $SitePolicyFeatureActivated = Get-PnPFeature -Identity 2fcd5f8a-26b7-4a6a-9755-918566dba90a -Scope Site -Web $SiteUrl -Connection $Connection 
        $SitePolicyFeatureActivated = $SitePolicyFeatureActivated | Select-Object -Property DisplayName

        if (!$SitePolicyFeatureActivated) { 
            write-Host "Site Policy feature is not activated" $SiteUrl -ForegroundColor Yellow
            Enable-PnPFeature -Identity 2fcd5f8a-26b7-4a6a-9755-918566dba90a -Scope Site -Connection $Connection 
            write-Host "Site Policy feature now activated" $SiteUrl -ForegroundColor Green
            $SitePolicyActivated = Get-PnPSitePolicy -Name "ReadOnlyCTHubAuto" -Connection $Connection | Select-Object -Property Name
            if (!$SitePolicyActivated) {
                write-Host "Site Policy ReadOnlyCTHubAuto not found" $SiteUrl -ForegroundColor Yellow
                write-Host "Site Policy ReadOnlyCTHubAuto has not been set" $SiteUrl -ForegroundColor Yellow
            }
            elseif ($SitePolicyActivated) {
                write-Host "Site Policy ReadOnlyCTHubAuto found" $SiteUrl -ForegroundColor Green
                Set-PnPSitePolicy -Name "ReadOnlyCTHubAuto" -Connection $Connection
                write-Host "Site Policy ReadOnlyCTHubAuto have been set" $SiteUrl -ForegroundColor Green
            }
         } 
         elseif ($SitePolicyFeatureActivated) {
            write-Host "Site Policy feature is already activated" $SiteUrl -ForegroundColor Green
            $SitePolicyActivated = Get-PnPSitePolicy -Name "ReadOnlyCTHubAuto" -Connection $Connection | Select-Object -Property Name
                if (!$SitePolicyActivated) {
                    write-Host "Site Policy ReadOnlyCTHubAuto not found" $SiteUrl -ForegroundColor Yellow
                    write-Host "Site Policy ReadOnlyCTHubAuto has not been set" $SiteUrl -ForegroundColor Yellow
                }
                elseif ($SitePolicyActivated) {
                    write-Host "Site Policy ReadOnlyCTHubAuto found" $SiteUrl -ForegroundColor Green
                    Set-PnPSitePolicy -Name "ReadOnlyCTHubAuto" -Connection $Connection
                    write-Host "Site Policy ReadOnlyCTHubAuto have been set" $SiteUrl -ForegroundColor Green
                }
            
         }

    }

}

Here is the whole script.

#Getting SharePoint Online last activity date and setting site policy for site
function Set-SitePolicyPnP ($siteUrl, $rootWebTemplate)
{
    #Connect to the site 
    $Connection = Connect-PnPOnline -Url $siteUrl -UseWebLogin
    write-Host $siteUrl -ForegroundColor Blue
    write-Host $rootWebTemplate -ForegroundColor Yellow
 
 #check if site is based on Team Site or Group template then activate site policy feature
     if (($rootWebTemplate -eq "Team Site") -or ($rootWebTemplate -eq "Group"))  {
 
        write-Host "Enabling feature and policy for site closure" -ForegroundColor Green
        $SitePolicyFeatureActivated = ""
        $SitePolicyFeatureActivated = Get-PnPFeature -Identity 2fcd5f8a-26b7-4a6a-9755-918566dba90a -Scope Site -Web $SiteUrl -Connection $Connection 
        $SitePolicyFeatureActivated = $SitePolicyFeatureActivated | Select-Object -Property DisplayName

        if (!$SitePolicyFeatureActivated) { 
            write-Host "Site Policy feature is not activated" $SiteUrl -ForegroundColor Yellow
            Enable-PnPFeature -Identity 2fcd5f8a-26b7-4a6a-9755-918566dba90a -Scope Site -Connection $Connection 
            write-Host "Site Policy feature now activated" $SiteUrl -ForegroundColor Green
            $SitePolicyActivated = Get-PnPSitePolicy -Name "ReadOnlyCTHubAuto" -Connection $Connection | Select-Object -Property Name
            if (!$SitePolicyActivated) {
                write-Host "Site Policy ReadOnlyCTHubAuto not found" $SiteUrl -ForegroundColor Yellow
                write-Host "Site Policy ReadOnlyCTHubAuto has not been set" $SiteUrl -ForegroundColor Yellow
            }
            elseif ($SitePolicyActivated) {
                write-Host "Site Policy ReadOnlyCTHubAuto found" $SiteUrl -ForegroundColor Green
                Set-PnPSitePolicy -Name "ReadOnlyCTHubAuto" -Connection $Connection
                write-Host "Site Policy ReadOnlyCTHubAuto have been set" $SiteUrl -ForegroundColor Green
            }
         } 
         elseif ($SitePolicyFeatureActivated) {
            write-Host "Site Policy feature is already activated" $SiteUrl -ForegroundColor Green
            $SitePolicyActivated = Get-PnPSitePolicy -Name "ReadOnlyCTHubAuto" -Connection $Connection | Select-Object -Property Name
                if (!$SitePolicyActivated) {
                    write-Host "Site Policy ReadOnlyCTHubAuto not found" $SiteUrl -ForegroundColor Yellow
                    write-Host "Site Policy ReadOnlyCTHubAuto has not been set" $SiteUrl -ForegroundColor Yellow
                }
                elseif ($SitePolicyActivated) {
                    write-Host "Site Policy ReadOnlyCTHubAuto found" $SiteUrl -ForegroundColor Green
                    Set-PnPSitePolicy -Name "ReadOnlyCTHubAuto" -Connection $Connection
                    write-Host "Site Policy ReadOnlyCTHubAuto have been set" $SiteUrl -ForegroundColor Green
                }
            
         }

    }

}

#Get SharePoint site activity from Graph Api
$String = "https://graph.microsoft.com/beta/reports/getSharePointSiteUsageDetail`(`period=`'`D180`'`)?`$format=application/json"

$Results = Invoke-RestMethod -Headers @{Authorization = "Bearer $accessToken"} -Method Get -Uri $String 

Write-Host "Number of sites found:" $Results.value.Count.ToString() -ForegroundColor Green 
$Today = Get-Date 
write-Host "Current date:" $Today
$ExpDate = $Today.AddDays(-120)
write-Host "Expiration date:" $ExpDate

$Results.value | Sort-Object -Property lastActivityDate | Select-Object -Property siteUrl, lastActivityDate, rootWebTemplate | ForEach-Object {
    write-Host "------" 
    $_.siteUrl
    write-Host "Last activity date:" $_.lastActivityDate
    $_.rootWebTemplate
        #If lastActivityDate is null or empty
        if (!$_.lastActivityDate) {write-host "Last activity date not found" -ForegroundColor Yellow }
        #If lastActivityDate is older than 120 days and site template is classic Team Site or Group
        elseif(([datetime]$_.lastActivityDate -lt $ExpDate -and $_.rootWebTemplate -eq "Group") -or ([datetime]$_.lastActivityDate -lt $ExpDate -and $_.rootWebTemplate -eq "Team Site")) {
            write-host "Site is out of the date" -ForegroundColor Red
            write-host "Setting Site Policy with PnP" -ForegroundColor Blue
            Set-SitePolicyPnP -siteUrl $_.siteUrl -rootWebTemplate $_.rootWebTemplate
         }
        #If lastActivityDate is newer than 30 days
        elseif ([datetime]$_.lastActivityDate -ge $ExpDate) {write-host "Site is okay" -ForegroundColor Green } 
} 

Conclusions

Using Microsoft Graph API and PnP PowerShell commands you can do lot of automation in your SharePoint Online Tenant.

3 thoughts on “Setting SharePoint Online site collection to Read Only state based on Last Activity Date

  1. Steve Johnson

    Many, many thanks for this! I was literally about to write something similar and stumbled across your wonderful post!

    Like

    1. Hi, If you don’t see Site Closure and Deletion in a Site Administration, the reason is that Site Policy Feature is not Activated on the site collection level. Go to Site Settings and Site collection features to Active Site Policy Feature.

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s