Microsoft Collaboration, CTO viewpoint, and New York

The blog for Office 365, Power Apps, Flow, SharePoint, cloud, ….. plus a little NYC

Bit of Powershell to upload photos to users profile

Written by Peter Ward on May 29, 2016 – 2:29 pm -

Firstly-  Need to run as an Admin user. Or if it’s your own account, add SP Shell Admin  using:  Add-SPShellAdmin -UserName Domain\user

It takes a bit of time to proper gate.

Instructions to run the upload profile photos Power Shell script

1. Login as sp.admin user or any other farm administratoruserto any of the SharePoint Server and copy and paste the script files to any folder on the server. The script files are already uploaded to  server at location “c:\scripts”

2. Open SharePoint Management Shell (run as administrator)

3. Copy the path of the folder where script resides

<#
.SYNOPSIS
   Upload-ProfilePhotos
.DESCRIPTION
   Bulk upload of profile pictures for SharePoint 2013. The script do not require property mapping and do not rewrites the PictureURL.
   Supports BMP, GIF, JPEG, PNG, TIFF, and WMF picture formats. Script should run in elevated process under the farm account! A nice feature is that if the pictures are uploaded with this script the profile picture of the user will be with the largest thumbnail possible so you will have better picture resolution compared to the AD import.
   First you will need to run the script with GenerateCSV parameter. A CSV file will be generated where you can fill the path to the picture for the specific profile(using Excel or your editor of choice).
   Paths to the photos can be local or network. 
   After you fill all the photo paths that you want. Run the script with UpdatePhotos parameter. The script will upload the photos and will run the native command Update-SPProfilePhotoStore to generate thumbnails and update the PictureURL.
   The script do not support multiple User Profile Service applications in single farm or partitioned User Profile Service application!

   If you are running the script in a fresh SharePoint installation, make sure that User Photos library exist in your My Sites host and also that there is a folder in it called Profile Pictures. If no user has a profile picture most probably the folder is missing. You can create it manually or by uploading a profile picture for some account and the folder will be created.
   If you are using SharePoint installation with language different than English.Please edit the Upload-ToUserPhotos according, there you will find the name of the library, the folder and the upload method.

   v1.1 - Parameter typo fixed, enhanced error handling. Supported doble quoted picture path(Example "C:\SomePic") You will see the actual exception message in order to find what is wrong. Thanks to jlai79

   Author: Ivan Yankulov [ SharePoint Administrator @ BulPros Consulting]
   Contact: http://spyankulov.blogspot.com
   About this script: http://spyankulov.blogspot.com/2014/08/bulk-upload-and-update-user-profile.html

.PARAMETER GenerateCSV
   Use this switch to generate CSV
.PARAMETER UpdatePhotos
   Use this switch to Upload and Update the photos
.PARAMETER CSVPath
   Path to the CSV file that contains the account data
.PARAMETER MySiteHost
   My Site host for your User Profile Service Application
.EXAMPLE
   .\Upload-ProfilePhotos.ps1 -GenerateCSV -MySiteHost http://mysite.auto.l:8080/

 Description
 -----------
 This will generate CSV file UserPhotoCSV.csv in the script execution directory
 .EXAMPLE
    .\Upload-ProfilePhotos.ps1 -UpdatePhotos -MySiteHost http://mysite.auto.l:8080/

 Description
 -----------
 This will use the default CSV file UserPhotoCSV.csv to upload and update the profile photos
.EXAMPLE
   .\Upload-ProfilePhotos.ps1 -GenerateCSV -CSVPath C:\ProfilePhotos.csv -MySiteHost http://mysite.auto.l:8080/

 Description
 -----------
 This will generate CSV file in custom location C:\ProfilePhotos.csv
 .EXAMPLE
    .\Upload-ProfilePhotos.ps1 -UpdatePhotos -CSVPath C:\ProfilePhotos.csv -MySiteHost http://mysite.auto.l:8080/

 Description
 -----------
 This will use CSV file in custom location C:\ProfilePhotos.csv to upload and update the profile photos
.LINK
http://spyankulov.blogspot.com
http://spyankulov.blogspot.com/2014/08/bulk-upload-and-update-user-profile.html

#>

