Create subsites in SharePoint Online with CSOM


Often, when we are engaged with new Office 365/SharePoint Online projects, we may have to create hundreds of subsites within a site collection. unfortunately, we still do not have PowerShell Cmdlets to create SharePoint webs, and we can only create SharePoint Online Site Collections using the New-SPOSite Cmdlet. However, it is definitely possible to create your subsites remotely on your SharePoint Online tenant using CSOM.

To make it more efficient, we are going to create an XML file, store all the subsites info in it, then read the XML file from CSOM to populate your Site Collection structure.

The script below describes all the steps you need to automate your SharePoint Online Site Collection.

XML File

First, let's create a new XML file and call it contoso.xml. The XML will have the URL of the Site Collection and the webs to be created within it (technically you can use the same XML to create multi level subwebs). The file will look like this:

<?xml version="1.0" encoding="UTF-8"?>
<Webs>
<Web>
<Url>https://contoso.sharepoint.com/sites/<Site Collection></Url> 
 <Sites>
  <Site>
   <Name>Site1</Name>
   <Title>Title 1</Title>
  </Site>
  <Site>
   <Name>Site2</Name>
   <Title>Title 2</Title>
  </Site> </Sites> 
</Web>
</Webs>

You can download a sample of the XML document here: contoso.xml

CSOM Code

There are few steps you need to take to get the CSOM code.

First, you need to add references to your SharePoint client assemblies.

Add-Type -Path (Resolve-Path "C:\CreatePublishingSite\Microsoft.SharePoint.Client.dll")
Add-Type -Path (Resolve-Path "C:\CreatePublishingSite\Microsoft.SharePoint.Client.Runtime.dll")
Add-Type -Path (Resolve-Path "C:\CreatePublishingSite\Microsoft.SharePoint.Client.Publishing.dll")

Second, you need to authenticate to your SharePoint Online tenant and load your XML file:

$userName = "[email protected]"
$pwd = Read-Host -AsSecureString "Please enter your password"

Third, loop through the file and create the sites:

[XML]$Import = Get-Content "C:\CreatePublishingSite\PageList-min.xml" 

Foreach ($objWeb in $Import.Webs.Web)
    {      

    Write-Host $objWeb.Url -BackgroundColor Green

    $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($objWeb.Url)
    $ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($userName, $pwd)

    if (!$ctx.ServerObjectIsNull.Value)
    {
        Write-Host "Connected to SharePoint Online site: '$siteUrl'……" -ForegroundColor Green   
    }
    else
    {
        Write-Host "Could not connect to SharePoint Online site: '$siteUrl'" -ForegroundColor Yellow
    }

    $rootWeb = $ctx.Site.RootWeb
            $ctx.Load($rootWeb)
            $ctx.ExecuteQuery()
   
    $groups = $rootWeb.SiteGroups
            $ctx.Load($groups)
            $ctx.ExecuteQuery()

    Foreach ($objSubWeb in $objWeb.Sites.Site)
        {
                       
            Write-Host "Creating Sub Site…." $objSubWeb.Title -ForegroundColor Yellow
            $WCI = New-Object Microsoft.SharePoint.Client.WebCreationInformation
            $WCI.WebTemplate = "CMSPUBLISHING#0"
            #$WCI.Description = "SubSite"
            $WCI.Title = $objSubWeb.Title
            $WCI.Url = $objSubWeb.Name.Replace(" ", "-")
            $WCI.Language = "1033"
           
            $subWeb = $ctx.Web.Webs.Add($WCI)       
            $subWeb.BreakRoleInheritance($false, $false);         
            $subWeb.Update() 
            $ctx.Load($subWeb)
            $ctx.ExecuteQuery()
           

            Write-Host "Sub Site Created…." -ForegroundColor Yellow
            }      
    }