Import user profile pictures to SharePoint using PowerShell

Best solution to create Automatic UserProfile Import to SharePoint

  1. Create folder “ImportProfileImages”
  2. Create subfolder “ProfileImages”
  3. Create “c:\SPSolutions\ImportProfileImages\UpdateUserProfiles.ps1” with the code from SharePoint Use Cases
    cls
    if((Get-PSSnapin | Where {$_.Name -eq "Microsoft.SharePoint.PowerShell"}) -eq $null) {
        Add-PSSnapin Microsoft.SharePoint.PowerShell;
    }
    
    #---------------------------------------------------------------------------------
    # Default Values
    #---------------------------------------------------------------------------------
    
    $spNotFoundMsg = "Unable to connect to SharePoint.  Please verify that the site '$siteUrl' is hosted on the local machine.";
    
    #-----------------------------------------------------
    # Load Assemblies
    #-----------------------------------------------------
    
    if ([Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") -eq $null)       { throw $spNotFoundMsg; }
    if ([Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server") -eq $null)    { throw $spNotFoundMsg; }
    
    #-----------------------------------------------------
    # Functions
    #-----------------------------------------------------
    
    function ToSimpleString([string]$value, [bool]$trim = $true, [bool]$removeSpaces = $true, [bool]$toLower = $true)
    {
        if ($value -eq $null) { return [System.String]::Empty; }
    
        if ($trim)
        {
            $value = $value.Trim();
        }
    
        if ($removeSpaces)
        {
            $value = $value.Replace(" ", "");
        }
    
        if ($toLower)
        {
            $value = $value.ToLower();
        }
    
        return $value;
    }
    
    function GetSPSite($url)
    {
        [Microsoft.SharePoint.SPSite]$site = New-Object "Microsoft.SharePoint.SPSite" -ArgumentList $url
        return $site;
    }
    
    function GetSPWeb($url)
    {
        [Microsoft.SharePoint.SPSite]$site = GetSPSite -url $url;
        [Microsoft.SharePoint.SPWeb]$web = $site.OpenWeb();
        return $web
    }
    
    function GetSPList($url, $listName)
    {
        $listName = (ToSimpleString -value $listName);
    
        [Microsoft.SharePoint.SPWeb]$web = GetSPWeb -url $url;
        foreach($list in $web.Lists)
        {
            $title = (ToSimpleString -value $list.Title);
            if ($listName -eq $title)
            {
                return $list;
            }
        }
        return $null;
    }
    
    function GetSPDocumentLibrary($url, $libraryName)
    {
        [Microsoft.SharePoint.SPDocumentLibrary]$lib = [Microsoft.SharePoint.SPDocumentLibrary](GetSPList -url $url -listName $libraryName);
        return $lib;
    }
    
    function GetSPFile($libraryInstance, $fileName)
    {
        $fileName = (ToSimpleString -value $fileName -removeSpaces $false);
    
        foreach($file in $libraryInstance.RootFolder.Files)
        {
            $itemName = (ToSimpleString -value $file.Name -removeSpaces $false);
            if ($fileName -eq $itemName)
            {
                return $file;
            }
        }
        return $null;
    }
    
    function UploadSPFile([string]$url, [string]$libraryName, [string]$filePath, [System.Text.StringBuilder]$verbose = $null)
    {
        try
        {
            [Microsoft.SharePoint.SPDocumentLibrary]$lib = (GetSPDocumentLibrary -url $url -libraryName $libraryName);
            if ($lib -eq $null)
            {
                throw (([string]'Cannot find document library "') + ([string]$libraryName) + ([string]'" at url "') + ([string]$url) + ([string]'"!'));
            }
    
            $bytes = [System.IO.File]::ReadAllBytes($filePath);
            $fileName = [System.IO.Path]::GetFileName($filePath);
    
            [Microsoft.SharePoint.SPFile]$file = GetSPFile -libraryInstance $lib -fileName $fileName;
    
            if ($file -eq $null)
            {
                if ($verbose -ne $null)
                {
                    [void]$verbose.AppendLine("Uploading File...");
                }
                $file = $lib.RootFolder.Files.Add($fileName, $bytes);
            }
            else
            {
                if ($verbose -ne $null)
                {
                    [void]$verbose.AppendLine("File Exists, overwriting...");
                }
                $file.SaveBinary($bytes);
            }
    
            if ($verbose -ne $null)
            {
                [void]$verbose.AppendLine(($bytes.Length.ToString()) + ([string]" bytes written!"));
            }
    
            return $file;
        }
        catch
        {
            if ($verbose -ne $null)
            {
                [void]$verbose.AppendLine(([string]'Error: Upload to document library "') + ([string]$libraryName) + ([string]'" at "') + ([string]$url) + ([string]'" or file "') + ([string]$filePath) + ([string]'" failed!'));
                [void]$verbose.AppendLine([string]'Error: ' + [string]$error[1]);
            }
        }
    
        return $null;
    }
    
    function GetSpContext($url)
    {
        [Microsoft.SharePoint.SPSite]$site = GetSPSite -url $url
        return [Microsoft.Office.Server.ServerContext]::GetContext($site);
    }
    
    function GetProfileManager($url)
    {
        [Microsoft.Office.Server.ServerContext]$ctx = GetSpContext -url $url
        [Microsoft.Office.Server.UserProfiles.UserProfileManager]$upm = New-Object "Microsoft.Office.Server.UserProfiles.UserProfileManager" -ArgumentList $ctx
    
        return $upm;
    }
    
    function GetSPUser($url, $loginName)
    {
       [Microsoft.SharePoint.SPWeb]$web = GetSPWeb -url $url
       [Microsoft.SharePoint.SPUser]$user = $web.AllUsers[$loginName]
       return $user;
    }
    
    function GetProfilePropertyName($userProfileManager, $propertyName)
    {
        $propertyName = (ToSimpleString -value $propertyName);
        $propertyName = $propertyName.Replace("sps-", "");
    
        foreach($prop in $userProfileManager.Properties)
        {
            [string]$n = (ToSimpleString -value $prop.DisplayName);
            $n = $n.Replace("sps-", "");
            if ($propertyName -eq $n) { return $prop.Name.ToString(); }
    
            $n = (ToSimpleString -value $prop.Name);
            $n = $n.Replace("sps-", "");
            if ($propertyName -eq $n) { return $prop.Name.ToString(); }
        }
    
        return $null;
    }
    
    #This function is VERY different from [System.IO.Path]::Combine
    function CombineUrls([string]$baseUrl, [string]$relUrl)
    {
        [System.Uri]$base = New-Object System.Uri($baseUrl, [System.UriKind]::Absolute);
        [System.Uri]$rel = New-Object System.Uri($relUrl, [System.UriKind]::Relative);
    
        return (New-Object System.Uri($base, $rel)).ToString();
    }
    
    function Update-SPProfilePictures([string]$webUrl, [string]$picLibraryName, [string]$localFolderPath, [string]$domain)
    {
        #Get web and picture library folder that will store the pictures
        $web = Get-SPWeb $webUrl
        $picFolder = $web.Folders[$picLibraryName]
        if(!$picFolder)
        {
            Write-Host "Picture Library Folder not found"
            return
         }
    
        #Attach to local folder and enumerate through all files
        $files = ([System.IO.DirectoryInfo] (Get-Item $localFolderPath)).GetFiles() | ForEach-Object {
    
            $username = [IO.Path]::GetFileNameWithoutExtension($_.FullName);
    
            #Create file stream object from file
            $fileStream = ([System.IO.FileInfo] (Get-Item $_.FullName)).OpenRead()
            $contents = new-object byte[] $fileStream.Length
            $fileStream.Read($contents, 0, [int]$fileStream.Length);
            $fileStream.Close();
    
            write-host "Copying" $_.Name "to" $picLibraryName "in" $web.Title "..."
    
            #Add file
            $spFile = $picFolder.Files.Add($picFolder.Url + "/" + $_.Name, $contents, $true)
            $spItem = $spFile.Item
    
            $upm = GetProfileManager -url $webUrl
            $up = $null;
            $up = $upm.GetUserProfile("$domain\$username");
    
            $picturePropertyName = GetProfilePropertyName -UserProfileManager $upm -PropertyName "PictureUrl";
    
            if($up -ne $null)
            {
                if (-not [System.String]::IsNullOrEmpty($picturePropertyName))
                {
                    $PortraitUrl = CombineUrls -baseUrl $spFile.Web.Url -relUrl $spFile.ServerRelativeUrl;
                    Write-Host $PortraitUrl
                    $up.get_Item($picturePropertyName).Value = $PortraitUrl;
                    $up.Commit();
                }
            }
    
        }
    
        Write-Host "Updating User Profile Photo Store..." -foregroundcolor yellow
        Update-SPProfilePhotoStore –MySiteHostLocation $webUrl
        Write-Host "Done" -foregroundcolor green
    }
    
  4. Create “c:\SPSolutions\ImportProfileImages\RunUpdateUserProfiles.ps1” with this code:
    cd C:\SPSolutions\ImportProfilePhotos
    . .\UpdateProfiles.ps1
    Update-SPProfilePictures "http://my-sites-host-url" "User Photos" "c:\SPSolutions\ImportProfileImages\ProfileImages" "Your_Domain"
    
  5. Save the files, copy images into the “ProfileImages” folder, using the useralias as filename.
  6. Rightclick “RunUpdateUserProfiles.ps1” and select “Run with PowerShell”

Source: SharePoint Use Cases

1 thought on “Import user profile pictures to SharePoint using PowerShell”

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.