Forum Discussion
Profile Photo Sync SPO
- https://spbreed.wordpress.com/2015/11/06/demystifying-user-profile-picture-sync-in-office365/
- http://windowsitpro.com/blog/synchronizing-user-photos-across-office-365-workloads-isnt-easy
So, I set the user photo using Powershell. See screenshot. It ran without any errors. Now, when I go the sharepoint admin page, the photo for this particular user has not been set. See screenshot. Set-UserPhoto does not seem to set the profile photo in SharePoint. Any further help?
- SanthoshB1Jun 21, 2017Bronze Contributor
Following PowerShell script is used to instantly process and display profile picture in Exchange Online and SharePoint Online using “Set-UserPhoto” cmdlet and CSOM.
Before executing the following script, you need to modify the input parameters in the script with your own values as follows,
Input Parameters:
$siteUrl= "https://tenantname-my.sharepoint.com/"
$username= "admin@tenantname.onmicrosoft.com"
$password= "xxxxxxxx"
$folderpath= "E:\photo"
$SPOAdminPortalUrl= “https://tenantname-admin.sharepoint.com/”#Add references to SharePoint client assemblies and authenticate to Office 365 site – required for CSOM Add-Type -Path ([System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client").location) Add-Type -Path ([System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.runtime").location) Add-Type -Path ([System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.UserProfiles").location) Add-Type -AssemblyName System.Drawing Function UpdateUserProfile() { Param( [Parameter(Mandatory=$True)] [String]$targetAcc, [Parameter(Mandatory=$True)] [String]$PropertyName, [Parameter(Mandatory=$False)] [String]$Value, [Parameter(Mandatory=$True)] [String]$SPOAdminPortalUrl, [Parameter(Mandatory=$True)] [System.Net.ICredentials]$Creds ) $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SPOAdminPortalUrl) $ctx.Credentials = $Creds $peopleManager = New-Object Microsoft.SharePoint.Client.UserProfiles.PeopleManager($ctx) $targetAccount = ("i:0#.f|membership|" + $targetAcc) $peopleManager.SetSingleValueProfileProperty($targetAccount, $PropertyName, $Value) $ctx.ExecuteQuery() } Function UploadImage () { Param( [Parameter(Mandatory=$True)] [String]$SiteURL, [Parameter(Mandatory=$True)] [String]$User, [Parameter(Mandatory=$False)] [String]$Password, [Parameter(Mandatory=$True)] [String]$Folder, [Parameter(Mandatory=$True)] [String]$SPOAdminPortalUrl ) #Defualt Image library and Folder value $DocLibName ="User Photos" $foldername="Profile Pictures" #Connect Exchange online $secstr = New-Object -TypeName System.Security.SecureString $password.ToCharArray() | ForEach-Object {$secstr.AppendChar($_)} $cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $User, $secstr $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/?proxyMethod=RPS -Credential $cred -Authentication Basic -AllowRedirection Import-PSSession $Session $Securepass = ConvertTo-SecureString $Password -AsPlainText -Force $Creds = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($User,$Securepass) #Bind to site collection $Context = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL) $Context.Credentials = $Creds #Retrieve list $List = $Context.Web.Lists.GetByTitle($DocLibName) $Context.Load($List) $Context.Load($List.RootFolder) $Context.ExecuteQuery() $ServerRelativeUrlOfRootFolder = $List.RootFolder.ServerRelativeUrl $uploadFolderUrl= $ServerRelativeUrlOfRootFolder+"/"+$foldername $spoimagename = @{"_SThumb" = "48"; "_MThumb" = "72"; "_LThumb" = "200"} #Upload file Foreach ($File in (dir $Folder -File)) { #Upload image into Exchange online $PictureData = $File.FullName $Identity=$File.BaseName Set-UserPhoto -Identity $Identity -PictureData ([System.IO.File]::ReadAllBytes($PictureData)) -Confirm:$false Write-Host "Exchange online image uploaded successful for" $Identity $username=$File.BaseName.Replace("@", "_").Replace(".", "_") $Extension = $File.Extension Foreach($imagename in $spoimagename.GetEnumerator()) { #Covert image into different size of image $img = [System.Drawing.Image]::FromFile((Get-Item $PictureData)) [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 $ImageRelativeURL="/"+$DocLibName+"/"+$foldername+"/"+$FullFilename $ModifiedRelativeURL=$ImageRelativeURL.Replace(" ","%20") [Microsoft.SharePoint.Client.File]::SaveBinaryDirect($Context,$ModifiedRelativeURL, $stream, $true) } Write-Host "SharePoint online image uploaded successful for" $Identity #Change user Profile Property in Sharepoint onlne $PictureURL=$SiteURL+$DocLibName+"/"+$foldername+"/"+$username+"_MThumb"+$Extension UpdateUserProfile -targetAcc $Identity -PropertyName PictureURL -Value $PictureURL -SPOAdminPortalUrl $SPOAdminPortalUrl -Creds $Creds UpdateUserProfile -targetAcc $Identity -PropertyName SPS-PicturePlaceholderState -Value 0 -SPOAdminPortalUrl $SPOAdminPortalUrl -Creds $Creds UpdateUserProfile -targetAcc $Identity -PropertyName SPS-PictureExchangeSyncState -Value 0 -SPOAdminPortalUrl $SPOAdminPortalUrl -Creds $Creds UpdateUserProfile -targetAcc $Identity -PropertyName SPS-PictureTimestamp -Value 63605901091 -SPOAdminPortalUrl $SPOAdminPortalUrl -Creds $Creds Write-Host "Image processed successfully and ready to display for" $Identity } } #Input parameter $siteUrl="https://tenantname-my.sharepoint.com/" $username= "admin@tenantname.onmicrosoft.com" $password= "pass@word1" $folderpath= "E:\photo" $SPOAdminPortalUrl = "https://tenantname-admin.sharepoint.com/" uploadimage -SiteURL $siteUrl -User $username -Password $password -Folder $folderpath -SPOAdminPortalUrl $SPOAdminPortalUrl- gte2723Jul 30, 2020Copper Contributor
Thank you for this code example.
My image file was continually locked after the first edit. I was able to fix it by changing the following lines of code in case you want to include this.
$graph = [System.Drawing.Graphics]::FromImage($img2) $graph.DrawImage($img, 0, 0, $new_width, $new_height)to include
$graph = [System.Drawing.Graphics]::FromImage($img2) $graph.DrawImage($img, 0, 0, $new_width, $new_height) $img.Dispose(); $graph.Dispose();- TravisMerrillJan 06, 2021Copper Contributor
I got the script working, but I only updates for the current user. I need it to update ALL users.
- Phillip LittlelyJun 21, 2017Copper Contributor
This looks exactly what I'm looking for - but not being a big powershell user, what is required for me to run this powershell script? What do I need to connect to first and how?
- SanthoshB1Jun 23, 2017Bronze Contributor
You need to run 'Set-ExecutionPolicy RemoteSigned' first and you need to install CSOM https://www.microsoft.com/en-in/download/details.aspx?id=42038
Also please note that the user photos should be named as userprincipalname (email address) of the user to whom you need to upload photo.
Now you need to change the imput parameters in the script as mentioned and save as .ps1 file and run it. This will update the user photos immediately.