GAL Photos in Exchange 2010 and Outlook 2010
Published Mar 10 2010 07:51 PM 379K Views
Microsoft

Over the years, displaying recipient photographs in the Global Address List (GAL) has been a frequently-requested feature, high on the wish lists of many Exchange folks. Particularly in large organizations or geographically dispersed teams, it's great to be able to put a face to a name for people you've never met or don't frequently have face time with. Employees are commonly photographed when issuing badges/IDs, and many organizations publish the photos on intranets.

There have been questions about workarounds or third-party add-ins for Outlook, and you can also find some sample code on MSDN and elsewhere. A few years ago, an unnamed IT person wrote ASP code to make employee photos show up on the intranet based on the Employee ID attribute in Active Directory - which was imported from the company's LDAP directory. A fun project to satisfy the coder alter-ego of the said IT person.

Luckily, you won't need to turn to your alter-ego to do this. Exchange 2010 and Outlook 2010 make this task a snap, with help from Active Directory. Active Directory includes the Picture attribute (we'll refer to it using its ldapDisplayName: thumbnailPhoto) to store thumbnail photos, and you can easily import photos— not the high-res ones from your 20 megapixel digital camera, but small, less-than-10K-ish ones, using Exchange 2010's Import-RecipientDataProperty cmdlet.

Photos in Active Directory? Really?

The first question most IT folks would want to ask is— What's importing all those photos going to do to the size of my Active Directory database? And how much Active Directory replication traffic will this generate? The thumbnailPhoto attribute can accomodate photos of up to 100K in size, but the Import-RecipientDataProperty cmdlet won't allow you to import a photo that's larger than 10K. (Note, the attribute limit was stated as 10K earlier. This has been updated to state the correct value. -Bharat)

The original picture used in this example was 9K, and you can compress it further to a much smaller size - let's say approximately 2K-2.5K, without any noticeable degradation when displayed at the smaller sizes. If you store user certificates in Active Directory, the 10K or smaller size thumbnail pictures are comparable in size. Storing thumbnails for 10,000 users would take close to 100 Mb, and it's data that doesn't change frequently.

Note: The recommended thumbnail photo size in pixels is 96x96 pixels.

With that out of the way, let's go through the process of adding pictures.

A minor schema change

First stop, the Active Directory Schema. A minor schema modification is required to flip the thumbnailPhoto attribute to make it replicate to the Global Catalog.

Note: If you're on Exchange 2010 SP1, skip this step. The attribute is modified by setup / SchemaPrep.

  1. If you haven't registered the Schema MMC snap-in on the server you want to make this change on, go ahead and do so using the following command:

    Regsvr32 schmmgmt.dll

  2. Fire up a MMC console (Start -> Run -> MMC) and add the Schema snap-in
  3. In the Active Directory Schema snap-in, expand the Attributes node, and then locate the thumbnailPhoto attribute. (The Schema snap-in lists attributes by its ldapDisplayName).
  4. In the Properties page, select Replicate this attribute to the Global Catalog, and click OK.

    Figure 1: Modifying the thumbnailPhoto attribute to replicate it to Global Catalog

Loading pictures into Active Directory

Now you can start uploading pictures to Active Directory using the Import-RecipientDataProperty cmdlet, as shown in this example:

Import-RecipientDataProperty -Identity "Bharat Suneja" -Picture -FileData ([Byte[]]$(Get-Content -Path "C:\pictures\BharatSuneja.jpg" -Encoding Byte -ReadCount 0))

To perform a bulk operation you can use the Get-Mailbox cmdlet with your choice of filter (or use the Get-DistributionGroupMember cmdlet if you want to do this for members of a distribution group), and pipe the mailboxes to a foreach loop. You can also retrieve the user name and path to the thumbnail picture from a CSV/TXT file.

Thumbnails in Outlook 2010

Now, let's fire up Outlook 2010 and take a look what that looks like.

In the Address Book/GAL properties for the recipient


Figure 2: Thumbnail displayed in a recipient's property pages in the GAL

When you receive a message from a user who has the thumbnail populated, it shows up in the message preview.


Figure 3: Thumbnail displayed in a message

While composing a message, the thumbnail also shows up when you hover the mouse on the recipient's name.


Figure 4: Recipient's thumbnail displayed on mouse over when composing a message

