AD to SP:

Import User Pictures from Active Directory to SharePoint 2010 My Site: http://www.sharepointdiary.com/2013/01/import-user-pictures-from-active-directory-to-sharepoint-2010-mysite.html

SP to AD:

How to sync picture from SharePoint to Active Directory and hence to Outlook and Lync: http://blogs.technet.com/b/nishants/archive/2012/02/21/how-to-sync-picture-from-sharepoint-to-active-directory-and-hence-to-outlook-and-lync.aspx

http://support.microsoft.com/kb/2784927

AD user picture and Outlook/exchange:

http://www.stevieg.org/2010/12/enabling-outlook-2003-and-2007-to-display-exchange-gal-photos/

http://www.exchangeinbox.com/article.aspx?i=156

TIPs:

User pictures size recommendations:

  • 100k max for thumbnail photo attribute. 116×150 pixels in AD.
  • If you upload a photo to Exchange 2013 Exchange will automatically create a 48  pixel by 48 pixel version of that photo and update the user’s thumbnailPhoto attribute. Note, however, that the reverse is not true: if you manually update thethumbnailPhoto attribute in Active Directory the photo in the user’s Exchange 2013 mailbox will not automatically be updated.
  • 96 pixels by 96 pixels, for use in Microsoft Outlook 2013 Web App, Microsoft Outlook 2013, Microsoft Lync Web App, and Lync 2013.
  • Out of box for Sharepoint 2013, we use the large (144×144 px) thumbnail on the profile page contact card, the medium (96×96 px) thumbnail on the people search results page and the small (32×32 px) thumbnail on various webparts and controls displaying people data like the Newsfeed, Colleagues, In Common With You, Note Board and many others.

Scripting:

To upload photos into Active Directory’s thumbnailPhoto attribute you can use the Powershell  Import-RecipientDataProperty cmdlet. This cmdlet can be used to upload photos or even audio files of a spoken name to a user’s account or mail contact. Once a photo is uploaded into Active Directory, applications such as Exchange, Outlook, and Lync can display these photos through the thumbnailPhoto attribute. SharePoint can even use this attribute using the User Profile Sync to display user photos providing a centralized location to retrieve a user’s profile image.

It is recommended to use a photo size that is 96×96 pixels, which isn’t very large, but it’s enough to get a decent thumbnail photo for all to see in the GAL. Even though the thumbnailPhoto attribute can store up to 100kb, the Import-RecipientDateProperty cmdlet can only upload 10kb or less, so you will need to make sure photo is that size or smaller. If your photo is too large the import will fail.

Run the following cmdlet into the Exchange Management Shell:

This image shows an example:

PScmd

You will need to update your Offline Address book before you can view photos in the offline address book, otherwise the photos will not appear until the next update. After you’ve updated your OAB and pulled downed the latest copy in your outlook client you can then go into the GAL and view the photo. If you’re using Outlook in non-cached mode the thumbnail Photo is visible right away.

Other Scripts:

PS script to export AD user picture:

