SharePoint : Your storage is almost full - one approach

Steel Contributor

I've been looking for low impact ways to minimize our storage usage across our SharePoint tenant.

This post outlines the approach I took and the outcome, and who it might work for.

 

My environment:

Only 350GB remaining in Tenancy 8.7 TB used.
265 sharepoint sites in total (teams / communication etc)

 

I decided to focus on sites with more than 100Gb of storage used. In my case this turned up 
16 sites. Of these I had to exclude 2 sites.
This left 14 sites using 5.194553 TB

 

My goal was to have low/no impact on users while reducing the volume of content in our M365 tenant SharePoint environment.

My approach was to do the following:
- Get list of all SharePoint site collections, find out Size of each
Those larger than 100Gb do the following:
- delete all items in recycle bin deleted more than 30 days ago (current setting 93 days, unchanged)
- delete all items from 2nd stage recycle bin (current setting 30 days, unchanged)
- change all user libraries from 500 to 100 major versions

 

In my environment the recycle bins are rarely used and when I ran a script to work out the average number of versions it was in the 10s at most and for most sites it was 3 or 4.

NOTE no sites have minor versioning turned on.

 

I wanted to measure the change so I exported a usage report pre and post doing the above. To achieve all this I used the following code, then the following day checked the SharePoint admin centre reported the same "Storage used" numbers.

 

BE AWARE the code below DELETES data you cannot get back (file versions, and files in the recycle bin). DO NOT RUN THIS to try it out. Test it on one or two sites first. Even if you have backups getting version history back would be very challenging.

 

 

<# goal is to reduce size sites take up

1 change version from 500 to 100

2 recycle bin deleted more than 30 days ago, move to 2nd stage recycling

3 empty second stage recycling


#>


#Get current stats

#Connect to Admin Center   

$AdminCenterURL = "https://MyCompanyName-admin.sharepoint.com"


Connect-PnPOnline -Url $AdminCenterURL -Interactive 

reportTenantSiteCollectioninfo 


function reportTenantSiteCollectioninfo 
{
		Try {
			#export file path 
			$dateStamp = get-date -format "yyyyMMdd-hhmm"

			$CSVPath = "c:\Temp\SiteUsageRpt-"+$dateStamp+".csv"

		  
			#Get all site usage details
			$Sites = Get-PnPTenantSite  -Detailed | Select *
		 
			$SiteUsageData = @()
			ForEach ($Site in $Sites)
			{
				#Collect site data
				$SiteUsageData += New-Object PSObject -Property ([ordered]@{               
						'Title'                    = $Site.Title
						'URL'                      = $Site.Url
						'Description'              = $Site.Description                    
						'Owner'                    = $Site.OwnerName
						'Storage Quota'            = $Site.StorageQuota
						'Storage MaximumLevel'     = $Site.StorageMaximumLevel 
						'Storage Usage Current'    = $Site.StorageUsageCurrent
						'Resource Quota'           = $Site.ResourceQuota
						'Resource Quota Warning'   = $Site.ResourceQuotaWarningLevel
						'Resource Usage Average'   = $Site.ResourceUsageAverage
						'Resource Usage Current'   = $Site.ResourceUsageCurrent
						'Template'                 = $Site.Template
						'Sharing Capability'       = $Site.SharingCapability
						'Lock Status'              = $Site.LockState
						'Last Modified Date'       = $Site.LastContentModifiedDate
						'Subsites Count'           = $Site.WebsCount
					})
			}
			$SiteUsageData
			#Export Site Usage Data to CSV
			$SiteUsageData | Export-Csv $CSVPath -NoTypeInformation
			Write-Host "Site Usage Report Generated Successfully!" -ForegroundColor Green
		}
		Catch {
			Write-Host -ForegroundColor Red "Error generating site usage report:" $_.Exception.Message
		}
}