There are other locations in Outlook where photos are displayed. For example, in the Account Settings section in the Backstage Help view.

Update from the Outlook team

Our friends from the Outlook team have requested us to point out that the new Outlook Social Connector also displays GAL Photos, as well as photos from Contacts folders and from social networks, as shown in this screenshot.


Figure 5: Thumbnail photos displayed in the People Pane in the Outlook Social Connector

More details and video in Announcing the Outlook Social Connector on the Outlook team blog.

GAL Photos and the Offline Address Book

After you've loaded photos in Active Directory, you'll need to update the Offline Address Book (OAB) for Outlook cached mode clients. This example updates the Default Offline Address Book:

Update-OfflineAddressBook "Default Offline Address Book"

In Exchange 2010, the recipient attributes included in an OAB are specified in the ConfiguredAttributes property of the OAB. ConfiguredAttributes is populated with a default set of attributes. You can modify it using the Set-OfflineAddressBook cmdlet to add/remove attributes as required.

By default, thumbnailPhoto is included in the OAB as an Indicator attribute. This means the value of the attribute isn't copied to the OAB— instead, it simply indicates the client should get the value from Active Directory. If an Outlook client (including Outlook Anywhere clients connected to Exchange using HTTPS) can access Active Directory, the thumbnail will be downloaded and displayed. When offline, no thumbnail downloads. Another example of an Indicator attribute is the UmSpokenName.

You can list all attributes included in the default OAB using the following command:

(Get-OfflineAddressBook "Default Offline Address Book").ConfiguredAttributes

For true offline use, you could modify the ConfiguredAttributes of an OAB to make thumbnailPhoto a Value attribute. After this is done and the OAB updated, the photos are added to the OAB (yes, all 20,000 photos you just uploaded...). Depending on the number of users and sizes of thumbnail photos uploaded, this would add significant bulk to the OAB. Test this scenario thoroughly in a lab environment— chances are you may not want to provide the GAL photo bliss to offline clients in this manner.

To prevent Outlook cached mode clients from displaying thumbnail photos (remember, the photo is not in the OAB – just a pointer to go fetch it from Active Directory), you can remove the thumbnailPhoto attribute from the ConfiguredAttributes property of an OAB using the following command:

$attributes = (Get-OfflineAddressBook "Default Offline Address Book").ConfiguredAttributes
$attributes.Remove("thumbnailphoto,Indicator")
Set-OfflineAddressBook "Default Offline Address Book" -ConfiguredAttributes $attributes

Bharat Suneja

Updates:

  • 11/3/2010: Corrected size limit of thumbnailPhoto attribute to 100K.
  • 8/25/2011: Added note to reflect Exchange 2010 SP1 setup / SchemaPrep modifies thumbnailPhoto attribute to replicate to Global Catalog.
  • GAL Photos now has an FAQ. Check out GAL Photos: Frequently Asked Questions.

To visit this post again, use the short URL aka.ms/galphotos. To go to the 'GAL Photos: Frequently Asked Questions' post, use aka.ms/galphotosfaq.

55 Comments
Not applicable
The command above is not correct the right is.

Import-RecipientDataProperty -Identity "Bharat Suneja" -Picture -FileData ([Byte[]]$(Get-Content -Path "C:picturesBharatSuneja.jpg" -Encoding Byte -ReadCount 0))

Thanks for the great Article

Regards Steven
Not applicable
"Are you serious? You cannot be serious!" to paraphrase a famous tennis player... Ever heard about usability? How can users themselves update their picture? Can't there be a GUI for that?
Not applicable
Hi, I've tried this a couple of moth ago and it works. But I don't find it easy for Human Resources personal to manage. I agree with Simon, a GUI app would be nice. Active directory administrative center would be a good place to manage this. Also, there is no OWA support for the pictures or windows 7 user picture support.

none the less, you are doing an excellent job with exchange :D
Not applicable
@Simon, do you trust all of your users to update their picture and not put something completely inappropriate into the GAL? :)