#
# Exporting AD user pictures
#
# Created: 04/11/2010
# Updated: 2016/03/22
#
# Author: jdalbera
# Comments:
#
#   Exporting AD user pictures
#
# Usage:
#    export-picturesinad.ps1 jdalbera
#    export-picturesinad.ps1 -all
#
#
param([Switch]$all, [String]$UserName)
#Default Values. Change them based on your environment.
cls
Write-Host “”
Write-Host “——————————————————-”
Write-Host ” Exporting AD User Pictures ”
Write-Host “——————————————————-”
Write-Host “”
If ( ! (Get-module ActiveDirectory )) {
Import-Module ActiveDirectory
}
## VARIABLES
$DefaultPhotoPath = ‘.\Pictures\fromAD\’
$date = Get-Date -Format ddMMyyyy
$log = “.\logs\Dump-ExportPicturesinAD-” + $date + “.csv”
Write-Host “”
## FUNCTIONS
Function DownloadOne(){
Write-Warning “Checking Photo in AD…”
Write-Host “Checking Photo in AD… ” -nonewline
$status = Get-ADUser -identity $UserName -properties thumbnailPhoto
If ($status){
Write-Host ” $UserName [AD picture found]” -ForeGroundColor Green
$Filename=$DefaultPhotoPath+$UserName+’.jpg’
#$Filename
$Picture = Get-ADUser -identity $UserName -properties thumbnailPhoto | select thumbnailPhoto
$Picture.thumbnailPhoto | Set-Content $FileName -Encoding byte
Write-Host ” $UserName [AD picture downloaded…]” -ForeGroundColor Green
Write-Output “$UserName,PictureDownloaded” >> $log
Write-Host “”
} Else {
Write-Host ” $UserName [AD picture not found]” -ForeGroundColor Red
Write-Output “$UserName,KO” >> $log
}
} #End function
Function DownloadAll(){
$files = 0
$userlist = Get-ADUser -Filter * -Properties thumbnailPhoto | ? {$_.thumbnailPhoto} | select Name,thumbnailPhoto,samaccountname
Foreach ($UserName in $userlist){
If ($Username.thumbnailphoto){
$User = $UserName.samaccountname
Write-Host ” $User [AD picture found]” -ForeGroundColor Green
$Filename=$DefaultPhotoPath+$UserName.samaccountname+’.jpg’
#$Filename
$UserName.thumbnailPhoto | Set-Content $FileName -Encoding byte
Write-Host ” $User [AD picture downloaded…]” -ForeGroundColor Green
Write-Output “$User,PictureDownloaded” >> $log
Write-Host “”
} Else {
$User = $UserName.samaccountname
Write-Host ” $User [AD picture not found]” -ForeGroundColor Red
Write-Output “$User,KO” >> $log
Write-Host “”
}
$files++
} #End foreach
Write-Host “–STATISTICS–” -BackgroundColor Blue -ForegroundColor White
Write-host “TOTAL “$files” Photo files processed” -BackgroundColor Yellow -ForegroundColor Black
Write-Host “”
} #End function
Function CheckAll(){
$files = 0
ForEach ($TempFile in Get-ChildItem $DefaultPhotoPath | Where-Object { $_.Extension -eq “.jpg” } )
{
$TempUserName = $TempFile.Name.substring(0, $TempFile.Name.Length – 4)
Write-Host $TempUserName -ForeGroundColor Yellow -NoNewLine
$status = get-aduser -identity $TempUserName -properties thumbnailPhoto | where {$_.thumbnailPhoto -eq “”}
If ($status -eq $null)
{
Write-Host ” [AD picture not found]” -ForeGroundColor Red
Write-Output “$TempUserName,KO” >> $log
Write-Host “”
}
Else
{
Write-Host ” [AD picture found]” -ForeGroundColor Green
Write-Output “$TempUserName,OK” >> $log
Write-Host “”
}
$files++
} #End foreach
Write-Host “–STATISTICS–” -BackgroundColor Blue -ForegroundColor White
Write-host “TOTAL “$files” Photo files processed” -BackgroundColor Yellow -ForegroundColor Black
Write-Host “”
} #End function
## MAIN
$startscript = Get-Date
write-host “”
If ($all -eq $true){
Write-Warning ” ## This action will check and download all pictures to .\Pictures\FromAD of the AD users.”
Write-Warning ” ## All pictures must have the same name of the usernames (samaccountname)”
Write-host “”
Write-Warning “Are you sure that you want check all pictures to the users (Y/N)?”
$Opt1 = Read-Host
If ($Opt1 -eq ‘y’)
{
CheckAll;
}
Write-host “”
Write-Warning “Are you sure that you want download all AD user pictures (Y/N)?”
$Opt2 = Read-Host
If ($Opt2 -eq ‘y’)
{
DownloadAll;
} Else { Write-Host “No changes were made.” -BackgroundColor Yellow -ForegroundColor Black }
}
Else
{
if ($UserName)
{
DownloadOne;
Write-Host “”
} Else {
$UserName = Read-Host “Enter a username (samaccountname)”
#Write-Host $UserName
DownloadOne;
Write-Host “”
}
}
Write-Host “”
#Start-Sleep 5
Write-Host “”
Write-Host “”
Write-Host “——————-”
Write-Host “– End of Script –”
Write-Host “——————-”
$stopscript = Get-Date
Write-Host “Has started at” $startscript -BackgroundColor Gray -ForegroundColor Black
Write-Host “Had finished at” $stopscript -BackgroundColor Gray -ForegroundColor Black
Write-Host “TIME SPENT:” (New-TimeSpan -Start $startscript -End $stopscript).hours “Hours” (New-TimeSpan -Start $startscript -End $stopscript).minutes “Minutes” (New-TimeSpan -Start $startscript -End $stopscript).seconds “Seconds” -BackgroundColor Green -ForegroundColor Black
Write-Host “”
Write-Host “”

 

