Compartilhar via


SharePoint user profile properties now writable with CSOM

One of the highly requested capabilities for the SharePoint client side object model (CSOM) has been the capability to update user profile properties. This has been supported for remote operations using web services (UserProfileService.asmx), but since web service interfaces area already deprecated, having this capability natively in the CSOM has been frequently requested.

We have listened and are happy to announce native support for this in the Office 365, using the latest version of the CSOM package (3rd of Sep 2014 or newer). These required methods have been available for a while in the redistributable library and now the capability has been enabled also in service for each tenant. This means that you can start using these new capabilities in your Office 365 development immediately.

Introduction to new methods

Even though from functionality perspective this is huge, actual changes in the CSOM API are relatively simple. These new capabilities are available from the Microsoft.SharePoint.Client.UserProfiles.dll assembly (16 version targeted to cloud) and more precisely as follows.

  • Microsoft.SharePoint.Client.UserProfiles.PeopleManager::SetSingleValueProfileProperty()
  • Microsoft.SharePoint.Client.UserProfiles.PeopleManager::SetMultiValuedProfileProperty()

When this post was written, official documentation in MSDN had not yet been updated, but you will find the updated method signatures in the MSDN at some point. You can download the showed code from this blog post from the Office 365 Developer Patterns and Practices. See more details further down on this blog post.

You need to provide at least Write permission for the user profile service, so that the app will have the right oAuth permissions to perform the required actions, like in below picture.

image

Notice also that when we update the user profile properties, all typical user profile property configurations are still valid. This means for example that you will need to ensure that properties are marked to be editable in the user profile service application. You can access these settings from the SharePoint Admin CenterUser ProfilesManage User Properties – [property] – Edit – Edit Settings.

image

Updating single value property

Here’s a simple example on how to update single value property using these new methods in user profile CSOM. This code is updating the AboutMe property with the updated value.

    1: var spContext = SharePointContextProvider.Current.GetSharePointContext(Context);
    2:  
    3: using (var clientContext = spContext.CreateUserClientContextForSPHost())
    4: {
    5:     // Get the people manager instance for current context to get account name
    6:     PeopleManager peopleManager = new PeopleManager(clientContext);
    7:     PersonProperties personProperties = peopleManager.GetMyProperties();
    8:     clientContext.Load(personProperties, p => p.AccountName);
    9:     clientContext.ExecuteQuery();
   10:  
   11:     // Convert entry to html
   12:     string updatedValue = (txtAboutMe.Text).Replace(
   13:                                 Environment.NewLine, "<br />");
   14:  
   15:     // Update the AboutMe property for the user using account name from profile
   16:     peopleManager.SetSingleValueProfileProperty(
   17:                         personProperties.AccountName, "AboutMe", updatedValue);
   18:     clientContext.ExecuteQuery();
   19:  
   20: }

 

Updating multi-value property

Here’s a simple example on how to update multi-value property using these new methods in user profile CSOM. This sample is updating the SPS-Skills property with some new entries.

    1: var spContext = SharePointContextProvider.Current.GetSharePointContext(Context);
    2:  
    3: using (var clientContext = spContext.CreateUserClientContextForSPHost())
    4: {
    5:     // Get the people manager instance for current context to get account name
    6:     PeopleManager peopleManager = new PeopleManager(clientContext);
    7:     PersonProperties personProperties = peopleManager.GetMyProperties();
    8:     clientContext.Load(personProperties, p => p.AccountName);
    9:     clientContext.ExecuteQuery();
   10:  
   11:     // Collect values for profile update
   12:     List<string> skills = new List<string>();
   13:     for (int i = 0; i < lstSkills.Items.Count; i++)
   14:     {
   15:         skills.Add(lstSkills.Items[i].Value);
   16:     }
   17:  
   18:     // Update the SPS-Skills property for the user using account name from profile.
   19:     peopleManager.SetMultiValuedProfileProperty(
   20:                             personProperties.AccountName, "SPS-Skills", skills);
   21:     clientContext.ExecuteQuery();
   22:  
   23: }

 

What about just getting the property values?