@Bharat, great article! Is it worth mentioning 96x96 pixels might be the most optimal size so Outlook doesn't squish larger photos down and distort them?
Not applicable
Now if we could just get this to integrate with Sharepoint...
Not applicable
@Steven: Thanks for catching that - updated.
@Simon & Julian: Thanks for the feedback. (As a side note, consider that you're not likely to add/change photos more than once or twice for the lifetime a user account.)
Not applicable
"As a side note, consider that you're not likely to add/change photos more than once or twice for the lifetime a user account."
I work in a K-12 school where all students have AD / Exchange accounts (yes even 5 year olds).  I would wager that if added a picture when they are 5 they might want a different one by age 18.  We use our yearbook pictures in other DB updated at least yearly.  It would be great to have AD be a single source of those pictures.
Not applicable
This also works with Exchange 2007, the only thing missing is the cmdlet to upload photos.  

For a vbs script to do batch uploads look here: http://www.arricc.net/active-directory-photos-sharepoint.php

Note you must edit the script to change jpegphoto to thumbnailphoto.
Not applicable
@GT: Yes - the thumbnailPhoto attribute has been around. Exchange 2010 adds the cmdlet to upload photos. Outlook 2010 displays the photos.

Other tools, including VBS scripts as you suggested, can do the same thing.
Not applicable
Excellent post! It would be great to have this in EMC or ADUC, but not sure about allowing users to do this from Outlook. Our Security team would never allow users to update their own photos.
Not applicable
I love having this capability now.  Does the photo display in OWA? Outlook Anywhere is fantastic, but there are times a browser's more convenient.
Not applicable
@bday: Thanks for the feedback. Yes, the recommended size is in fact 96x96.
@GT: Forgot to add in previous response - the OAB support is in Exchange 2010.
@Evans: No, it's not in OWA.
Not applicable
@GT: The code that does that upload uses a jpegPhoto attribute... any idea why that was used over thumbnailPhoto? Can the whole thing be re-written to thumbnailPhoto?

@MSFT: Too bad OWA isn't included. Being that it isn't, is the only thing provided the Exchange 2010 (other than the upload script that can be worked around) the OAB support?
Not applicable
It's possible to simply set up SharePoint 2010 to publish photos to the Active Directory, without using these commandlets. These are just great tools for admins to do them without end user involvment.
Not applicable
Here is the vbs with jpegphoto replaced to thumbnailphoto.  I've tested it, it works ...

-------------------
'Photos must be less than 10kb
Const ForReading = 1
InDir = "C:TempStaffPhotos"
Set fso = CreateObject("Scripting.FileSystemObject")
set oIADS = GetObject("LDAP://RootDSE")
strDefaultNC = oIADS.Get("defaultnamingcontext")
Set theConn = CreateObject("ADODB.Connection")
theConn.Provider = "ADsDSOObject"
theConn.Open "ADs Provider"
Set theCmd  = CreateObject("ADODB.Command")
theCmd.ActiveConnection = theConn
Set objRecordSet = CreateObject("ADODB.Recordset")
For Each tFile In fso.GetFolder(InDir).Files
   tName = tFile.Name
   'Gets the persons Name from the file by stripping the extention.
   tName = Left(tName, InStrRev(tName,".")-1)
   'You may need to tweak this bit depending on your naming conventions.
   strQuery = "<LDAP://" & strDefaultNC & ">;" & _
                             "(&(objectClass=person)(name=" & tName & "));name,adspath;subtree"
   theCmd.CommandText = strQuery
   Set objRS = theCmd.Execute
   If objRS.RecordCount = 0 Then
     MsgBox "Can't find account for " & tName
   Else
     Set objUser = GetObject(objRS("adspath"))
     ObjUser.Put "thumbnailPhoto", ReadByteArray(tFile.Path)
     ObjUser.SetInfo
   End If
Next
'Stolen from http://www.ericphelps.com/q193998/index.htm
Function ReadByteArray(strFileName)
   Const adTypeBinary = 1
   Dim bin
   Set bin = CreateObject("ADODB.Stream")
   bin.Type = adTypeBinary
   bin.Open
   bin.LoadFromFile strFileName
   ReadByteArray = bin.Read
End Function
Not applicable
@GT: Thanks for posting.
@Everyone: The usual disclaimers about scripts/code downloaded from the Internet apply. Please test thoroughly in sandbox before using in production.
Not applicable
@Bharat: Do you have any insight into wether the thumbnailPhoto attribute is/will be used for the user account picture?
Not applicable
Thanks for a wonderful post. Looking forward to Outlook 2010 (Office 2010) RTM!
Not applicable
"Noone will ever want a picture greater than 10K" - Bill Gates

For real?  It's the 2010 version of EXCHANGE and it doesn't even support a proper profile image.....
Not applicable
10k is fine (for now at least). With a properly compressed image you can get a pretty good 96x96 picture out of it. We don't need to fill our GALs with everyone's 2GB beauty shots from the mall photo store in RAW format. :)
Not applicable
@Exchange?: The attribute name says it all - it's a thumbnail photo.
@bday: The sample image used in the post was a 9k original, optimized to <2.5k. 10K is a lot for a thumbnail!. :)
Not applicable
@Bahrat Right it's just a thumbnail..   check out the competition that the majority of exchange 2003/07 users are moving to.  Gmail doesn't have silly limitations imposed on it because it's using an LDAP server as it's datastore.  Just like the mobile space, MS is going to lose its foothold in enterprise mail because of silly little things like this.
Not applicable
@Bharat Suneja [MSFT]: A GUI (perhaps SharePoint 2007 and 2010 could be the interface - and you can't assume just because a company has Exchange 2010 it has SharePoint 2010!) is desperately needed to allow staff photo's to be uploaded and stored in AD. I want my HR department to be able to do this whenever they want and not burden the IT department with this.
Not applicable
@Exchange?:  Being the one who would have to manage 2mb photos being replicated to remote sites over $30,000 128k satalite links, I am extraordinarily grateful for the size limits.  This is indeed a thumbnail.  Links to full pictures can be stored in any number of other locations.  You do not want a large picture replicating to every DC in an enterprise.  I'm sure your SMB can continue to work just fine on Google AppX, but the MS has actually through this one through on something more than just a micro scale, which is the way you are thinking.

Think globally, and you will quickly see that size limitations are important.

P.S.  Let me know how your offline access to GMail contact pictures are working for you.
Not applicable
I'm trying to make a simple uploading application in Visual Basic.Net. I have most if it working... I can choose a user, I can select part of a photo, and I can save that to AD. I can retrieve that data out of the thumbnailPhoto attribute and display that picture back into VB.net. I can even use it as embedded data in PHP, but for some reason it's not displaying in Outlook 2010. Anybody have an brilliant ideas? Here's some relevant code (note: this is partial code, not the whole app):

-------------------- Saving to AD in VB.net -------------------------
       Dim myUser As New DirectoryServices.DirectoryEntry("LDAP://" & userDN)
       Dim stream As New IO.MemoryStream
       Dim img As Image
       Dim ptr As IntPtr

       ' Clear any existing photo
       myUser.Properties("thumbnailPhoto").Clear()

       ' Make sure our size is 96x96
       img = picPreview.Image.GetThumbnailImage(96, 96, thumbnail_abort, ptr)

       ' Convert the img to a byte array for storage in AD
       img.Save(stream, Imaging.ImageFormat.Jpeg)
       Dim b(stream.Length) As Byte
       stream.Position = 0
       stream.Read(b, 0, stream.Length)

       ' Store the image
       myUser.Properties("thumbnailPhoto").Add(b)
       myUser.CommitChanges()


------------ Retrieving from AD in VB.net -------------------

       picOriginal.Image = Nothing
       Dim myUser As New System.DirectoryServices.DirectoryEntry("LDAP://" & userDN)
       Dim b() As Byte
       b = myUser.Properties("thumbnailPhoto").Value
       If b IsNot Nothing Then
           picPreview.Image = Image.FromStream(New IO.MemoryStream(b))
       End If

--------------- Using as a data URL in PHP --------------------
[[ $u is populated from the ldap_get_entries() function ]]
<img style='float:left; padding-right:5px;' src='data:image/jpeg;base64,".base64_encode($u['thumbnailphoto'][0])."'>

------------------------------------------------

As mentioned above, both of the retrieval functions display the thumbnailPhoto as expected, but it's still not showing up in Outlook. I double checked the schema change mentioned above and I know for sure the PHP code is using data from the Global Catalog.
Not applicable
By the way: I have build 14.0.4536.1000 (which I just downloaded after I read this article) that I'm trying to test with.
Not applicable
"For true offline use, you could modify the ConfiguredAttributes of an OAB to make thumbnailPhoto a Value attribute"

How exactly is this attribute set?
Not applicable
What about adding something useful to AD for a change. I am crying and begging for years to have "Languages" and "Preferred language" as a part of the users AD. Guess what: In Europe it gets quite difficult to send automated messages to different people working in different countries using a language they understand. No 3rd party tool can rely on what should be a key part of the user account properties, so I have to mess around with scripts and custom properties.

GAL Photos? Thanks for solving a problem that I never had!
Not applicable
Even though I still don't have it working in Outlook 2010, I thought it might be nice if there was some way to have the thumbnailPhoto be used as the User Account Picture on Windows 7. It looks like that's not something supported out of the box. So I thought maybe it'd be possible to write a small .Net app that could run on login and would pull the picture out of AD and set it as the users Account picture. Seems that it's not possible to progmatically set this picture at all :(.

I know that's more of a Windows Team issue than an Exchange Team issue, but this is where the thumbnailPhoto seems to be being discussed right now.
Not applicable
@Mikael & Jake: We've passed on the feedback to the Windows team.
@Jake: Export-RecipientDataProperty (http://technet.microsoft.com/en-us/library/dd298157.aspx) will let you export the picture from AD (but won't meet your requirements of having this run from user workstations... ).
Not applicable
Excellent post!! End-user ability to do this in ECP would be great! Also having the photo pulled from AD and displayed on user workstation.
Not applicable
This is useful information.  I am curious, however, as to why the attribute needs to be replicated in the GC?  Is it for quicker resolution of the photos?  Does the photo itself get copied to the GAL as well, or just OAB?

I'm wondering why being stored in AD is not sufficient.  You indicate that if a client "can access AD, the thumbnail will be downloaded and displayed".  Is that the case (access to AD only), or does it require to gather the image from the Global Catalog?
Not applicable
@Bharat: Getting the picture back out of AD is no problem in Visual Basic.Net ... It's really as easy as:

-----------
Dim myUser As New System.DirectoryServices.DirectoryEntry("LDAP://" & userDN)
Dim b() As Byte
b = myUser.Properties("thumbnailPhoto").Value
If b IsNot Nothing Then
   picPreview.Image = Image.FromStream(New IO.MemoryStream(b))
End If
-----------

To get it into a picture box. The issue is getting it set as the user's account picture.

Also, I still haven't gotten the pictures to show up in Outlook 2010 Beta build 14.0.4536.1000. Do you know if it's supported in that build? Or should I contact the Office Beta team to try and figure out what went wrong?

Thanks again.
Not applicable
@Jake: That build of Outlook and the previous public one both support pictures. We've been using them at work for a while. I'd contact the Office team and see what's up.
Not applicable
@Dean: GAL (Global Address List) and Address Lists are views of recipient information in Active Directory. So you're not copying anything in a GAL/Address List. For OABs, thumbnailPhoto is included as indicator attribute (the picture isn't actually copied to the OAB).

Global Catalog is just another partition on a Domain Controller that contains partial replica of objects from all domains in the forest. Exchange looks up GCs for user information. In a multi-domain environment, GCs allow you to quickly lookup the replicated info.

Note, you don't need to set the attribute to replicate to GCs in a single-domain environment - it works without the change.
Not applicable
Russian version of this post is here:
Русская версия статьи здесь: http://www.maximumexchange.ru/2010/03/15/gal-photos-in-exchange-2010-and-outlook-2010/
Not applicable
Anyone any idea why, after replicating thumbnailphoto to the GC, using the script to upload the <10k jpg file (and can see it in ADISEDIT)....does it not display the thumbnail in Outlook 2010 ?  I have it working fine in a test environment which is a  single 2008 domain (so I know the upload script works!), but in a 2003R2 multi domain...it doesn't display ?

Any help appreciated

Stuart
Not applicable
@Stuart: Does it work in online mode? If a Cached Mode issue, are you on Exchange 2010? (The OAB support is in Exchange 2010, as mentioned in the post) And has the OAB been updated?
Not applicable
No, it does NOT work in Online mode either :(
We are using e2k3, the OAB gets updated twice a day, and the client (using Outlook 2010) obviously grabs the AB as required.

In our testlab, we have the same version Outlook 2010 client (RC code) in cached mode, against a 2008 single domain, E2k3 servers and that does work just fine.
Not applicable
To bump what Janne said:

"For true offline use, you could modify the ConfiguredAttributes of an OAB to make thumbnailPhoto a Value attribute"

How exactly is this attribute set?
You only show how to remove it.
Not applicable
Quick Question to see if anyone has an opinion:

E2k7 with no plans to go to E2k10 for at least a year (financial reasons).

Would it make more sense to try and implement pictures in AD via the aforementioned VBS script or just wait until I go to e2k10 before I have this function?  

I.e. I wouldn't want to go through a ton of work to get all of these pictures updated and working in 2k7 via custom scripting only to have to redo all of that work when I go to 2k10.  Or... if I do this in 2k7 using the modifiy attribute, is it likely that I won't have to redo the work because the same attribute will be used in 2k10 for the pic?
Not applicable
"For true offline use, you could modify the ConfiguredAttributes of an OAB to make thumbnailPhoto a Value attribute"

Yes please!
Not applicable
@Stuart: I don't know if it has to do with the actual DC running Windows Server 2008 or just the schema change, but as you can see above I had a ton of issues getting this to work in Outlook 2010 Beta w/Exchange 2007 and Windows Server 2003 R2 domain controllers. This past week I updated the first production DC in our forest (which is also at my site) to Windows Server 2008 R2. I didn't even think about this issue so I didn't test between the schema change and the DC upgrade, but when I fired up Outlook 2010 for unrelated reasons, I found the pictures suddenly working! I'm pretty sure I didn't change anything other than the DC between the last time I noticed it not working and when it started working.

So, if anybody's interested in it, the VB.net code I've posted above will set the thumbnailPhoto. Oh, and the PHP code I worked will only work on browsers that support inline images, which does not include Internet Explorer.
Not applicable
@Izac: None of the code I've seen above is specific to Exchange 2010 (other than the cmdlet stuff posted by the Exchange Team). The .vbs code posted by GT and the VB.net code posted by myself load the images into Active Directory. The site GT links to talks about modifying SharePoint to display those images.

So, my semi-informed opinion on this is that there's no reason to hold off. I'm not. I'm loading images (a little at a time) right now. We probably won't even be using Outlook 2010 anywhere but the IT dept. for a year or longer, but I'm also displaying the images on our intranet using custom PHP code.
Not applicable
I have already imply the photo inside my profile of Exchange 2010. But I cannot find my photo in GAL which I'm now using OL2007. Is it compatible?
Not applicable
We are running Exchange 2003/2010 in mixed mode and slowly moving mailboxes across to Exchange 2010. We also use a combination of Outlook 2003 and 2007.

Does this only work in a pure Exchange 2010 and Outlook 2010 environment?

Thanks

Neal
Not applicable
@Neal & Toniko: Outlook 2010 and Active Directory 2008 servers (or maybe just the schema, I'm not sure) seem to be the key to getting photos to show up in the GAL. I don't have any Exchange 2010 servers, though I do have one 2007 on my network (and 6 2003). My mailbox is on the 2007 server, but I'd image it would still work if I was on a 2003 server.

However, in order to add the images to the offline address book, I think you need Exchange 2010.
Not applicable
There is a schema update required to enable this if you're running 2003 DC's and have never updated the schema beyond that.  I'm not sure exactly the versions, but we had all 2003 R2 DC's and it wasn't working.  Worked with MS for what seemed like weeks and finally found a difference between their test environment and ours.  All I had to do in the end was do the 2008 R2 forest/domain prep and the pictures magically appeared.

The parameter in question was in schema attribute "Picture" the "mAPIID" attribute should be "35998".  In our older version of the schema is was "not set".  Was advised not to update this manually but to instead do the prep.

We are running 100% on Exchange 2007 and it works great as long as Outlook can talk to AD (if Outlook is offline, you don't get pictures and there is no cache).  With Exchange 2010 you get the offline capability using OAB.

We wrote some custom syncing code similar to above that pulls the pictures from our ID badge database and samples them down to 96x96.

Works great!
Not applicable
And what about removing a picture?

Please a GUI is absolutely required!
Not applicable
We had photos already uploaded because we used another program (rdirectory) for our online directory. They are showing up fine and all but we had some concern that they may be sent outside the company. I am assuming this just does an internal look up and they are not actually attached to the emails?
Version history
Last update:
‎Jul 01 2019 03:50 PM
Updated by: