Import user profile pictures to SharePoint using PowerShell

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