In the past I’ve written posts for “PowerShell to Enumerate SharePoint 2010 or SharePoint 2013 Permissions” or “PowerShell Script To Traverse All Sites In SharePoint 2010 (or 2007) Farm” to assist with traversing through all sites within a SharePoint on-prem farm. In this post I’ll share a snippet I recently used for traversing through all site collections and subsites within a SharePoint Online tenant.
If you’ve worked with the SharePoint Online Management Shell you may know that originally it was not able to retrieve Personal Sites (also known as My Sites / OneDrive for Business sites) in SharePoint Online. As far as I’m aware this was primarily a limitation of the underlying client side libraries (Microsoft.SharePoint.Client.*). Fast forward to a recent release (I don’t have the specific one but I can confirm it is in the 16.1.6621.1200 release of the Microsoft.SharePointOnline.CSOM NuGet package) and now it is supported to retrieve Personal Sites. In the management shell this is accomplished by calling the following:
Connect-SPOService -Url ‘<tenantAdminUrl>’
Get-SPOSite -Limit all -IncludePersonalSite $true
The problem is that if you want to traverse all site collections in SharePoint Online in client side object model (CSOM) you would need to know how the SharePoint Online Management Shell implements that inclusion of Personal Sites with the rest of site collections. In order to find this out I used a disassembler (ILSPY in my case, but there are many alternatives available as well) on the underlying libraries to recreate the process in my own code.
The resulting CSOM that I came up with is below. The yellow code is processing all site collections within SharePoint Online while the green code is processing sites (subsites / webs / “not site collections”). Feel free to borrow this and use in your own code but note that it is provided as-is with no warranty.
SPOSitePropertiesEnumerable ssp = null;
SPOSitePropertiesEnumerableFilter sspFilter = new SPOSitePropertiesEnumerableFilter();
SharePointOnlineCredentials creds = new SharePointOnlineCredentials(“myUsernameGoesHere”, securePassword);
using (PnPClientContext cc = new PnPClientContext(“myURLGoesHere”))
cc.Credentials = creds;
Tenant tenant = new Tenant(cc);
//loop through all site collections including personal sites (even though not being used)
//borrowed this code from after decompiling SPO Management Shell assemblies
sspFilter.IncludePersonalSite = PersonalSiteFilter.Include;
sspFilter.IncludeDetail = true;
sspFilter.StartIndex = null;
ssp = tenant.GetSitePropertiesFromSharePointByFilters(sspFilter);
foreach (SiteProperties sp in ssp)
//DO YOUR WORK HERE FOR EACH SITE COLLECTION, such as looping through subwebs
cc.Load(cc.Web, w => w.NoCrawl,
w => w.Webs,
w => w.Url);
foreach (var subweb in cc.Web.Webs)
cc.Load(subweb, sw => sw.NoCrawl,
sw => sw.Url);
In this post I shared a snippet for traversing all site collections in SharePoint Online with C# CSOM code. In my daily job I’ve been using this in combination with Azure Functions for a number of interesting interactions with a SharePoint Online tenant. More to come on those scenarios in future weeks. For now let me know in the comments if you have any questions or issues implementing the above snippet in your own code. Happy coding!