[CmdletBinding(DefaultParameterSetName="GenerateCSV")]
Param(
    [parameter(ParameterSetName="GenerateCSV")]
    [switch]$GenerateCSV =$false,
    [parameter(ParameterSetName="UpdatePhotos")]
    [switch]$UpdatePhotos =$false,
    [parameter(Mandatory=$false)]
    [string]$CSVPath = ($PSScriptRoot + "\UserPhotoCSV.csv"),
    [parameter(Mandatory=$true)]
    [string]$MySiteHost
)
PROCESS{
Add-PSSnapin Microsoft.SharePoint.PowerShell
### Function region
Function Generate-CSV{
[CmdletBinding()]
param(
 [parameter(Mandatory=$true)]
    [string]$URL,
    [parameter(Mandatory=$true)]
    [string]$Path
)
Process{
    $Site = Get-SPSite -Identity $URL
    $context = Get-SPServiceContext -Site $site
    Try{
        $upm = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($context) -ErrorAction Stop
    }Catch [System.Exception]{
        Write-Host "Unable to get the User Profiles !!! Folowing exception occurred: $($_.Exception.Message)" -ForegroundColor Red
        Break
    }
    $AllProfiles = $upm.GetEnumerator()
    $accounts = @()
    Clear-Content -Path $Path -ErrorAction SilentlyContinue
    Try{
        Add-Content -Value "RecordID,LoginName,PhotoPath" -Force -Path $Path -ErrorAction Stop
    }Catch [System.Exception]{
        Write-Host "Unable to generate CSV file to Path: `"$Path`", folowing exception occurred: $($_.Exception.Message)" -ForegroundColor Red
        Break
    }
    ForEach($profile in $AllProfiles)
    {
        Add-Content -Path $Path -Value "$($profile.RecordId.ToString()),$($profile.AccountName.ToString())"
    }
    Write-Host "A CSV file with Profile Information was generated: `"$Path`"" -ForegroundColor Green
    Write-Host "Fill the 'PhotoPath' column with the path to the users photo and run again the script with 'UpdatePhotos' parameter. " -ForegroundColor Green
}
}
Function Upload-ToUserPhotos{
 [CmdletBinding()]
 Param(
     [parameter(Mandatory=$true)]
    [string]$URL,
    [parameter(Mandatory=$true)]
    [string]$Path,
    [parameter(Mandatory=$true)]
    [string]$ID
 )
 Process{
    $docLibraryName = "User Photos"
    $docLibraryUrlName = "Profile%20Pictures"
    $web = Get-SPWeb $URL
    $docLibrary = $web.Lists[$docLibraryName]
    $file = Get-Item $Path
    #Open file
    $fileStream = ([System.IO.FileInfo] (Get-Item $file.FullName)).OpenRead()
    #Add file
    $folder =  $web.GetFolder($docLibraryUrlName)
    $spFile = $folder.Files.Add("/" + "User%20Photos" + "/" + $folder.Url + "/" + "0c37852b-34d0-418e-91c6-2ac25af4be5b_" + $ID + ".jpg", [System.IO.Stream]$fileStream, $true)
    #Close file stream
    $fileStream.Close();
    }
}
Function Update-Photos{
 [CmdletBinding()]
 Param(
     [parameter(Mandatory=$true)]
    [string]$URL,
    [parameter(Mandatory=$true)]
    [string]$Path
 )
Process{
    Try{
        $accountData = Import-Csv $Path -ErrorAction Stop
    }Catch [System.Exception]{
        Write-Host "Unable to load the CSV file from path: `"$Path`", folowing exception occurred: $($_.Exception.Message)" -ForegroundColor Red
        Break
    }
    ForEach ($acc in ($accountData | Where {$_.PhotoPath.Length -ge 2} ))
    {
        $photoPath = $acc.PhotoPath.Replace('"', "")
        If(Test-Path $photoPath -ErrorAction SilentlyContinue)
        {
            If((Get-Item -Path $photoPath).Extension -eq ".jpg")
            {    
                Copy-Item -Path $photoPath -Destination ($PSScriptRoot + "\tempPicture.jpg")
                Try{
                    Upload-ToUserPhotos -ID $acc.RecordID -Path ($PSScriptRoot + "\tempPicture.jpg") -URL $URL -ErrorAction Stop
                    Write-Host "Uploading picture for account: `"$($acc.LoginName)`"" -ForegroundColor Green
                }Catch [System.Exception]{
                    Write-Host "Unable to upload the picture for account: `"$($acc.LoginName)`", folowing exception occurred: $($_.Exception.Message)" -ForegroundColor Red
                }
                Remove-Item -LiteralPath ($PSScriptRoot + "\tempPicture.jpg") -ErrorAction SilentlyContinue
            }
            Else
            {
                Copy-Item -Path $photoPath -Destination ($PSScriptRoot + "\tempPicture.jpg")
                $convertedFile = ($PSScriptRoot + "\convertedPicture.jpg")
                Add-Type -AssemblyName system.drawing
                $image = [drawing.image]::FromFile(($PSScriptRoot + "\tempPicture.jpg"))
                $image.Save($convertedFile, [System.Drawing.Imaging.ImageFormat]::jpeg)
                $image.Dispose()
                Try{
                    Write-Host "Uploading picture for account: `"$($acc.LoginName)`"" -ForegroundColor Green
                    Upload-ToUserPhotos -ID $acc.RecordID -Path $convertedFile -URL $URL -ErrorAction Stop
                }Catch [System.Exception]{
                    Write-Host "Unable to upload the picture for account: `"$($acc.LoginName)`", folowing exception occurred: $($_.Exception.Message)" -ForegroundColor Red
                }
                Remove-Item $convertedFile -Force -ErrorAction SilentlyContinue
                Remove-Item -LiteralPath ($PSScriptRoot + "\tempPicture.jpg") -ErrorAction SilentlyContinue
            }
        }
        Else{
            Write-Host "Unable to get the picture for Account: $($acc.LoginName)" -ForegroundColor Red
        }
    }
        Try{
            Write-Host "Updating Profile Photo Store...." -ForegroundColor Green
            Update-SPProfilePhotoStore -MySiteHostLocation $URL -CreateThumbnailsForImportedPhotos:$true -ErrorAction Stop
        }Catch [System.Exception]{
            Write-Host "Unable to updating Profile Photo Store ! Folowing exception occurred: $($_.Exception.Message)"
        }
}
}

### Function region
switch ($PsCmdlet.ParameterSetName) 
{
    "GenerateCSV" { Generate-CSV -URL $MySiteHost -Path $CSVPath} 
    "UpdatePhotos" { Update-Photos -URL $MySiteHost -Path $CSVPath} 
}
}

Run following command to generate the CSV file:.\Upload-ProfilePhotos.ps1 -GenerateCSV -MySiteHost http://my.site:80/Following message should be displayed after running this command

A CSV file should have been generate at the location where the script file resides. Fill  PhotoPath column with the path to the users photo

Run following command to upload the photos.\Upload-ProfilePhotos.ps1 -UpdatePhotos -MySiteHost http://my.site.com:80/

8.Let the script complete, it should show message like above screen shot for the users for whom PhotoPath column is filled with correct location of the profile photo.

Posted in Technology.