SharePoint Online presents quite a compelling business case for most organizations. It offers a tremendous amount of features for a low cost and fewer headaches. However, many companies still need to keep an on-premises SharePoint farm for a variety of reasons, requiring them to deploy a hybrid topology. This type of configuration places some workloads in Office 365 and some on-premises (whichever is best suited for the job). Moving My Sites to Office 365 makes a tremendous amount of sense. For example, OneDrive for Business, the Office 365 equivalent of My Sites, offers users far more capacity than normally would be available on-premises. Users' personal storage is often the first to move to the Cloud.
The Challenge of User Profiles in a Hybrid Topology
Deploying a hybrid topology can greatly assist businesses and their users get full value out of both platforms, but it also presents some challenges. User Profiles and the whole Social story might be the thorniest of them all. User Profiles have been an important part of SharePoint for many years, and – love 'em or hate 'em –they're crucial to several workloads. For example, they're necessary for My Sites as well as for the SharePoint social features. When you engage in the social features, the data is stored with the user's profile. SharePoint User Profiles are not, however, part of the hybrid story. It is not possible for both SharePoint on-premises and SharePoint Online to share the same user profile and user profile data. This means that each is environment is its own profile island – and this can be very confusing for users.
When configuring Hybrid, we at Summit 7 usually recommend that customers choose one environment or the other to host User Profiles and Social. One would carry the workload and the other would have profile-dependent features disabled (such as social). It certainly is not ideal, but it can ease some significant pain. Since businesses normally want to take full advantage of OneDrive for Business, this means that SharePoint Online is usually chosen to own the User Profile and Social workloads. In fact, I have yet to see a customer choose otherwise.
If SharePoint Online is chosen as the owner of these workloads, it becomes necessary to configure the on-premises farm to send users away from the on-prem farm. This, however, can be very challenging. When a user clicks About Me up in the Suite Bar, or if they click on a person's name on a page, how do you send the user to the profile in SharePoint Online instead of on-premises? Let me show you how.
Here are the files you'll need:
User Profile Redirection
To send users to their cloud profiles, it is necessary to effectively configure SharePoint Online as a Trusted My Site Host. In order to do so and prevent errors when working with People on-premises, it is necessary to deploy a custom solution to act as a profile re-director.
Although simply changing the Trusted My Site Host will handle most of the configuration (as described in http://blogs.msdn.com/b/jvasil/archive/2013/12/04/using-an-office-365-sharepoint-online-hybrid-mysite-solution.aspx), some activities, such as clicking on a user's name in a list/library column, will generate a "User not found" error. This is due to the fact that SharePoint will attempt to make the call to SharePoint Online using the Windows user name "Domain\UserName" as the account name. SharePoint Online, however, is looking for the claims-encoded version (ex. i:firstname.lastname@example.org). To solve the issue, we need a custom page which will build the correct URL and redirect the user to it. I have created such a page and made its code available in this blog. The solution was developed based on the following posts/blogs, and it implements Smart Links:
I am very grateful to these individuals for their direction and their code.
I have developed a farm solution called S7Sys.ProfileRedirect.wsp to implement the custom page. It creates a new application page: /_layouts/15/S7Sys.ProfileRedirect/ProfileRedirect.aspx. This page is then set as both the My Site Host Location and as a Trusted Host Location. When a user hits the page, some configurations are pulled out of the farm, the User Principal Name (UPN) is pulled from their user profile, a URL is built, and the user is redirected to SharePoint Online's Person.aspx page (which then usually forwards to PersonImmersive.aspx). If the user clicked their own "About Me" link, they will be redirected to their profile in SharePoint Online. If they clicked on a person's name (like in a people picker field), they will be redirected to that person's profile page in SharePoint Online.
So there are three primary components to the solution:
- The definition of the object stored in the Hierarchical Object Store
- PowerShell to create/configure the object in the Hierarchical Object Store
- The application page which redirects the user to SharePoint Online's Person.aspx page
Configuration and the Hierarchical Object Store
The Hierarchical Object Store is basically the configuration database. Of course, we aren't allowed to modify the SharePoint configuration database directly. There is, however, a supported means to store structured objects in it via the API. It requires creating a class (in our case, S7Sys.ProfileRedirectConfig) which derives from Microsoft.SharePoint.Administration.SPPersistedObject. The class defines the properties available in the SPPersistedObject. The properties can then be set and read via the API. In this solution, we're creating an SPPersistedObject called "S7Sys.ProfileRedirect," and it contains the SharePoint Online My Site URL (https://[something]-my.sharepoint.com) and, optionally, the base URL for a Smart Link (see https://community.office365.com/en-us/w/sso/using-smart-links-or-idp-initiated-authentication-with-office-365 for more on Smart Links). We're storing the configuration in an SPPersistedObject so that we don't have to hardcode the URL in the C# code. We could have stored the URLs in any of the property bags or in a list, but since it's an application page and is thus accessible from any site in the farm, I feel it makes the best sense to store the configurations at the farm level.
Setting the Redirect Configuration
We use PowerShell to set or update the S7Sys.ProfileRedirect object. The code to do so is in ConfigureProfileRedirect.ps1 (the file is included in the Visual Studio project). Again, this object holds the configuration for the redirect page. Simply update the $mySiteBaseUrl variable with the URL for your SharePoint Online My Sites (https://[something]-my.sharepoint.com) and $smartLinkBaseUrl with the URL for a Smart Link (if you're using one). If you're not using Smart Links, just set the variable to an empty string ("").
The final custom element of the solution is the redirect page itself: ProfileRedirect.aspx. It's an application page that is deployed (along with S7Sys.ProfileRedirectConfig) via a farm solution (WSP). It provides the logic to build the redirect URL. SharePoint will automatically supply the AccountName and MySiteRedirect parameters (if needed) in the query string. The problem is that SharePoint sends the AccountName in its Windows authentication form (domain\UserName) instead of the claims format that SharePoint Online needs. So the page takes the AccountName passed to it, gets the user's UPN from their profile, and builds a new claims-encoded AccountName that SharePoint Online understands. It then builds the redirect URL using Person.aspx and the claims-encoded AccountName. The page also queries the Hierarchical Data Store to pull the configuration data and then uses those URLs to build the final redirect string.
In order to test and troubleshoot the page better, I added another parameter to the query string: Redirect. If you add "&redirect=0" to the URL, the page will not redirect but will instead output the redirect URL. This is very useful when testing your URLs and making sure your configurations are good. To use this, your URL would look like so:
Finally, if there are any errors on the page, the redirect will fail and display any messages on the page.
Deploying the Solution
In order to deploy our solution, we need to do the following:
- Deploy S7Sys.ProfileRedirect.wsp to the farm
- Update the variables in ConfigureProfileRedirect.ps1 and run the script
- In the User Profile service:
- Set the "My Site Host" URL
- Add a "My Site Trusted Host Location"
- Ensure that users have permissions to interact with profiles/social
Deploying the Farm Solution
To deploy the farm solution, copy S7Sys.ProfileRedirect.wsp to a farm server or a share accessible from the farm. In an elevated SharePoint 2013 Management Shell session (right-click, run as Administrator), run the following:
Install-SPSolution "S7Sys.ProfileRedirect.wsp" -GACDeployment
Note that, as with all farm solutions, there will be a brief interruption in service when the solution is deployed across the farm.
To configure the redirection URLs, open ConfigureProfileRedirect.ps1 in the PowerShell ISE (as Administrator). Alternatively, you can open it in any text editor and later run the script from a PowerShell prompt. Modify the $mySiteBaseUrl and $smartLinkBaseUrl variables as described earlier in this article. Once those variables are properly set, simply run the script to create the configuration object in the Hierarchical Object Store.
Note: The S7Sys.ProfileRedirect.wsp solution must be deployed to the farm before running the script or otherwise manipulating the S7Sys.ProfileRedirect.Config object.
Configure the User Profile Service
In Central Administration, go to your User Profile Service Application. We need to set the "My Site Host" URL and add a "My Site Trusted Host Location."
First, you need to know the URL for the redirect page. Since it's an application page, you can use any web application for the URL. The URL will be:
This URL will be used for both settings.
To set the "My Site Host" value:
- Click "Setup My Sites" in the "My Site Settings" section of the User Profile Service Application
- Update the "My Site Host" value to the ProfileRedirect.aspx URL above
- Click "OK"
Next, we need to add the URL as a "Trusted Host Location." To do so:
- Click "Configure Trusted Host Locations" in the "My Site Settings" section of the User Profile Service Application
- Click "New Link"
- In the "URL" field, enter the ProfileRedirect.aspx URL above
- Fill out the other fields as you like. The Target Audiences setting can be used to direct only a subset of users to SPO for their My Sites. Leaving the field empty will mean all users will be effected.
- Click "OK"
Finally, we need to make sure that users have permissions to interact with My Sites and the other social features in SharePoint (at least at a high level). I'll admit that I am not 100% sure of the permissions required. I believe that, at a minimum, users require "Create Personal Site" and "Use Tags and Notes." If they don't have the appropriate permissions, they will see "My Settings" in the dropdown on their names (in the Suite Bar), not "About Me."
To set permissions:
- Click "Manage User Permissions" in the "People" section of the User Profile Service Application
- Select each account (usually NT AUTHORITY\AUTHENTICATED USERS) and make sure at least "Create Personal Site" and "Use Tags and Notes" are checked.
- Click "OK"
That's it! You should now be all setup. If everything was properly deployed, users should be directed to their profile in SharePoint Online. The complete Visual Studio 2013 solution is attached to this blog. S7Sys.ProfileRedirect.wsp and ConfigureProfileRedirect.ps1 are also attached in case you don't want to muck about with the code and just want to run it. I really hope that this has been helpful. Feel free to post any questions or comments, and I'll do my best to respond. Thank you for reading!
A HUGE thank you to everyone who contributed to the links above (Eric Bowden, almaplayera, jvasilSP, David Ross, and the Office 365 community wiki)!
Editor's note: This blog is featured in the book "Microsoft SharePoint Online for Office 365 Administering and Configuring for the Cloud" - Kudos to everyone on our team who worked on this book. Check it out!
The sample scripts are not supported under any Summit 7 Systems standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Summit 7 Systems further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Summit 7 Systems, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Summit 7 Systems has been advised of the possibility of such damages.