Office 365 Profile Picture Not Displayed Inside SharePoint Online Webparts

Last Updated on February 17, 2024

From time to time you may notice that SharePoint Online does not display updated user photos in webparts.

You may see or experience something like this:

  • Profile picture displayed in Office 365 Suite Bar: Yes
  • Profile picture displayed in Office Delve: Yes
  • Profile picture displayed in Outlook on the Web: Yes
  • Profile picture displayed in Microsoft Teams: Yes
  • Profile picture displayed in SharePoint People Web Part on a Modern SharePoint Page or trying to load user profile through custom web part on a classic SharePoint Page: No

There is a simple solution to this. Navigate to this URL in your SharePoint tenant:

  • https://[tenant name here]-my.sharepoint.com/User%20Photos/Forms/Thumbnails.aspx?RootFolder=%2FUser%20Photos%2FProfile%20Pictures

This list stores three photos for each user in your Office 365 tenant.

How to browse your profile picture location in SharePoint

The photos have the following naming convention and dimension requirements:

  • username_tenantname_tld_SThumb.jpg: 42px x 42px
  • username_tenantname_tld_MThumb.jpg: 78px x 78px
  • username_tenantname_tld_LThumb.jpg: 300px x 300px

If my username was ryanclark, my tenant name was mrsp1, my TLD (top-level domain) was .com (could be .net, .org, .co, etc.), then we’d have the following:

  • ryan.clark_mrsp1_com_SThumb.jpg
  • ryan.clark_mrsp1_com_MThumb.jpg
  • ryan.clark_mrsp1_com_LThumb.jpg

Save (and possibly overwrite) the three images in the user photos library and you should be good to go. You will have to do a hard refresh and/or clear your cache to see the results on the front-end.

Update: 11/9/2021


I’ve provided a PowerShell script below that can help with syncing photos from Exchange Online to SharePoint Online.

You must set the two input parameters ($siteURL and $SPOAdminPortalURL) on lines 96 and 97. In addition, you can enter an individual user’s email address or put in “All” when prompted for UserEmail.

Test on a test account first. Use at your own risk.

#Add references to SharePoint client assemblies and authenticate to Office 365 site as required for CSOM
Add-Type -AssemblyName System.Drawing

Function UploadImage ()
{
	Param(
	  [Parameter(Mandatory=$True)]
	  [String]$SiteURL,

	  [Parameter(Mandatory=$True)]
	  [String]$SPOAdminPortalUrl,

	  [Parameter(Mandatory=$True, HelpMessage="Enter user email address or All for all mailboxes")]
	  [String]$UserEmail

	)

	#Default Image library and Folder value 
	$DocLibName ="User Photos"
	$foldername="Profile Pictures"

    Connect-ExchangeOnline
    $siteConnection = Connect-PnPOnline -Url $SiteURL –Interactive -ReturnConnection

    #NOTE: there is a bug in Set-PnPUserProfileProperty in which the ConnectPnPOnline must connect with the UseWebLogin option 
    # https://github.com/pnp/powershell/issues/277
    $adminConnection = Connect-PnPOnline -Url $SPOAdminPortalUrl –UseWebLogin -ReturnConnection

	$spoimagename = @{"_SThumb" = "48"; "_MThumb" = "72"; "_LThumb" = "200"}


    $allUserMailboxes = Get-Mailbox -ResultSize Unlimited -RecipientTypeDetails UserMailbox

    Foreach($mailbox in $allUserMailboxes)
    {

        if(($mailbox.PrimarySmtpAddress -eq $UserEmail) -or ($UserEmail -eq "All")){

            Write-Host "Processing " $mailbox.PrimarySmtpAddress

            try{
		        #Download Image from Exchange online 
                $photo = Get-UserPhoto -Identity $mailbox.Identity
		        Write-Host "Exchange online image downloaded successful for" $mailbox.PrimarySmtpAddress

		        $username = $mailbox.PrimarySmtpAddress.Replace("@", "_").Replace(".", "_")

		        $Extension = ".jpg"
		        Foreach($imagename in $spoimagename.GetEnumerator())
		        {
			        #Covert image into different size of image
                    $ms = new-object System.IO.MemoryStream(,$photo.PictureData)
			        $img = [System.Drawing.Image]::FromStream($ms)
			        [int32]$new_width = $imagename.Value
			        [int32]$new_height = $imagename.Value
			        $img2 = New-Object System.Drawing.Bitmap($new_width, $new_height)
			        $graph = [System.Drawing.Graphics]::FromImage($img2)
			        $graph.DrawImage($img, 0, 0, $new_width, $new_height)

			        #Covert image into memory stream
			        $stream = New-Object -TypeName System.IO.MemoryStream
			        $format = [System.Drawing.Imaging.ImageFormat]::Jpeg
			        $img2.Save($stream, $format)
			        $streamseek=$stream.Seek(0, [System.IO.SeekOrigin]::Begin)

			        #Upload image into sharepoint online
			        $FullFilename=$username+$imagename.Name+$Extension
                    Add-PnPFile -Connection $siteConnection -Folder "User Photos/Profile Pictures" -FileName $FullFilename -Stream $stream                                

		        }
		        Write-Host "SharePoint online image uploaded successful for" $mailbox.PrimarySmtpAddress
		        #Change user Profile Property in Sharepoint onlne 
		        $PictureURL=$SiteURL+$DocLibName+"/"+$foldername+"/"+$username+"_MThumb"+$Extension

                Set-PnPUserProfileProperty -Connection $adminConnection -Account $mailbox.PrimarySmtpAddress -PropertyName PictureURL -Value $PictureURL

                Set-PnPUserProfileProperty -Connection $adminConnection -Account $mailbox.PrimarySmtpAddress -PropertyName SPS-PicturePlaceholderState -Value 0

                Set-PnPUserProfileProperty -Connection $adminConnection -Account $mailbox.PrimarySmtpAddress -PropertyName SPS-PictureExchangeSyncState -Value 0

                Set-PnPUserProfileProperty -Connection $adminConnection -Account $mailbox.PrimarySmtpAddress -PropertyName SPS-PictureTimestamp -Value 63605901091

		        Write-Host "Image processed successfully and ready to display for" $mailbox.PrimarySmtpAddress
            }catch{
                $ErrorMessage = $_.Exception.Message
                Write-Host "Failed to process " $mailbox.PrimarySmtpAddress -ForegroundColor red
                Write-Host $ErrorMessage -ForegroundColor red
            }
	    }        

    }

}

