Monthly Archives: June 2015

Looping through all subsites in SharePoint Online

SharePoint Online requires use of the Client Object model when modifying the site via PowerShell due to there being no backend server exposed in Office 365. Users with previous experience of using JavaScript Client Object model will find this a familiar method.

In the example below, the Powershell iterates through all subsites (and subsites of subsites) in a site collection or root site. This could be used for disabling a web scoped feature or automating site modification.

First of all, the variables are initiated including the path to the relevant DLLs.

#connection variables and reference DLL
$username = "user@onmicrosoft.com"
$password = "Password123"
$SiteCollectionUrl = "https://tonyishere.sharepoint.com"
Add-Type -Path "c:\Microsoft.SharePoint.Client.dll"

A new object for the client context requires creating, this can be done in a reusable function as shown below.

# Generate ClientContext function so we can reuse
function GetClientContext($SiteCollectionUrl, $username, $password) {
     $securePassword = ConvertTo-SecureString $password -AsPlainText -Force
     $context = New-Object Microsoft.SharePoint.Client.ClientContext($SiteCollectionUrl) 
     $credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($username, $securePassword) 
     $context.Credentials = $credentials
     return $context
}

The following function has a nested call to call itself, this enables it to iterate through subsites of subsites. Without the nested function call, it would only cover a single subsite depth. The function writes the url of the site to the screen but this could be replaced with more complex functionality such as enabling a feature or creating a list item.

# function to loop through subsites
function catchsubsites ($subsiteurl){
	$clientContext = GetClientContext $subsiteurl $username $password
	$rootWeb = $clientContext.Web
	$childWebs = $rootWeb.Webs
	$clientContext.Load($rootWeb)
	$clientContext.Load($childWebs)
	$clientContext.ExecuteQuery()
	#do something on top level site
	write-host $rootWeb.url -ForegroundColor Yellow
	foreach ($childWeb in $childWebs)
	{
		#do something for each subsite
		write-host $childWeb.url -ForegroundColor Yellow
		#see if there are any subsites beneath this and loop all of them too
		catchsubsites $childWeb.url
	}
}

Finally the function is called to kick off the whole process of looping through the site.

#Finally run the function to get it all started!
catchsubsites $SiteCollectionUrl

This example could be refined so that it doesn’t authenticate at every request but it does show how simple it can be to create the complex PowerShell scripts that we are all used to using on SharePoint on-premises in the cloud version of Microsoft’s Office 365 SharePoint Online.

Update: Code updated 01/10/2016, fixed variable in loop and added section to run code for parent site