Provisioning site collections with CSOM in SharePoint 2016

Since field is more and more adopting SharePoint 2016, have started received more and more questions on how to enable site collection creation using CSOM with SharePoint 2016. Back in 2014, I wrote a blog post on how to make this happen with SharePoint 2013, since it requires some server side configurations, but there are small differences on this with SharePoint 2016 platform.

To make things easy, we have provided needed script for SharePoint 2013 and SharePoint 2016 from the SharePoint Patterns and Practices initiative under the PnP-Tools repository in GitHub. You can find direct link to these scripts below. You’ll find different scripts for SP2013 (15) and SP2016 (16) for enabling the CSOM client callable proxy in your farm.

Let’s walk through the steps to enable this using these scripts one-by-one.

Enable Server Stub for site collection creation

When you install SharePoint 2016, we do not unfortunately enable this assembly for the CSOM, so we’ll need to explicitly enable the server side support for the tenant assembly, so that when we are using CSOM remotely, SharePoint knows which assembly is responsible for handling the request in server side. If you don’t do this, you’ll get following exception in the CSOM side when you use the APIs.

 
[sourcecode language='text'  padlinenumbers='true' wraplines='true']
{"Cannot find stub for type with id \"{268004ae-ef6b-4e9b-8425-127220d84719}\". The specified server may not support APIs used in this operation."}

 

You can enable the server side stub by using the allowtenantapiv16.ps1 script from the GitHub. You will need to do this only once in the farm with the farm administrative permissions, since we are modifying the SharePoint web application settings to enable this. If you have multiple web applications, you will need to be repeating this cross all of those where you want this capability to be enabled.

 
[sourcecode language='powershell'  wraplines='true']
param
(
[Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()]
    [String]$WebApplicationUrl
)
#
# Enable the remote site collection creation for on-prem in web application level
# If this is not done, unknon object exception is raised by the CSOM code
#
$snapin = Get-PSSnapin | Where-Object {$_.Name -eq 'Microsoft.SharePoint.Powershell'}
if ($snapin -eq $null) 
{
    Write-Host "Loading SharePoint Powershell Snapin"
    Add-PSSnapin "Microsoft.SharePoint.Powershell"
}    
 
$webapp=Get-SPWebApplication $WebApplicationUrl
$newProxyLibrary = New-Object "Microsoft.SharePoint.Administration.SPClientCallableProxyLibrary"
$newProxyLibrary.AssemblyName = "Microsoft.Online.SharePoint.Dedicated.TenantAdmin.ServerStub, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
$newProxyLibrary.SupportAppAuthentication = $true
$webapp.ClientCallableSettings.ProxyLibraries.Add($newProxyLibrary)
$webapp.SelfServiceSiteCreationEnabled=$true
$webapp.Update()
Write-Host "Successfully added TenantAdmin ServerStub to ClientCallableProxyLibrary for web application" $WebApplicationUrl
# Reset the memory of the web application
Write-Host "IISReset..."    
Restart-Service W3SVC,WAS -force
Write-Host "IISReset complete on this server, remember other servers in farm as well." 

Here’s what the script does in practice

  1. Load SharePoint PowerShell module
  2. Connect to SharePoint web application provided as parameter for the script
  3. Add TenantAdmin assembly as known assembly for the client callable proxies – this will include the needed mapping with the CSOM methods and the actual assembly performing the operation in server side
  4. Enable self service site collection for the web application, so that we can perform site collection creations remotely

You might be thinking on why didn’t we perform these needed steps by default with the installation, which is a fair question without clear answer. This operation is though fully supported and absolutely something what can be performed in the farm.

Set one of the existing site collections as tenant admin site

This could be slightly confusing step, but it’s required even though you would not use multi-tenant features in on-premises. You can consider this as a “feature” of this API, but it’s actually due the fact that the API used for site collection creation or the tenant admin assembly is directly ported from the SharePoint Online and the code still has some historical leftovers from the past (yes – it shouldn’t, but it does).

So – to make this API work in the on-premises, you’ll need to mark one of your site collections as tenant admin site collection. This could sound much more terrifying that what it actually means. In practice, you’ll need to chose the site collection, which will be used when you call the API to create new site collections and flip one property on that site collection, which does not have any other impact in on-premises. From consistency perspective, I’d create either specific empty site collection for this operation or use the root site collection of web application. Both are absolutely valid options. Here’s the code to perform this in practice from definetenantadminsite.ps1.

 
[sourcecode language='powershell' ]
param
(
[Parameter(Mandatory=$true)][ValidateNotNullOrEmpty()]
    [String]$siteColUrl
)
#
# Set admin site type property to the site collection using PS for any site collection type.
# This is needed to be set for the site collection which is used as the 
# "Connection point" for the CSOM when site collections are created in on-prem
#
  
$snapin = Get-PSSnapin | Where-Object {$_.Name -eq 'Microsoft.SharePoint.Powershell'}
if ($snapin -eq $null) 
{
    Write-Host "Loading SharePoint Powershell Snapin"
    Add-PSSnapin "Microsoft.SharePoint.Powershell"
}
 
$site = get-spsite -Identity $siteColUrl
$site.AdministrationSiteType = [Microsoft.SharePoint.SPAdministrationSiteType]::TenantAdministration

Write-Host "Site $siteColUrl set to AdministrationSiteType" $site.AdministrationSiteType

After this step, you’ll be then good to and start provisioning site collections in SharePoint 2016 with CSOM. Needed code is exactly the same as shown in the SP2013 version of this blog post, so you can copy that from there. Notice that you’ll need to connect to the site collection URL, which you marked as your “tenant admin” site collection for the operations.

 

“Sharing is caring!”