SharePoint Automation Gary Lapointe – Founding Partner, Aptillon, Inc.

22Dec/1155

Updating SharePoint 2010 User Information

One of my clients recently had an issue where a particularly high profile user (CEO) had their title spelled incorrectly in Active Directory; unfortunately the error wasn’t noticed right away and now, despite changing the information in Active Directory, SharePoint was still showing the wrong title in the People Picker when granting the user rights to a Site Collection. Fortunately I had a partial PowerShell script to fix the issue and just needed to only slightly modify it – you can see the original script on pages 299 and 300 of my book. So before I show the modified script it’s first important to understand the problem and why I needed to use a script and why what I had in the book is somewhat incomplete.

Whenever you grant a user rights to a Site Collection or when that user creates/updates/deletes any item within a Site Collection, an entry for the user will be added to a hidden user information list, if not already there. This “User Information List” is located at http://<SiteCollectionUrl>/_catalogs/users/detail.aspx:

SNAGHTMLa064e71

By looking at this list you can see that several key pieces of information are stored here – unfortunately, when you change this information in Active Directory the information stored here is not updated (even after running a full or incremental import via UPS). To complicate matters there is no way to edit the information via the browser, thus the need for a PowerShell script. If you click the user’s name you’ll see the additional properties, including an “Edit Item” option, however, the edit dialog is simply a read-only display of the username, helpful right?:

SNAGHTMLa089b49

So let’s first consider the scenario that my book addresses and assume that a user had had their name and/or email address changed. To accommodate this scenario we simply use the Set-SPUser cmdlet along with the -SyncFromAD parameter. The following script is taken directly from my book and simply iterates through all Site Collections and calls the Set-SPUser cmdlet for the provided user:

function Sync-SPUser([string]$userName) {
  Get-SPSite -Limit All | foreach {
    $web = $_.RootWeb
    if ($_.WebApplication.UseClaimsAuthentication) {
      $claim = New-SPClaimsPrincipal $userName -IdentityType WindowsSamAccountName
      $user = $web | Get-SPUser -Identity $claim -ErrorAction SilentlyContinue
    } else {
      $user = $web | Get-SPUser -Identity $userName -ErrorAction SilentlyContinue
    }
    if ($user -ne $null) {
      $web | Set-SPUser -Identity $user -SyncFromAD
    }
    $web.Dispose()
    $_.Dispose()
  }
}

 

Before I make any changes to demonstrate this script and the modifications we’ll make to it, let’s first see how my user is currently set in the Site Collection:

image

And as shown in the People Picker:

SNAGHTMLa14e91b

Note the “Name”/”Display Name”, “Work e-mail”/”E-Mail”, and “Title” fields.

Now I’ll change these values in Active Directory (make the “p” in my last name capitalized, change the title, and set the email) and then run the script (I saved the script as Sync-SPUser.ps1):

SNAGHTMLa17239b

(Note that lowercase “p” is the correct spelling for my name, just in case you were wondering Smile). Now if we look at the user details in the Site Collection and the People Picker we should see the following:

image

SNAGHTMLa1a344d

Notice that the the “Name” / “Display Name” and “Work e-mail” / “E-Mail” fields were updated but not the “Title” field. This is because the Set-SPUser cmdlet and -SyncFromAD parameter only updates these two fields. So how do you update the remaining fields? We simply need to add some code to our function which will grab the SPListItem corresponding to the user from the hidden “User Information List” and then update the corresponding fields manually. The following modified script does this for the “Title” field (note that I’ve changed the function signature to take the title in as a parameter):

function Sync-SPUser([string]$userName, [string]$title) {
  Get-SPSite -Limit All | foreach {
    $web = $_.RootWeb
    if ($_.WebApplication.UseClaimsAuthentication) {
      $claim = New-SPClaimsPrincipal $userName -IdentityType WindowsSamAccountName
      $user = $web | Get-SPUser -Identity $claim -ErrorAction SilentlyContinue
    } else {
      $user = $web | Get-SPUser -Identity $userName -ErrorAction SilentlyContinue
    }
    if ($user -ne $null) {
      $web | Set-SPUser -Identity $user -SyncFromAD
      
      $list = $web.Lists["User Information List"]
      $query = New-Object Microsoft.SharePoint.SPQuery
      $query.Query = "<Where><Eq><FieldRef Name='Name' /><Value Type='Text'>$userName</Value></Eq></Where>"
      foreach ($item in $list.GetItems($query)) {
        $item["JobTitle"] = $title
        $item.SystemUpdate()
      }
    }
    $web.Dispose()
    $_.Dispose()
  }
}