Here’s also sample code for CSOM for getting user property values as a reference. This capability has been available for a quite a while, but just for a reference together with the update methods. This code is loading all the properties and outputting them to text box in provider hosted app.

    1: var spContext = SharePointContextProvider.Current.GetSharePointContext(Context);
    2:  
    3: using (var clientContext = spContext.CreateUserClientContextForSPHost())
    4: {
    5:     // Get the people manager instance and load current properties
    6:     PeopleManager peopleManager = new PeopleManager(clientContext);
    7:     PersonProperties personProperties = peopleManager.GetMyProperties();
    8:     clientContext.Load(personProperties);
    9:     clientContext.ExecuteQuery();
   10:  
   11:     // just to output what we have now to text box
   12:     txtProperties.Text = "";
   13:     foreach (var item in personProperties.UserProfileProperties)
   14:     {
   15:         txtProperties.Text += string.Format("{0} - {1}{2}", 
   16:                         item.Key, item.Value, Environment.NewLine);
   17:     }
   18: }

 

What about on-premises?

Right now this capability was released only to the Office 365 side, but we are actively listening input from the customers and partners for following other actions. You can still continue using user profile web service in the on-premises deployments. It’s important to notice that even though this web service is deprecated, it is still fully supported for on-premises deployments as well. This statement is also valid for Office 365 Dedicated customers (different service than typical Office 365).

Please use the Office Developer User Voice to provide your feedback on the needed capabilities. Having this capability now exposed through CSOM is good example of the changes which were introduced based on the feedback and input from the field (customers and partners).

 

Office 365 Developer Patterns and Practices

Office365PnPLogoRed_thumb1Techniques showed in this blog post are part of the UserProfile.Manipulation.CSOM sample in the Office 365 Developer Patterns and Practices guidance, which contains more than 80 samples and solutions demonstrating different patterns and practices related on the app model development together with additional documentation related on the app model techniques. We are already working on new versions of other samples which are using user profile capabilities and have been using the legacy web service interface.

Check the details directly from the GitHub project at https://aka.ms/OfficeDevPnP. Please join us on sharing patterns and practices for the community.

“From the community for the community” – “Sharing is caring”

