Pre-populating OneDrive containers in an Education tenancy

Looks like I’ve been neglecting the blog a bit over the last few months, mainly due to being very busy a long migration project that has taken a lot of my time up. That said it has given me a lot of material to think about and potentially blog about too! The first aspect that I wanted to highlight was the differences between a standard E1/3/5 tenant compared to the equivalent Education tenant when it comes to SharePoint Profiles and by their symbiotic relationship, OneDrive containers.

Whenever I have worked on a large Office 365 implementation, we’ve always tried to pre-populate the OneDrive containers so that on launch day, we don’t have a large amount of people waiting for their OneDrives to provision. (In case you weren’t aware, the OneDrive container only gets provisioned when either a user clicks on the OneDrive link, or the profile is forced through code)

The way we’ve always approached this in the past is to let the AAD Sync process run to provision all of the users into Office 265/Azure AD then allow the SharePoint import wizard time to import the users and create profiles for them. We then have a PowerShell script that runs through the active profiles and checks the status of their personal site instantiation property. This shows whether the user is Unitialized (No site), Enqueued (awaiting creation), Created and a number of other useful states. (See here for the TechNet summary.) Our script then adds the unitialized users to a list for creation and these are added to the queue 100 users at a time (There’s a 200 user limit to the queue).

However in an Education tenancy, SharePoint only creates a profile for the user when they actually logon to SharePoint or OneDrive

The problem that we hit with the Education tenancy lies in the way that the SharePoint User Profile Sync works, which is different to the standard E subscriptions. Instead of importing users as they are added to Azure AD, SharePoint only creates a profile for the user when they actually logon to SharePoint or OneDrive. I’m assuming that this is to reduce the load on Microsoft’s own servers as education tenancies by their very nature generally have a lot of users in them.

With this in mind you can see that the usual approach of walking the User Profile store to find those users that don’t have a personal site instantiated isn’t going to work, but after a bit of digging I came across the ProfileLoader object which also contains the CreatePersonalSiteEnqueueBulk() method that we use in the other script. This particular object doesn’t need an active profile to begin with, and the act of queuing the user for personal site creation forces the creation of their profile and the subsequent OneDrive container. (On a side note, I did try using SPWeb.EnsureUser() to add a user to a site which it does, but this does NOT trigger the profile creation!)

Here’s the basic steps you need to connect to your Admin site and create a single user, I’ll leave it to you to adapt the script as you need.



# Specifies the URL for your organization's SPO admin service
$AdminURI = ""

# Specifies the User account for an Office 365 global admin in your organization
$AdminAccount = ""
    $AdminCredentials = get-credential -UserName $adminAccount -Message "Input password for $AdminAccount"

# You'll need the Client DLLs (I put mine in the same location as the scripts)

Add-type -path .\Microsoft.SharePoint.Client.dll
Add-type -path .\Microsoft.SharePoint.Client.Runtime.dll
add-type -path .\Microsoft.SharePoint.Client.UserProfiles.dll

#Create a credentials object for SPO.
$spoCredentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($AdminCredentials.UserName,$AdminCredentials.Password)

# Add the path of the User Profile Service to the SPO admin URL, then create a new webservice proxy to access it
$proxyaddr = "$AdminURI/_vti_bin/UserProfileService.asmx?wsdl"
$UserProfileService= New-WebServiceProxy -Uri $proxyaddr -UseDefaultCredential False
$UserProfileService.Credentials = $spoCredentials

# Set variables for authentication cookies
$strAuthCookie = $spoCredentials.GetAuthenticationCookie($AdminURI)
$uri = New-Object System.Uri($AdminURI)
$container = New-Object System.Net.CookieContainer
$container.SetCookies($uri, $strAuthCookie)
$UserProfileService.CookieContainer = $container

$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($AdminURI)
$ctx.Credentials = $spoCredentials

$profileLoader = [Microsoft.SharePoint.Client.UserProfiles.ProfileLoader]::GetProfileLoader($ctx)

#With the profile loader in place we can request a user provisioning.
#Where username@upn is the User Principal Name of the user you want to add.
#This can be a string array with multiple UPNs to process.


Leave a Reply

Your email address will not be published.


This site uses Akismet to reduce spam. Learn how your comment data is processed.