SharePoint Online and Private CDN

Hello All,

Recently was working with a customer and Private CDN's, when the customer mentioned how awesome it would be if it was simple for end users to use...well poooof that feature just recently hit GA.

The feature will sync your document library to the Private CDN and replace the library URL with the CDN url. While it has a few caveats I think you will find this to work very well and will improve page load time as static objects are replicated across the CDN network.  If you want to see a video of this, please see the article.

Caveats:

  1. If you look at the url of the Asset thru IE it looks like it is coming from the Document Library while in reality it is coming from the CDN.  You need to use Network monitor or other browser (I used Chrome) to see the true URL.
  2. By default not all Document libraries are syncing with the Private CDN (We can change this)
  3. By default not all file extensions are syncind with Private CDN (We can change this)
  4. You need to provide time between upload and use of file, as well as configuration and upload (Approx 15 mins should be enough)
  5. Only works with Publishing sites

How to implement:

If not already done enable private CDN for your tenant, by connecting to your tenant and running this PowerShell command Set-SPOTenantCdnEnabled -CdnType Private -Enable $True

NOTE: This enables the following locations */UserPhoto.aspx, and */Siteassets in all sites to be origins (An Origin is a location that will be synched with Private CDN).  As well you will have to run 'Get-SPOTenantCdnOrigins -CdnType Private' till you see that Origins no longer say 'Configuration Pending' before you can use origins (Approx 15 mins)

By default the following extensions are synched GIF,ICO,JPEG,JPG,JS,PNG (You can see this by running the command Get-SPOTenantCdnPolicies -CdnType Private) if you want other file extensions to be synched then you need to add them by running the following PowerShell Command Set-SPOTenantCdnPolicy -PolicyType IncludeFileExtensions -PolicyValue "GIF,ICO,JPEG,JPG,JS,PNG,DOCX"  -CdnType Private (This will add docx extension to list)

NOTE: When adding extensions you are replacing the value so include ALL extensions that you want to sync.

To add an origin you need to run the following PowerShell cmdlet Add-SPOTenantCdnOrigin -CdnType Private -OriginUrl sites/cdn/cdn, this would enable the cdn library in cdn Site Collection as an origin.

NOTE: Library must exist before you run the command or you will get an error.

 

Realizing that you may have other Document Libraries that you want to enable as origins, we should look to PowerShell.  Here are two examples of what we could do.

Executing this command will create origins of all libraries with the relative url of /photo, because of the use of the wildcard

Add-SPOTenantCdnOrigin -CdnType Private -OriginUrl */photo

Executing this script will create origins of all libraries with a type of Document Library or AssetLibrary, this could be modified to work with other queries if you have a different idea

 $TenantAdminUrl = "https://christwe-admin.sharepoint.com"
$ReplicatedBaseTemplate = @("851","101")     #https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.client.listtemplatetype.aspx, https://www.codeproject.com/articles/765404/list-of-sharepoint-lists-basetemplatetype

$Creds = Get-Credential
Connect-SPOService -url $TenantAdminUrl -Credential $Creds

Get-SPOSite | where {$_.Template -like "*PUBLISHING*"} | ForEach-Object {
    $context = New-Object Microsoft.SharePoint.Client.ClientContext($_.Url)
    $context.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Creds.UserName, $Creds.Password)
    $web = $context.Web
    $lists = $web.Lists
    $context.Load($web)
    $context.Load($lists)
    $context.ExecuteQuery()

    #Must filter on Basetype = DocumentLibrary to insure we don't try to sync a list by accident
    $Lists | where {$_.BaseType -eq "DocumentLibrary"} | ForEach-Object {
        if($ReplicatedBaseTemplate -contains $_.BaseTemplate)
        {
            $ListFolder = $_.RootFolder
            $context.Load($ListFolder)
            $context.ExecuteQuery()
            $LibUrl = $ListFolder.ServerRelativeUrl
            Add-SPOTenantCdnOrigin -CdnType Private -OriginUrl $liburl -Confirm:$false
        }
    }
}
Disconnect-SPOService