Code Sample – Enumerate all sub webs of a SPO site collection

In SharePoint OnPremise, it is very easy to enumerate all the sub webs [SPWeb] of a site collection [SPSite]. This is exposed as the AllWebs property under the SPSite object – See here.

However, this is not exposed in SharePoint Online via CSOM. So in order to touch all the SPWeb objects via CSOM, we need to use recursion – and the below code sample can assist in achieving that.

# replace these details (also consider using Get-Credential to enter password securely as script runs)

$username
=
"administrator@domain.onmicrosoft.com"

$password
=
"pwd"

 

#Provide site collection URL here. Alternatively, you can enumerate all site collections using get-sposite and process each.

#The SPSite will be constructed based on this URL.

$url
=
"https://domain.sharepoint.com/"

 

$securePassword
=
ConvertTo-SecureString
$Password
-AsPlainText
-Force

 

#Install SharePoint Online Client SDK on the machine you are running this script to load these DLLs.

 

[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SharePoint.Client')

[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SharePoint.Client.Runtime')

 

# connect/authenticate to SharePoint Online and get ClientContext object

$clientContext
=
New-Object
Microsoft.SharePoint.Client.ClientContext($url)

$credentials
=
New-Object
Microsoft.SharePoint.Client.SharePointOnlineCredentials($username, $securePassword)

$clientContext.Credentials = $credentials

 

if (!$clientContext.ServerObjectIsNull.Value)

{

Write-Host
"Connected to SharePoint Online site: '$Url'"
-ForegroundColor
Green

}

 

 

function
processWeb($web)

{

    if($urls
-notcontains
$web.url)

    {

        $urls
+=
$web.url

    }

    function
getchildcount($web)

    {

        $web.Context.Load($web.webs)

$web.Context.ExecuteQuery()

return
$web.Webs.Count

    }

    if((getchildcount($web)) -gt
0)

    {

        $ch
=
$web.Webs

        foreach($c
in
$ch)

        {

            $WEB.Context.Load($C)

$web.Context.ExecuteQuery()

processWeb($c)

        }

    }

    return
$urls

}

 
 

 

$rootweb
=
$clientContext.Web

$clientContext.Load($rootweb)

$clientContext.ExecuteQuery()

 

#This command may take some time to complete – can be monitored using a tracing tool like Fiddler.

$subwebURLs
=
processWeb($rootweb)

 

#Displaying the list of SPWeb URLs as a result.

$subwebURLs