Enumerate all SharePoint Online site collections via the Graph API

In another article of the “this is now finally possible in Office 365”, here’s how to get a list of all SharePoint Online site collections (or “sites”, as Microsoft is confusingly calling themĀ  lately) via a simple Graph API query:

GET https://graph.microsoft.com/v1.0/sites

OK, not so fast! There are some important details we need to discuss here, starting with authentication. You need to have an app with at least Sites.Read.All application permissions granted. I repeat, application permissions! Delegate permissions are not currently supported, as apparently it’s too challenging to trim the output to just the sites a given user can access!?

The good news is that the method is available in /v1.0. As in, officially supported, GA, etc. Another good news is that it returns not only all the sites (collections) you will find listed under the SPO Admin Center, but also all personal ODFB sites. Which will come in handy for my “list all shared files” proof of concept script, which until now had to rely on workarounds in order to generate a list of all ODFB sites within the tenant. It does not however return “hidden” sites, such as those used by the redirect functionality, deleted ones, etc.

And of course, as with most things Graph, it’s not all good news. The set of properties returned for each site (collection) is minimal, and you cannot for example get useful information, such as which template is used. And while the lastModifiedDateTime property sounds like a useful one to report on, the value returned seems to always reflect the exact time you obtained the data. But hey, it’s a start.

Without further ado, here’s how a complete example looks like. Well, complete sans the authentication part, but here’s another reminder that you should be using the client credentials flow/application permissions model! Sample code below:

#List all sites, app-only context needed!
$uri = "https://graph.microsoft.com/v1.0/sites"
$Gr = Invoke-WebRequest -Headers $AuthHeader1 -Uri $uri -Verbose -Debug
$result = ($gr.Content | ConvertFrom-Json).Value
$result.count

61

So, a total of 61 site collections were returned for my tenant. We can group those by their type (not the same thing as template!), as follows:

$result | select @{n="Type";e={$_.siteCollection.hostname}} | group type -NoElement

Count Name
----- ----
12 michev-my.sharepoint.com
48 michev.sharepoint.com
1 michev-public.sharepoint.com

So, 12 out of these 61 site collections correspond to personal ODFB sites. We can filter out those directly via something like:

$result | ? {$_.siteCollection.Hostname -eq "michev-my.sharepoint.com"} | select name,webUrl,id

Unfortunately, we cannot filter out Group/Team sites, private channels and so on, as the output doesn’t feature any information on the template used.

Before finishing up, here’s another reminder that you must use application permissions to obtain the above! Here’s what the same call will result in when used with Graph explorer for example, even when running in the context of a Global admin user and having all delegate permissions granted:

No Graph explorer for you!

This entry was posted in Graph API, Microsoft 365, Office 365, SharePoint Online. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.