SharePoint Profile Picture Import 1.3

Link to original post: https://adamsorenson.com/user-profile-picture-import-with-active-directory-import/

A new year, blog home, & version of the picture importer

I have just completed a migration to my new blog home here. This platform will give us a bit more flexibility with design and such. I have been working a many bugs that have been plaguing the profile picture import. I think I have a handle on the majority of the outstanding issues. The major bug we had was the terrible performance for larger pictures. This is now fixed since we don’t need to reset the variable. We are still using Active Directory Import(ADI) and able to do incremental.

New variable

There is one new variable to assist with the “LDAP Server Unavailable” issue. $DCorDomainName(line 20)
is set for a resolvable domain name(Netbios or FQDN) or a Domain Controller.

XML file will auto create

New logic in the script will create the DNLookup if it’s not present. There was another issue where existing users in AD would fail since the sAMAccountName property is not included with incremental syncs. This is resolved by doing a lookup by the DN and add them into the DNLookup.xml.

Download the new version here

39 thoughts on “SharePoint Profile Picture Import 1.3

  1. Will

    Thanks for a great script! I have a few thoughts / questions:

    1) I suppose the script can handle being scheduled repeatedly (I was thinking once a week, using Task Scheduler)? And will it then always do a full import, re-importing already imported photos? But maybe a full import every time is the only feasible way to do it, in case a user has changed their picture…

    2) It’s the $LDAPFilter that determines which AD-users should be processed, right? I’m not a script guru, but I tried to see if there’s logic for checking which users are actually imported to the UPSA already, and just querying the AD for images for those users?

    3) We have several UPSA:s, how do I direct the script to run against a specific one? Is it merely by setting $site to the correct My site host in question?

    4) Are there any “technical gains” in enabling $write2disk, or is it just for the convenience to be able to see the imported images?

    Thanks for any insights! 🙂

    1. Glad you’re able find some good usage for it.

      1.) I have a blog post up on how to set this up as a task. — SharePoint – Scheduling the Profile Picture Import Script
      This is the best way to schedule it. Since the script uses DirSync, this will create a cookie.bin file. The first time it runs it will be full pull from AD but will be incremental after that.

      2.) The default LDAP filter I put in the script is to find users that have a value in thumbnailPhoto and is also not disabled. After we pull these in, we only upload pictures that are in the UPA.

      3.) The $site should be the mysite host. I don’t know the reasoning behind having multiple UPAs but this will pull the default UPA that the site is consuming from. Also $site will the site collection we will be uploading the photos to.

      4.) This will cause a slight perf loss. I put it in there for troubleshooting or anything else you’d like to do with the pictures.

      –Adam

      1. Will

        Thanks a lot for your reply Adam!

        Great post, I had good timing with my scheduling question. 🙂 As the task should be run as the UPSA sync account, I should then obviously set $UseDifferentSvcAccount to “$false”?

        The script works well when I execute it manually, but I do have some problems, most likely with permissions, when running it as the sync account. It’s “Unable to get UserPhotos” (even though the folder exists) so I need to figure that one out…

        Oh, about multiple UPSA – we are basically running one environment for multiple customers, so we’re running multiple UPSA to get airtight separation.

        /W

        1. Will

          It works also as a scheduled task now – I must’ve been too tired when giving the sync account SPShellAdmin permissions the first time around, I had given permissions to the wrong account… X-)

          Thanks again, you rock! 🙂

  2. Anina

    Hi Adam,

    I used your script to import thumbnail photos to SharePoint and it works perfect. Only thing i noticed is the low resolution of the photos. Thumbnailphoto has 96x96pixel limitation and that when comes to sharepoint my profile picture, it looks blurred. Is there any work around for this?
    Thanks
    Anina

    1. Hi Anina,

      I’m glad the script is working for you.

      The quality of the picture is based on what is in Active Directory’s thumbnailphoto value. This is limited at 100 KB. SharePoint will create 3 versions of picture – small, medium, large.

      Small -> username_SThumb.jpg
      Medium -> username_MThumb.jpg
      Large -> username_LThumb.jpg

      You can run the script with $write2disk = $true to see what quality is coming from AD.

      1. Mohamed Almadany

        am getting the same issue the resolution is bad even with write2disk set to true, the file size doesnt exceed 2 KB on disk, is there a workaround for this

  3. I work for a Non for Profit organization and we cannot invest on a new VM to setup MIM 2016 and would really want to get he User photos from AD thumbnail attribute over to our local SharePoint site.

    Can anyone help me out with all steps from start to finish as I copied and pasted the script as is with changing the domain name and other attributes particular to my environment, but I am not sure what are the pre requisites to be setup before running the powershell script on the VM running SharePoint server 2016 as I realized just running the .ps script and changing attributes within the script failed for me.

  4. Rani

    Hi Adam,
    I’m running this script. It is working fine and uploading pictures. But I don’t see 3 sizes get uploaded. Does the script upload 3 sizes? I see the filename is partitionID_ user profileID.jpg, so I changed to the format in the mysite settings “username”. Now it is uploading with usename.jpg format, is this correct way of doing it and also, how to upload 3 sizes?

  5. Rani

    Hi Adam, my previous comment is not clear. I changed the filename in the script to follow the format in the mysite site name format which is username.jpg. (I didn’t change the format in the mysite settings)

    1. The last line of the script should be the one that creates the 3 thumbnails.

      Update-SPProfilePhotoStore -MySiteHostLocation $site -CreateThumbnailsForImportedPhotos $true

      Try running this outside the script to see if it’s failing.

      1. Rani

        Adam, thanks for the reply. I missed your reply before.
        I tried running with partition id , it is saving the picture in picture store with that partition id string, but no thumbnail pictures are created.
        I ran this command also outside the script, it didn’t give me any error. It ran.
        Update-SPProfilePhotoStore -MySiteHostLocation $site -CreateThumbnailsForImportedPhotos $true
        Have couple of questions.
        1.Does the partition ID have to be changed in the script?
        2.After running the above update command when will the thumbnail pictures be generated?

        1. Rani

          Adam,
          Creation of thumbnail pictures is working for me. The issue was I had 2 User profile service applications and the one associated with my site is different. I removed the other UPSA and pointed the mysite to correct UPS, it is now working. Thanks.

  6. Pingback: User Profile Picture Import with Active Directory Import(Dirsync) - Adventures of SharePoint OnPrem

  7. Florian

    Hi,

    first of all thanks for providing this script for importing pictures.
    When the photo in AD is changed for an already imported user, will a re-run of the script update the profile picture in SharePoint, too?

  8. Andy Rogers

    Hi Adam,
    This script is failing for me after the line
    $sam=Byte2DArrayToString -attr $dsam
    I get:
    Failed to create XML file
    Cannot index into a null array.

    If I delete the cookie file and run it works fiine.
    Any thoughts what is coming back null?

  9. Andy Rogers

    Hi Adam,
    There is a DNlookup.xml, but it is blank. That blank DNlookup.xml is dated 7/1, which is the last time there was a new user to update. Since 7/1, the log shows:

    Trying to get the Profile Pictures Folder
    Successfully loaded the Profile Pictures
    New upload started at 07/09/2021 22:31:17 for 0 users
    Summary: Upload completed at 07/09/2021 22:31:17(took 00:00:00.0156294). 0 users imported from AD. 0 errors. 0 user photos successfully uploaded.

  10. Jason Unruh

    Hey Adam, I’m having an issue with the script, after running the script I get the message below in the out.log file. but these profile is in our User Profile Service. So I’m not sure why it is telling us it can’t find the user.
    Also It is not downloading the pictures locally even when I set
    $write2disk = $true.

    Trying to get the Profile Pictures Folder
    Successfully loaded the Profile Pictures
    New upload started at 01/03/2022 11:50:39 for 106 users
    Could not find User Profile for i:0e.t|pingsts|******
    Could not find User Profile for i:0e.t|pingsts|******
    Could not find User Profile for i:0e.t|pingsts|******
    Could not find User Profile for i:0e.t|pingsts|******

    we are using our dedicated AD sync account that has rights, and I’m running the script from the server running User Profile Services.

    Thanks for your help

    1. HI Jason,

      This entry means we didn’t find a user profile that matched that name.
      The line we’re running this this:
      $UserProfile = $pm.GetUserProfile($username)

      Check in the User Profile service application to see if you have those user profiles sync’d with AD in that format of i:0e.t|pingsts|******

      Here is a test lines to see if you have the profiles and the account running the script doesn’t have permissions to the UPA:
      Change these two lines
      $site = Get-SpSite http://MySiteHostURL
      $username = “i:0e.t|pingsts|******”

      $context = Get-SPServiceContext($site)
      $pm = new-object Microsoft.Office.Server.UserProfiles.UserProfileManager($context, $true)
      $pm.GetUserProfile($username)

      This may come back as access denied which would need to add that account to the UPA in central admin as documented here: https://adamsorenson.com/sharepoint-scheduling-the-profile-picture-import-script/

  11. Jason Unruh

    Adam, thank you for your reply

    It turns out my User Profile service was not working as expected, Once I deleted and recreated the UPSA your script worked great. I will add that I had to give sharepoint permissions to my normal sync account that had previously only rights to active Directory. I gave it full control permissions of the UPSA service, made it shelladmin and gave the account full control of our MySiteHostURL. Adam thanks again for your post, this script avoids us from using MIM just for pictures.

  12. Christian Kelly

    Hi Jason,

    First off thanks for this great script.

    I have no issues when running the script manually with the “$UseDifferentSvcAccount = $true”. But I’ve gone through the steps in your other blog post to give the account the needed permission, and when I run it as a scheduled task I get the following. It’ s not clear what the error is. Do you have any ideas?

    Trying to get the Profile Pictures Folder
    Successfully loaded the Profile Pictures
    New upload started at 02/02/2022 01:00:36 for 1 users
    Uploading xDOMAIN\xUSER1
    xDOMAIN\xUSER1 did not upload
    Summary: Upload completed at 02/02/2022 01:00:37(took 00:00:01.2969085). 1 users imported from AD. 1 errors. 0 user photos successfully uploaded.

      1. Christian Kelly

        Sorry if I wasn’t clear. When I run the script with UseDifferentSvcAccount using account “xyz” it works. When use that xyz account as the schedule task (and with the script set UseDifferentSvcAccount $false) I get the above issue.

        Basically I can run the script using the account that I’m scheduling it with but only when it’s running as the schedule do I get that odd error.

        1. When using $UseDifferentSvcAccount, this will use a different account(xyz) to import the pictures from AD. The rest of the script will run in context of the user that is running PowerShell.exe. That account will need access to the UPA and the Content Database(Shell access).

          To fix this issue, give “xyz” account access to the Content Database that has the My Site Host Site Collection.

          $site = get-spsite “http://mysitehostURL”
          Add-SPShellAdmin -UserName contoso\xyz -database $site.ContentDatabase

          https://adamsorenson.com/sharepoint-scheduling-the-profile-picture-import-script/

          1. Tony

            Hi Adam, I’m having the same issue as Christian above getting it to run as a scheduled task.

            I’m logging in to the Sharepoint App server as SPInstall.

            If I run the script manually via Powershell ISE with useDifferentSvcAccount $true and use our ProfileSyncAccount it works.

            When creating the scheduled task, the owner is SPInstall but is run under SPProfileSync. The script runs but with errors as per Christian above.

            I have given SPProfileSync and SPInstall shell access.

            Any ideas on what it could be? I’ve noticed that when it fails and I’ve set it to write the pictures it doesn’t download them. I’m wondering is that a clue? Almost as if the Profile sync doesn’t have enough rights on the server to do so.

          2. useDifferentSvcAccount is not going to work with scheduled tasks since it prompts for credentials to use.

            I would suggest using the service account that is used in Connection for the user profile sync.

  13. Szabolcs Géczi

    Hi Adam,

    thanks for the script it works well except the quality of the pictures :/ The user saved self from his outlook profile and it has a normal size not the 2-7kb what we can extract from the AD with help of your script.
    Is there any chance to get better quality?

  14. Rani

    The script is working good, but I have one question related to re-add of the user profileds with a different account. We have one user with domain\user1 userid and that user got terminated an year back and that user should have been removed after a month or so of the termination, but got re-hired recently with a different userid. The script is not updating the picture, giving error that domain\user1 not found. Somehow it is associating the old userid with the new user.

  15. RZollander

    The script is not automatically creating the DNS Lookup xml. Is there a copy of that file around that I can use? If I create a bank xml file with that work?

Leave a Reply

Your email address will not be published. Required fields are marked *