Thursday, January 22, 2015

SharePoint 2013 Active Directory Import: Set User Profile Pictures

In SharePoint 2013, the user profiles Active Directory Import is the fastest way to import user profiles from the Active Directory.

SharePoint AD Import does not import user profile pictures, Fortunately you you can  achieve this with a bit of  work on your own.

In this post, we focus on importing profile pictures from a network folder location, but you can do something similar directly with AD,
So first copy your AD profile pictures to a local folder, and we will get started ...

Add a new SharePoint folder named Profile Pictures in http://MySiteURL/user photos.

Then use the following PowerShell script to set user profile pictures :
Clear

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Load SharePoint User Profile assemblies
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.Office.Server")

#Constants
$slash = "/"
$backSlash = "\"
$fileExtension = ".jpg"

#Temp local folder
$folderLocalPath = "D:\AD Pictures"

if(!(Test-Path $folderLocalPath))
{
    $pictureLocalFolder = New-Item $folderLocalPath -type directory
}

$mySiteURL = "http://mysite"

$assignment = Start-SPAssignment

$web = Get-SPWeb $mySiteURL

$pictureMySiteFolderName = "User Photos"

$pictureMySiteSubFolderName = "Profile Pictures"

$pictureProperty = "PictureURL"    

#Add folder named Profile Pictures in the "http://mysite/User photos" 

$pictureFolder = $web.Folders[$pictureMySiteFolderName].SubFolders[$pictureMySiteSubFolderName]

$site = $web.Site

$serviceContext = Get-SPServiceContext $site

$upm = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($serviceContext)

$PathLDAP = [String]::Empty

$picDirectory = "Your pictures folder path"

$strQuery ="(sAMAccountName={0})"

#You need the Active Directory Domain Services or Active Directory #Lightweight Directory Services server role to use this command
Import-Module ActiveDirectory

Get-ChildItem $picDirectory -Recurse | Select-Object FullName, BaseName | ForEach-Object{
     
       $accountName = $_.BaseName

       $strCurrQuery = [String]::Format($strQuery, $accountName)

       $searcher =  New-Object System.DirectoryServices.DirectorySearcher([adsi]$PathLDAP ,$strCurrQuery)
     
       # Run LDAP Query - Does user exists in AD ?
       $currUser = $searcher.FindOne()

       if($currUser -ne $null)
       {
              $photoURL = $_.FullName
              $photo = [byte[]] (Get-Content $photoURL -Encoding byte)
              $account = [String]$currUser.GetDirectoryEntry().sAMAccountName

        $userProfile = $upm.GetUserProfile($account)

        if($userProfile -ne $null)
        {
          $login = $userProfile["AccountName"].Value.Split($backSlash)

          $domain = $login[0]

          $user = $login[1]
    
          $pictureLocalPath = $folderLocalPath + $backSlash + $user + $fileExtension
    
          $photo = ([ADSISEARCHER]"samaccountname=$($user)").FindOne().Properties.thumbnailphoto

           if($photo)
           {
               $photo | Set-Content -Path $pictureLocalPath -Encoding Byte
    
               $fileStream = ([System.IO.FileInfo] (Get-Item $pictureLocalPath)).OpenRead()

               $fileStreamLength = $fileStream.Length

               if($fileStreamLength -gt 0)
               {
                 $contents = New-Object byte[] $fileStreamLength

                 $fileStream.Read($contents,0,[int] $fileStreamLength)

                 $fileStream.Close()
    
                 $pictureDestinationURL = $pictureFolder.Url + $slash + $user + $fileExtension
    
                 $spFile = $pictureFolder.Files.Add($pictureDestinationURL, $contents, $true)   
    
                 $userProfile[$pictureProperty].Value = $mySiteURL + $slash + $spFile.Url
    
                 $userProfile.Commit()      

                 Remove-Item -LiteralPath $pictureLocalPath
    
               }
           }
        } 
     }
}

Stop-SPAssignment $assignment 
Next, produce thumbnails using the following PowerShell script :
Update-SPProfilePhotoStore -MySiteHostLocation "MySiteURL:MySitePort"
(for instance "http://mysite:80")
Thank you for reading and see you in another post.