Comments

  • Anonymous
    November 07, 2014
    Hi Vesa, First, great post and thank you for sharing.  Second, does this now allow UserA (someone in HR) to update UserB's (any employee) user profile properties or is it still the case that only UserA can edit UserA's properties.  I realize global admins can do as they like, but I often see that there's a need for some lower-level delegation of user profile property management.

  • Anonymous
    November 08, 2014
    Hi Vesa, is there any chance this will be supported on next CUs for On-Premises?

  • Anonymous
    November 09, 2014
    @Eric Skaggs I think you could do that with the App Only policy? Basically by giving the app permissions to modify user properties regardless of who the user is.

  • Anonymous
    November 10, 2014
    @Eric, I to update profiles using JSOM on hosted web with no luck. It says 'Access denied' and allows to update own properties only. But when I run it on SharePoint admin center (yourdomain-admin.sharepoint.com) it works and updates properties of other users. I'm not sure that suggestion of @Vardhaman about app permissions will work, but you can try. Anyway even if it works I'm not sure that SharePoint App Store will approve such app because they have strict policy about app permissions.

  • Anonymous
    November 16, 2014
    To update properties of other people you have to authenticate on admin center. Something like this: string URL = "https://mytenant-admin.sharepoint.com"; string adminUsername = "mysharepointadmin@mytenant.onmicrosoft.com"; string adminPassword = "mypassword" using (ClientContext context = new ClientContext(URL)) {      SecureString pass = new SecureString();      foreach (char c in adminPassword.ToCharArray())          pass.AppendChar(c);      context.Credentials = new SharePointOnlineCredentials(adminUsername, pass);     //follow the post here } It works fine for me.

  • Anonymous
    November 28, 2014
    Having to auth against the admin portal effectivly makes this API not suitable for apps in SPO as you cannot install the app there. Also tried to run with App-Only full permissions, but can still only edit your own user (after adding a UPA entry for the app user). All my nifty util ideas seems to run much better as console.exe than as apps :( I'm just about giving up on apps for small nice utils for now.

  • Anonymous
    December 01, 2014
    Please vote here if you want this on prem. officespdev.uservoice.com/.../6699586-userprofile-manipulation-csom-is-needed-on-premise

  • Anonymous
    December 04, 2014
    Possible bug....if I do the following with the latest SDK in PowerShell $pm = New-Object Microsoft.SharePoint.Client.UserProfiles.PeopleManager($clientContext) I get new-object : Cannot find an overload for "PeopleManager" and the argument count: "1". If I use an older version of the SDK, for example the ones in the 15 hive it works just fine. If I however use C# it works.

  • Anonymous
    December 04, 2014
    Forget about the last comment :) Seems a powershell issue

  • Anonymous
    December 09, 2014
    The peopleManager.setSingleValueProfileProperty  was working fine on SharePoint Hosted App to edit any user properties but since 1 week it is not working anymore. The App had UserProfile Full Control. Is there any alternative ? Thanks

  • Anonymous
    December 12, 2014
    If you update photo via this method in SP user profile db, does the photo ever end up in Azure AD thumbnailphoto attribute? If O365 dir sync is pushing users photo into Azure AD, what is the relationship between Azure photo and SharePoint user profile photo? Thx

  • Anonymous
    January 06, 2015
    I have tried to debug the app. The app installs but I am getting an error that the clientContext is null when I try to click the link to " learn more and test out scenario 2." From what I can see it looks as though the Page_PreInit class from the code behind on the default page is not running to check that the clientcontext is not null. Is there any fix for this?

  • Anonymous
    January 13, 2015
    Hi Vesa , I know it might be a basic question , but wanted to understand how / where to get Tenant information that displayed below , do we need to raise a request with fast help or some where we can get automatically. Because we have stared recently working on SP Apps and facing lot of issues in getting user profile properties like Manager , organization , company code etc. , the app is not enabling the Trust it option if we select User profile in permissions tab. string URL = "https://mytenant-admin.sharepoint.com"; string adminUsername = "mysharepointadmin@mytenant.onmicrosoft.com"; string adminPassword = "mypassword" Your help is most valuable.

  • Anonymous
    January 13, 2015
    Lot of comments which I unfortunately missed completely. Sorry for that. I would strongly recommend to use the Office 365 Developer Patterns and Practices group at the Office 365 network for any of these kind of questions. There's 1500 members already in that group with active support for these kind of questions.

  • aka.ms/officedevpnpyammer Quick comments on some of the things. You can update other persons properties as long as you point the connection to admin site collection and you have tenant permissions. This was similar as with the user profile web service. UPA changes in the Office 365 are not sync'd to Azure AD, so user profile photo would not be updated. Getting this to on-premises will be dependent on the requests to get it there... please use the user voice to vote on following if needed. This is official channel with weekly triage meetings which will impact on future resource alignment in our development - officespdev.uservoice.com/.../6699586-userprofile-manipulation-csom-is-needed-on-premise
  • Anonymous
    January 28, 2015
    I seem unable to find this method in the JSOM . When I called it I receive the error: peopleManager.SetSingleValueProfileProperty is not a function I am using the following code in SharePoint Online: myfunctions.fn.UpdateAboutMe = function () {    var scriptbase = _spPageContextInfo.webAbsoluteUrl + "/_layouts/15/";        $.getScript(scriptbase + "SP.js", function () {        $.getScript(scriptbase + "SP.Runtime.js", function () {            $.getScript(scriptbase + "SP.UserProfiles.js", function () {                var clientContext = new SP.ClientContext.get_current();                var peopleManager = new SP.UserProfiles.PeopleManager(clientContext);                userProfileProperties = peopleManager.getMyProperties();                clientContext.load(userProfileProperties);                clientContext.executeQueryAsync(silversands.fn.onRequestSuccess, onRequestFail);            });        });    }); } myfunctions.fn.onRequestSuccess = function() {    alert(userProfileProperties.get_userProfileProperties()['AboutMe']);    alert(userProfileProperties.get_userProfileProperties()['AccountName']);    var clientContext = new SP.ClientContext.get_current();    var peopleManager = new SP.UserProfiles.PeopleManager(clientContext);    peopleManager.SetSingleValueProfileProperty(userProfileProperties.get_userProfileProperties()['AccountName'], "AboutMe", "New About Me");    clientContext.executeQueryAsync(silversands.fn.onRequestSuccess, onRequestFail); } Is it not implemented yet in JSOM?

  • Anonymous
    February 27, 2015
    Hi Vesa, We are using a console application with CSOM  to update custom fields in the user profiles. This is working OK. Because we update thousands we get  sometimes a 503. Because of this we implemented in our code the ExecuteQueryWithExponentialRetry.  I assumed we would get a 429, do some sleep and after some incremental sleep time if that failed a 503. But we still get occasionally a 503 but never the 429. I would like some insight in how to interpret this behaviour.

  • Anonymous
    March 02, 2015
    Hi Peter, 503 is basically unexpected error and not directly related on the throttling. We are working on updated guidance for this one or working on right patterns to handle the exception with the engineering. Right now we do not have a story for that one and the automatic re-try would not work, since command queue will be cleared.

    • Anonymous
      June 08, 2017
      Hi, I'm using a Console Application with CSOM for SharePoint Online, but i can't found "SetSingleValueProfileProperty" method. I'm using Microsoft.SharePoint.Client.UserProfiles version 16.
  • Anonymous
    April 03, 2015
    @Keith Baron, I have got it working with almost exactly the same code: www.vrdmn.com/.../set-user-profile-properties-using-jsom.html Can you make sure if my code works for you? If not, then your tenant might not be yet updated with the latest CSOM APIs.

  • Anonymous
    April 15, 2015
    "You can update other persons properties as long as you point the connection to admin site collection and you have tenant permissions." This is true, but all I can retrieve then or update are Admin User Profiles  - why?

  • Anonymous
    June 04, 2015
    I have written a console app and referenced the O365 Client Dlls. I couldnt able to get the properties which has privacy settings "only to me" in the PersonProperties.UserProfileProperties disctionary . I have written code against the admin center. Please help.

  • Anonymous
    August 12, 2015
    Do you have a snippet code, for creating Custom Profile Properties..?

  • Anonymous
    August 12, 2015
    Hi RG, there's no remote APIs to create custom profile properties. For on-premises or for Office 365, you'd have to do this manually from the admin end user interface. If there's any additional questions or feedback, please use the Office 365 Developer Patterns and Practices Yammer group for those at aka.ms/OfficeDevPnPYammer. thx.

  • Anonymous
    September 01, 2015
    Hi Vesa! Great post, I was wondering if it is possible to create custom user properties using CSOM? Or SharePoint GUI is the only way? Thanks!

  • Anonymous
    September 01, 2015
    Hi Eliya, GUI is the only way for SharePoint online since there's no remote APIs to create or configure custom user properties, only for accessing their value is possible. In on-premises server side APIs is then the option. If there's any additional questions or feedback, please use the Office 365 Developer Patterns and Practices Yammer group for those at aka.ms/OfficeDevPnPYammer. thx.

  • Anonymous
    November 04, 2015
    Its nice article, Vesa. Thanks for your article.

  • Anonymous
    July 21, 2016
    Hey great Article, but I keep getting "Access denied. You do not have permission to perform this action or access this resource." when executing the SetSingleValueProfileProperty query.I am trying to do this from powershell.Can anyone chime in with any help?

    • Anonymous
      May 30, 2017
      you ever figure out the access denied?
  • Anonymous
    March 03, 2017
    I used to be suggested this blog by way of my cousin. I'm no longer certain whether or not this submit is written by way of him as nobody else recognise such precise about my problem. You are wonderful! Thanks!|

  • Anonymous
    June 22, 2017
    Hi Vesa,I would like to set some properties in User Profile with Taxonomy Terms, but the names are not unique, so when I would like to set it by name it finds randomly one Term by the Name and the rest is skipped.I found also this article, where it is detailed described : https://www.rickvanrousselt.com/setting-userprofile-properties-backed-term-sets-names/Are there any other options, how to set those terms correctly by Ids, or the same way as it is possible in OnPremise version?