The changes to the original function have been highlighted. Note that the internal field name for the “Title” field is “JobTitle” and that is what we are using to set the Title. Now if we run this modified script we should see the Title field updated:

SNAGHTMLa21bc70

SNAGHTMLa236af7

Okay, so what about the other fields (Department, Mobile Number, etc.)? You can see what fields are available to edit by running the following:

SNAGHTMLa265249

In the preceding example I’m grabbing a specific item (in this case the item corresponding to my user) so that I can see the internal field names in context with the data stored by the field – this helps to make sure that I grab the correct field name (i.e., “JobTitle” vs. “Title”). Now you can just add additional fields to update right before the call to SystemUpdate() – simply follow the pattern established for the title field.

So, add this guy to your script library and you’ll be good to go next time someone changes their name, email, or job title.

-Gary

Comments (55) Trackbacks (3)
  1. There exist a Job called “User Profile Service Application – User Profile to SharePoint Full Synchronization” which runs every hour by default. According to the description of this job, I’m guessing it’s doing exactly what you describe above.

    • Yes, you are correct and I should have pointed that out in the post. Unfortunately the job was not working for the client and I’ve yet to be able to see it work in any environment I’ve ever looked at – though I know others have had success with it.

    • This job doesn’t work in our envoronment. I spent 2 days to resolve this problem without success until I found this article and this script. So thanks Gary for help!

    • But this service is missing in sharepoint foundation 2013

  2. In some cases we can use third-party web-parts that allows users to update their AD and SharePoint details.
    For example HarePoint Self Service even alows to upload profile pictures:
    http://www.harepoint.com/Products/HarePointSelfService/Default.aspx

  3. I want to thank you for this article. I had a problem where a user was added to a site collection and then the user’s name was changed. I didn’t know about the -SyncFromAD switch. This was a huge help!

  4. Nice article Gary. However, I’m not seeing this issue in my farm. As long as the user is “active” on the site, changes are being pushed correctly from the Profile DB to the site (per the timer job mentioned above). If the user isn’t “active”, meaning they have only visited the site but haven’t done anything, changes aren’t pushed.

    • Well, like I said, I’ve just not had luck with that timer job though I know it’s supposed to work. The other thing I failed to mention is that of course if you are running Foundation that timer job won’t exist so there’s no automatic syncing (this is what that -SyncFromAD parameter is really for – Foundation users – I’ve just not had luck with the timer job so this approach works well when I need it). So, if the timer does what you need then fantastic – if not then hopefully this post will help you out :)

  5. I’m fairly new to SharePoint, and had this same problem. I had a user who had access to the site via AD group permissions. I searched for a solution like this, but being new to SharePoint I ended up manually adding the user to the site with read access, then removing the user (again, allowing her AD permissions to take over). This seemed to re-sync AD and the user information list.

    • In the beginnin we had aboud 80% of the names swnhiog domain/user. the other 20% was swnhiog full name.After running the mentioned script Get-SPUser –Web | Set-SPUser –SyncFromAD all usernames are swnhiog up as full names. But after a couple of minutes the usernames are changed back to domain/user.How to fix this problem forever?

  6. One more idea, we can simply delete the Corresponding User profile from site collection. On his next login the AD information is automatically updated in User Information list.

  7. Great post. I have tried to run the script (the second one) and it failed. I did not modify the script, just copied and pasted it. Any ideas? Here is the one of the errors lines:

    You cannot call a method on a null-valued expression.
    At C:\Users\yassar\Syn-SPUser2.ps1:16 char:39
    + foreach ($item in $list.GetItems <<<< ($query)) {
    + CategoryInfo : InvalidOperation: (GetItems:String) [], RuntimeE
    xception
    + FullyQualifiedErrorId : InvokeMethodOnNull

  8. Nice posting Gray!

    We are also having the same issue. Unfortunately for us “User Profile Service Application – User Profile to SharePoint Full Synchronization” job is not successful. (for the users who are already included in UIL)

    For those who are not much familiar with scripting, as Central administrator you might use the direct edit of specific user information. Refer below.

    Central Administration >> Application Management >> Manage Service Applications >> Click on ‘User Profile Service Application’ >> Under People Click on ‘Manage User Profiles’ >> Find Profile – Enter Name – Click ‘Find’ >> in the search result – Edit the selected user profile and Save.

  9. Thank you for your site.Really thanks! Fantastic.

  10. Hi gary,

    I’m using two methods to update this kind of info:
    1 – automatic script like you mentioned (visual studio console app)
    2- Visual console app which makes the user information list fields updatable by setting them to readonly = false. this way the users can update their info themselves. for this method to work you need to give them the permission role SPbasePermissions.EditMyUserInfo. The field are hidden and made readyonly if you are using sharepoint server (on first run of the user profile full sync job). they are updatable and visible if you are using Sharepoint foundation only. you can show/hide/edit more fields if you want when using server or foundation of course. The full sycn job does not change them them to hidden or readonly.

    Cheers !

  11. When running the script, im getting this error:

    The ‘=’ operator failed: Access to this Web site has been blocked.
    Please contact the administrator to resolve this problem..
    At line:8 char:14
    + $user = <<<< $web | Get-SPUser -Identity $userName -ErrorAction SilentlyContinue
    + CategoryInfo : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : OperatorFailed

    Does the script run through all my farm application? I should have site administrator right on all of them, but if I ny mistake dont, would I then get this error?

    • It iterates through every web in the Farm unless you’ve modified it so yeah, you’d get this error if a site was marked as locked or read-only or if you didn’t have access to the site.

      • Unfortunately I’m having the same issue, but haven’t been able to figure out where the permissions aren’t set accordingly.

  12. Hi Gary,

    ITs not working for me … Not throwing any error also. does this require iisreset or server reboot. Please let me know

  13. This worked great. Much appreciated!

  14. Hi Gary, great description, but what I’m really interested in is the cause, why the synchronization job does not pull the information from Profile DB. I’m talking about ENT version with UPS enabled.
    The problem is not to get information from AD to UPS, the problem is to push information into ContentDB. Even the job is manually ran, the information are not updated.

    Do you know the cause?
    Thank you, Jakub

    • A users information is stored in the hidden users list (~site/_catalogs/users); this information gets added under various circumstances (can’t remember them all). In the database there’s a field which effectively classifies the record as one that should be synchronized (has to do with whether or not the user has contributed in some way). If it’s not classified as one that should be synchronized then it won’t get updated. It’s something Microsoft did to improve the performance of the system but has introduced this unfortunately consequence.

  15. This script is exactly what I’m looking for, but I can’t manage to run it. This is the error I get repeatedly:

    The ‘=’ operator failed : specified file not found. (Exception de HRESULT : 0×80070002).
    C:\Sync-SPUser.ps1 : 8 Character : 14
    + $user = <<<< $web | Get-SPUser -Identity $userName -ErrorAction SilentlyContinue
    + CategoryInfo : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : OperatorFailed

    I run it using the farm admin account, and it gives me the same result with all users, unfortunately.
    Any idea? Thanks a lot in advance!

  16. Hi Garry,

    Thanks for nice post.

    I have issue in my sharepoint site. As in user profile when user deletes his picture.Then his picture in user group/ list shows broken image instead of displaying default picture.Any recommended solution for this problem would be great help.

    Thanks in advance,
    Gurudatt

  17. Hi, the previous comments are right, the “User profile to SharePoint full synchronisation” does this job.
    But it not works if you have some dabase out of sync for some reason.

    You have to launch the following command to see the list of database whitch are out of sync (and the last date of sync):
    stsadm.exe -o sync -listolddatabases 0

    And then, launch this comment to delete the sync information:
    stsadm.exe -o sync -deleteolddatabases 0

    Then launch the “User profile to SharePoint full synchronisation” timer

    It will work nice again!

  18. Is it possible to add users en masse to this list? I.E. Can users be added to list ahead of time rather than once they access the site collection?

  19. Hello Gary, thank you for the information. Very useful post and well written.

  20. Hi,

    We have almost some issue but it is about a domain group not user. I have changed the name of the group in AD and removed the group form User Information List. now when I try to add same group. When can not find the group with new name it picks up the old name always. we have done full profile synchronization too.

  21. Just wanted to say thank you for this. I was able to combine your script information with the one found at http://sharepoint-geek.com/2011/07/27/sync-sharepoint-foundation-2010-user-profiles-to-ad-using-powershell/ to create a script that will pull all my users from active directory, check to see if they are in the user info list for each site collection, and then set several of their pieces of information (name, position title, department, even custom columns I added to the user information list) with the info from AD…sort of a one-way profile sync. Haven’t figured out how to pass the manager yet but thank you so much for providing this.

  22. I have tried to run the script, but get nothing. No output or prompting me to enter a user name. How do I update an individual user?

  23. I have created a script which syncs all of the properties in the User Information List to the User Profile Service
    It can be found here http://www.softlanding.ca/Blog/Lists/Posts/Post.aspx?ID=46

  24. hi and thanks . is it possible to write an Event Rec to handle this issue on UserInfoChanged event ?

    • I suppose you could attach an event receiver to the hidden user info list but you’d have to do this for all site collections so you’d need a stapler to apply it. Event receivers aren’t guaranteed to fire though so you may need a backup option.

  25. I am on an enterprise MOSS 2007 system. The process that syncs between the user profile and user list works most of the time with some exceptions. These exceptions are driving us crazy.

    When a user’s login account name changes , the resulting last name gets updated as expected. Changes to other fields, like department, etc. occur just fine.

    However, when the user’s login changes, a second field that the userlist displays – the account field – does not get updated.

    The result that we see are odd things such as
    1. InfoPath applications which sometimes fail ; it turns out the user’s account name differs from the login name, and infopath has difficulty establishing permissions, etc.
    2. Users which check out a document discover it is checked out to an old account of theirs – and then they are unable to edit the document, because it is checked out to “someone else”.

    If we could find all these users, we can update their userlist entry by adding the users to a sharepoint group on the site collection.

    However, it is hard with 1500 users to check each name to determine whether or not their account is current.

    I am just at the beginning of writing powershell. It appears to me that eventually I will be able to write something like this – something that would check each user in the userlist, comparing the login and the login portion of the account name to see if they match, and if not, check to see if the user’s login is active in AD, and if so, write out the login to a report.

    Can powershell do all these various things?

    Thank you.

    • You should be able to generate a report like this fairly easily. In general though I would recommend your IT folks put a stop to changing user names – it’s a bad practice no matter how you look at it and you’ll run into numerous issues (not just with SharePoint).

  26. I have a SharePoint 2010 list in which there is a Person or Group column of Name (with presence.) This column programmatically is provided a text of the username, it looks in the User Information List, and then it resolves. Out of thousands of usernames, it comes back blank for a few hundred users, even though they are listed in the User Information List. These are older users who were here before an upgrade from MOSS 2007 to SharePoint 2010, and I think something is not getting synced correctly in the User Information List. I want to delete their names from the User Information List and then start the User Profile Synchronization in hopes that this time the right user information gets in the User Information List.

    Can you just delete them from the User Information List by going to the List, clicking Modify View, add Edit to the list of columns? And then go back to the list, click Edit beside the user to be deleted, and then click Delete User form Site Collection?

  27. Hi.

    I am pretty new to sharepoint, but I was trying to update a user’s Job Title with the following scrpit.

    function Sync-SPUser([string]$userName, [string]$title) {
    Get-SPSite -Limit All | foreach {
    $web = $_.RootWeb
    if ($_.WebApplication.UseClaimsAuthentication) {
    $claim = New-SPClaimsPrincipal $userName -IdentityType WindowsSamAccountName
    $user = $web | Get-SPUser -Identity $claim -ErrorAction SilentlyContinue
    } else {
    $user = $web | Get-SPUser -Identity $userName -ErrorAction SilentlyContinue
    }
    if ($user -ne $null) {
    $web | Set-SPUser -Identity $user -SyncFromAD

    $list = $web.Lists["User Information List"]
    $query = New-Object Microsoft.SharePoint.SPQuery
    $query.Query = “$userName”
    foreach ($item in $list.GetItems($query)) {
    $item["JobTitle"] = $title
    $item.SystemUpdate()
    }
    }
    $web.Dispose()
    $_.Dispose()
    }
    }

    Then running Sync-SPUser “sccc\jsmith” “Operations”

    After the command completed, all my SharePoint users have the title “Operations Manager”

    Is there any possible way to “re-pull” Job Title from Active Directory back into Sharepoint.

    Thanks!

    • The post likely stripped what you used for the query command so I can comment on why it updated all users instead of just the one you provided. Most likely your where clause is incorrect and is pulling all users. To reset from what is in AD you’ll have to use something like the Get-ADUser cmdlet (http://technet.microsoft.com/en-us/library/hh852208.aspx) to get the user and pull their job title (or look in the user profile property for the user if you have the user profile service running).

  28. can you tell me, how can i sync department name from AD domain for one webapplication for particular user.
    where i need to mention siteurl ?

    the following function will work ???

    function Sync-SPUser([string]$userName, [string]$Department) {
    Get-SPSite -Limit All | foreach {
    $web = $_.RootWeb
    if ($_.WebApplication.UseClaimsAuthentication) {
    $claim = New-SPClaimsPrincipal $userName -IdentityType WindowsSamAccountName
    $user = $web | Get-SPUser -Identity $claim -ErrorAction SilentlyContinue
    } else {
    $user = $web | Get-SPUser -Identity $userName -ErrorAction SilentlyContinue
    }
    if ($user -ne $null) {
    $web | Set-SPUser -Identity $user -SyncFromAD

    $list = $web.Lists["User Information List"]
    $query = New-Object Microsoft.SharePoint.SPQuery
    $query.Query = “$userName”
    foreach ($item in $list.GetItems($query)) {
    $item["Department"] = $Department
    $item.SystemUpdate()
    }
    }
    $web.Dispose()
    $_.Dispose()
    }
    }

  29. Fantastic! Thanks for sharing this. Very useful!

  30. Thanks for the post. I tried something simpler, though. I had one user and I simply deleted them from the site collection and had them launch the SharePoint site and it their information was updated.

  31. We’ve been running into this same issue. However, our SharePoint instance is setup in a “resource” AD forest with a one-way trust between our primary AD and the SharePoint one. It was recommended we set it up this way because we’ve SharePoint site members that are not part of the organization. I’m wondering if this complicates the fix. I’ve tried your script, but it seems to fail on the execution of the -SyncFromAD. Any suggestions?

    Thanks!

    • I’ve never played with SharePoint in this configuration so not sure what might be the issue (wouldn’t be surprised if it’s permission related but that’s just a gutt feeling). If you can get the stack trace it might help to debug but I’d probably still just be guessing.

      • From the setup, I would assume the external users are created in the resource forest? If so, that means the sync from AD command needs to be run from an account in the resource forest. Otherwise, it will look for those users in a forest they don’t exist in and fail.

  32. I had this same issue and it was solved after I followed the steps stated in this blog:

    http://sharepointnotes.wordpress.com/2008/05/05/syncing-wss-and-moss-user-profile-properties-with-active-directory/

    it might work for you too! :)

  33. I’ve a similar problem but I can’t figure it out: One AD user got renamed (SamAccountname and display name) and when logged in to SharePoint, the display name on the top right corner would display the old name; if we tried to go to My Profile from the pull down menu, it would show the old profile, with the old display name and old username. I tried your solution and also a solution I found here (http://blog.uvm.edu/jgm/2013/04/04/coping-with-renamed-user-accounts-in-sharepoint/) and now I already get the correct display name, but, whenever we go to My Profile, although it shows the correct one, it changes the top right corner display name to the old one! Besides, if I, then, try to go to My Profile again, it gives an error, saying the profile doesn’t exist anymore!?!
    Can you shed some light, please?

    Sorry for the long text.

    TIA
    Américo

  34. Hi Gary, are you still available to provide some advice for this thread? I’m trying to achieve the simplest thing but just can’t find any information on how to do it.

    http://blog.falchionconsulting.com/index.php/2011/12/updating-sharepoint-2010-user-information

  35. I am a site collection administrator and am getting access denied error when running this

    The ‘=’ operator failed: Access is denied….
    at path\syncadusers.ps1:8 char 9

    any one have ideas


Leave a comment

CAPTCHA Image

*