PS script to import AD user picture:

#
# Configuring and using display picture in Exchange/Lync/Outlook
#
# Created: 04/11/2010
# Updated: 2016/03/22
#
# Author: jdalbera
# Comments:
#
#   Configuring and using display picture in Outlook/Exchange/Lync
#
# Usage:
#    import-picturesinad.ps1 jdalbera
#    import-picturesinad.ps1 -all
#
#
param([Switch]$all, [String]$UserName)
#Default Values. Change them based on your environment.
cls
Write-Host “”
Write-Host “—————————————————————-”
Write-Host ” Configuring and using display picture in Outlook/Exchange/Lync ”
Write-Host “—————————————————————-”
Write-Host “”
Write-Host “—–To RUN THIS Powershell Script, you must be a GAD admin L3—–”
Write-Host “”
If ( ! (Get-module ActiveDirectory )) {
Import-Module ActiveDirectory
}
## VARIABLES
$DefaultPhotoPath = ‘.\Pictures\FromSharepoint\’
$date = Get-Date -Format ddMMyyyy
$log = “.\logs\Dump-ImportPicturesinAD-” + $date + “.csv”
Write-Host “”
## FUNCTIONS
Function CheckPhotoIfExist(){
Write-Warning “Checking Photo in AD…”
Write-Host “Checking Photo in AD… ” -nonewline
$status = get-aduser -identity $UserName -properties thumbnailPhoto | where {$_.thumbnailPhoto -eq “”}
If ($status -eq $null)
{
Write-Host ” $UserName [AD picture not found]” -ForeGroundColor Red
Write-Output “$UserName,KO” >> $log
}
Else
{
Write-Host ” $UserName [AD picture found]” -ForeGroundColor Green
Write-Output “$UserName,OK” >> $log
Write-Host “”
#Exit
}
} #End function
Function CheckPhotoFile(){
Write-Warning “Validating file(s)..”
Write-Host “File exists… ” -nonewline
If (Test-Path $PhotoPath)
{
Write-Host ” $UserName [OK Photo file exist]” -ForeGroundColor Green
Write-host ” Photo size… ” -nonewline
$PhotoSize = Get-ChildItem $PhotoPath | select Length
If ($PhotoSize.Length -le 10000) { Write-Host “[OK]” -ForeGroundColor Green } Else { Write-Host “[Fail]” -ForeGroundColor Red; exit }
}
Else
{
Write-Host ” $UserName [Photo file not exist]” -ForeGroundColor Red
Write-Output “$UserName,Photo file not exist” >> $log
Write-Host “”
#Exit
}
} #End function
Function UploadOne(){
Write-Warning “Checking Photo in AD…”
Write-Host “Checking Photo in AD… ” -nonewline
$status = get-aduser -identity $UserName -properties thumbnailPhoto | where {$_.thumbnailPhoto -eq “”}
If ($status -eq $null)
{
Write-Host ” $UserName [AD picture not found]” -ForeGroundColor Red
Write-Output “$UserName,KO” >> $log

Write-Warning “Validating file(s)..”
Write-Host “File exists… ” -nonewline
If (Test-Path $PhotoPath) {
Write-Host ” $UserName [OK Photo file exist]” -ForeGroundColor Green
Write-host ” Photo size… ” -nonewline
$PhotoSize = Get-ChildItem $PhotoPath | select Length
If ($PhotoSize.Length -le 10000)
{ Write-Host “[OK]” -ForeGroundColor Green
Write-Host $UserName -ForeGroundColor Yellow -NoNewLine
Set-ADUser $UserName -Replace @{thumbnailPhoto=([byte[]](Get-Content $PhotoPath -Encoding byte))}
Write-Host ” [AD picture uploaded…]” -ForeGroundColor Green
Write-Output “$UserName,NewPictureUploaded,OK” >> $log
Write-Host “”
} Else { Write-Host “[Fail]” -ForeGroundColor Red; exit }
} #End if
Else
{
Write-Host ” $UserName [Photo file not exist]” -ForeGroundColor Red
Write-Output “$UserName,Photo file not exist” >> $log
Write-Host “”
Write-Host “”
}
} #End if
Else
{
Write-Host ” $UserName [AD picture found]” -ForeGroundColor Green
Write-Output “$UserName,OK” >> $log
Write-Host “”
}
} #End function