Function Set-PnPVersionHistoryLimit
{
    param
    (
        [Parameter(Mandatory=$true)] $Web,
        [parameter(Mandatory=$false)][int]$VersioningLimit = 100
    )
     
    Try {
        Write-host "Processing Web:"$Web.URL -f Yellow
        Connect-PnPOnline -Url $Web.URL -Interactive
 
        #Array to exclude system libraries
        $SystemLibraries = @("Form Templates", "Pages", "Preservation Hold Library","Site Assets", "Site Pages", "Images",
                            "Site Collection Documents", "Site Collection Images","Style Library","Teams Wiki Data")
         
        $Lists = Get-PnPList -Includes BaseType, Hidden, EnableVersioning
        #Get All document libraries
        $DocumentLibraries = $Lists | Where {$_.BaseType -eq "DocumentLibrary" -and $_.Hidden -eq $False -and $_.Title -notin $SystemLibraries}
         
        #Set Versioning Limits
        ForEach($Library in $DocumentLibraries)
        {
            #powershell to set limit on version history
            If($Library.EnableVersioning)
            {
                #Set versioning limit
                Set-PnPList -Identity $Library -MajorVersions $VersioningLimit
                Write-host -f Green "`tVersion History Settings has been Updated on '$($Library.Title)'"
            }
            Else
            {
                Write-host -f Yellow "`tVersion History is turned-off at '$($Library.Title)'"
            }
        }
    }
    Catch {
        Write-host -f Red "Error:" $_.Exception.Message
    }
}





<#

Get a list of big sites 
#>

$bigSites = $SiteUsageData | where "Storage Usage Current" -gt 100000

$bigSites = $bigSites | where title -notin ("excluded site 1","excluded site 2")
$bigSites.count 

#loop through the big sites

foreach($bigsite in $bigSites) {

	connect-pnponline -url $bigSite.URL -interactive
	
	## get the deleted items that were deleteed more than 30 days ago

	$date30daysago = (get-date).adddays(-30)

	$DeletedItemsOlder = Get-PnPRecycleBinItem | Where { $_.DeletedDate -le $date30daysago} | Sort-Object -Property DeletedDate -Descending
	$DeletedItemsOlder.count

	#move all these to 2nd stage recycle bin
	$DeletedItemsOlder | Move-PnPRecycleBinItem -force

	#empty the second stage recycle bin
	Clear-PnPRecycleBinItem -SecondStageOnly -force
	
	#get all the libraries
	$Webs = Get-PnPSubWeb -Recurse -IncludeRootWeb
  
		ForEach($Web in $Webs)
		{ 
			Set-PnPVersionHistoryLimit -Web $Web
		}

	
}

#get site info again

reportTenantSiteCollectioninfo 

 

 

Outcome

[Updated 7 Aug 2023] On the day the outcome was spectacularly unsuccessful.

I saved 24GB by doing this across 5.194553 Terra bytes or less than 0.5 %
So worth trying, but not valuable in my environment, I thought.

But when I looked at the SharePoint admin screen, Storage used, in August there is a big drop two days after running this script. From 8.8TB down to 8.6TB so approx 200GB saving. Unfortunately this may not have been all to do with this script (other things going on in my tenant) but a lot of it is, again not massive at 2% but useful.

 

When would this be valuable for reducing storage volume ? I think the key thing isn't the removal of files from the recycle bins, but the removal of older versions of files. SO if you have an environment with most files having 100's of versions , and those versions are large changes to the file each time. (e.g. a daily report that has new images replace existing ones each day) then this could save a lot of space.

 

What about you?

How do you reduce SharePoint storage? What have you found that works?

 

2 Replies

@Dorje-McKinnon 

 

We are continuously adding space to SP Online site, because my SharePoint online is constantly running out of space, we have huge libraries with 1000 GB and 10000 Versions.

 

My Question:

with retention policy in place, therefore versions with retention policy will be deleted old versions and limit 50 versions by the script above. If not, what is the best course of action for my problem?

 

we have retention policy in place for 7 Years.

 

looking for best solution for high SharePoint storage Issue. 

Hi @N51768 

I'm not sure what the retention policy will do to your space ? You'll need to ask someone who works with that a lot.

 

If you've used "Version settings" for your libraries, that should mean that you have a maximum of 60 versions for any file in that library.

I'd suggest you check that first. e.g. a file that has existed for a long time, and is edited regularly might have be on Version 276, and you should only be able to go back 50 versions to version 226 and not further back in time.

If that is true for your files, then the space may be being eaten up by either the retention policy and or the size of the files.

 

In my environment I found that some files with 100s of versions took up almost no space, but that for most Word and Excel files previous versions were the same size as the file at that version. So for some files that were being edited hundreds of times a day we moved over to SharePoint lists or other solutions. This saved us quite a bit of space.

 

The other recommendation would be to get your Microsoft Account manager to take a look and help out. If you have that many files and are spending extra on storage they will likely be able to provide some recommendations.