#Input parameter
$siteUrl="https://company-my.sharepoint.com/"
$SPOAdminPortalUrl = "https://company-admin.sharepoint.com/"

uploadimage -SiteURL $siteUrl -SPOAdminPortalUrl $SPOAdminPortalUrl

If you have any questions, reach out to me at any time.

About Ryan Clark

As the Modern Workplace Architect at Mr. SharePoint, I help companies of all sizes better leverage Modern Workplace and Digital Process Automation investments. I am also a Microsoft Most Valued Professional (MVP) for M365 Apps & Services.

Subscribe
Notify of
guest
12 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments

Paul
Paul
3 years ago

Hey, Ryan. We’re dealing with this exact situation right now but the files for the affected users are not present in the URL you shared. They are there, however, for other users. As you described symptomatically, the following is true for impacted users: Profile picture displayed in Office 365 Suite Bar: Yes Profile picture displayed in Office Delve: Yes Profile picture displayed in Outlook on the Web: Yes Profile picture displayed in Microsoft Teams: Yes Profile picture displayed in SharePoint People Web Part on a Modern SharePoint Page or trying to load user profile through custom web part on a… Read more »

Mark Taylor
Mark Taylor
3 years ago

I am seeing the pictures all around O365, but for some not in the people web part. The profile pictures library has a mix of ‘real’ photo’s as you described, plus the problematic ones are just a placeholder silhouette file. I wonder if I delete these silhouette files if the user profile service (I have SharePoint server background, I don’t know if that is the term!) will populate them correctly?

Courtney
Courtney
Reply to  Ryan Clark
3 years ago

Hi Ryan,
I have the exact issue you described. I have tried deleting the initial-only placeholders and re-adding them in, but still no photo shows up – it’s also not in the user profile photos which is odd – some are some aren’t. Perhaps it takes a while to sync? I also don’t know how to save and/or override the ones that there but don’t show up.

Charlie
2 years ago

We have this exact problem.
Users have uploaded their own pics, I can see a few of them in that URL, I can see a few more silhouttes, but most are just missing.
Is the only solution to this to go into Delve and save off people’s photos and then upload them all to this location – there must be some kind of synch that can be re-run?

sebastian cerazy
sebastian cerazy
10 months ago

Connect-PnPOnline : A positional parameter cannot be found that accepts argument ‘â€Interactive -ReturnConnection
  #NOTE: there is a bug in Set-PnPUserProfileProperty in which the ConnectPnPOnline must connect with the
UseWebLogin option
  # https://github.com/pnp/powershell/issues/277
   = Connect-PnPOnline -Url https://correct_domain-admin.sharepoint.com/ â€UseWebLogin’.
At C:\PSScripts\photo-sync.ps1:23 char:23
+ … onnection = Connect-PnPOnline -Url $SiteURL –Interactive -ReturnCon …

These 2 characters need to be corrected in the above script

sebastian cerazy
sebastian cerazy
10 months ago

Also getting few errors like:

Failed to process 
Exception calling “.ctor” with “1” argument(s): “Buffer cannot be null.
Parameter name: buffer”

Edwin
Edwin
4 months ago

Hello,

I am trying to run the script on our tenant, but a soon as I do I get the error that “-Connection” holds no sharepoint context. I think it’s having issues with the Add-PnPFile command.

Do you know what to do to fix this problem?

12
0
Would love your thoughts, please comment.x
()
x
Scroll to Top