Function UploadAll(){
$files = 0
ForEach ($TempFile in Get-ChildItem $DefaultPhotoPath | Where-Object { $_.Extension -eq “.jpg” } )
{
$TempUserName = $TempFile.Name.substring(0, $TempFile.Name.Length – 4)
$status = get-aduser -identity $TempUserName -properties thumbnailPhoto | where {$_.thumbnailPhoto -eq “”}
If ($status -eq $null)
{
Write-Host ” $TempUserName [AD picture not found]” -ForeGroundColor Red
Write-Host $TempUserName -ForeGroundColor Yellow -NoNewLine
Set-ADUser $TempUserName -Replace @{thumbnailPhoto=([byte[]](Get-Content $TempFile.FullName -Encoding byte))}
Write-Host ” [AD picture uploaded…]” -ForeGroundColor Green
Write-Output “$TempUserName,NewPictureUploaded,OK” >> $log
Write-Host “”
}
Else
{
Write-Host ” $TempUserName [AD picture found]” -ForeGroundColor Green
Write-Output “$TempUserName,OK” >> $log
Write-Host “”
}
$files++
} #End foreach
Write-Host “–STATISTICS–” -BackgroundColor Blue -ForegroundColor White
Write-host “TOTAL “$files” Photo files processed” -BackgroundColor Yellow -ForegroundColor Black
Write-Host “”
} #End function
Function CheckAll(){
$files = 0
ForEach ($TempFile in Get-ChildItem $DefaultPhotoPath | Where-Object { $_.Extension -eq “.jpg” } )
{
$TempUserName = $TempFile.Name.substring(0, $TempFile.Name.Length – 4)
Write-Host $TempUserName -ForeGroundColor Yellow -NoNewLine
$status = get-aduser -identity $TempUserName -properties thumbnailPhoto | where {$_.thumbnailPhoto -eq “”}
If ($status -eq $null)
{
Write-Host ” [AD picture not found]” -ForeGroundColor Red
Write-Output “$TempUserName,KO” >> $log
Write-Host “”
}
Else
{
Write-Host ” [AD picture found]” -ForeGroundColor Green
Write-Output “$TempUserName,OK” >> $log
Write-Host “”
}
$files++
} #End foreach
Write-Host “–STATISTICS–” -BackgroundColor Blue -ForegroundColor White
Write-host “TOTAL “$files” Photo files processed” -BackgroundColor Yellow -ForegroundColor Black
Write-Host “”
} #End function
## MAIN
$startscript = Get-Date
write-host “”
If ( $all -eq $true)
{
Write-Warning ” ## This action will check and upload all pictures of .\Pictures\FromSharepoint to the AD users.”
Write-Warning ” ## All pictures must have the same name of the usernames (samaccountname)”
Write-host “”
Write-Warning “Are you sure that you want check all pictures to the users (Y/N)?”
$Opt1 = Read-Host
If ( $Opt1 -eq ‘y’ )
{ CheckAll;
}

Write-host “”
Write-Warning “Are you sure that you want upload all missing pictures to the users (Y/N)?”
$Opt2 = Read-Host
If ( $Opt2 -eq ‘y’ )
{ UploadAll;
} Else { Write-Host “No changes were made.” -BackgroundColor Yellow -ForegroundColor Black }
}
Else
{
$PhotoPath = $DefaultPhotoPath + $UserName + ‘.jpg’
Write-Host $PhotoPath
#CheckPhotoIfExist;
#CheckPhotoFile;
UploadOne;
Write-Host “”
}
Write-Host “”
#Start-Sleep 5
Write-Host “”
Write-Host “”
Write-Host “——————-”
Write-Host “– End of Script –”
Write-Host “——————-”
$stopscript = Get-Date
Write-Host “Has started at” $startscript -BackgroundColor Gray -ForegroundColor Black
Write-Host “Had finished at” $stopscript -BackgroundColor Gray -ForegroundColor Black
Write-Host “TIME SPENT:” (New-TimeSpan -Start $startscript -End $stopscript).hours “Hours” (New-TimeSpan -Start $startscript -End $stopscript).minutes “Minutes” (New-TimeSpan -Start $startscript -End $stopscript).seconds “Seconds” -BackgroundColor Green -ForegroundColor Black
Write-Host “”
Write-Host “”