Upload picture in Outlook 2010 using the Exchange Management Shell (Exchange 2010)

While prepping for one of my sessions @ TechEd Berlin on managing and administering Exchange 2010, I was looking for a demo to illustrate the changes introduced with Remote Powershell  when importing and exporting files. That's when I stumbled into the Exchange Management Shell cmdlet Import-RecipientDataProperty, which is described in the following TechNet article: Import-RecipientDataProperty.

So here are the steps to get a picture uploaded into Active Directory, in this example my user Ilse doesn't have a picture yet

Step 1. Get a picture

You need a JPEG file, limited in size to 10 kilobytes!

Step 2. Run the Exchange Management Shell cmdlet Import-RecipientDataProperty

Run the Exchange Management Shell cmdlet to upload the picture. Running it will populate Active Directory with the picture, more specifically the attribute called thumbnailPhoto will be populated. Make sure this attribute is replicated to the Global Catalog (big thank you to Astrid for helping me out with this one :-)) .

Before running the cmdlet, the attribute doesn't have a value:

 Check if the attribute is replicated to the Global Catalog, by using for example the Schema Snap-In:

Run the following cmdlet:

Few remarks:

- there is no need to refer to a UNC path, you can locate the file anywhere

- remember the limit of 10KB!!

After running this, Active Directory will be populated:

And after restarting Outlook, the picture will be there :-)

 

-Ilse

Follow-up: If you want to know if this will work with Exchange 2003-Exchange 2007, click this link:

http://blogs.technet.com/ilvancri/archive/2010/01/08/follow-up-import-recipientdataproperty.aspx

Comments

  • Anonymous
    January 01, 2003
    The comment has been removed

  • Anonymous
    January 01, 2003
    I actually got this working in a 2003 Native AD forest without any of the 2008 and up schema extensions. The thumbnailPhoto attribute is there, though I'm not sure what schema update added them. I do have the Exchange 2010 schema updates, so maybe that added them. The step I did forget was replicating the attribute to the global catalog. Once I did that, it all worked like a charm.

  • Anonymous
    January 01, 2003
    Hi, where should I start trouble shooting if the thumbnailPhoto attribute is populated and I can export the users photo using powershell but no contact photos are showing in Outlook? Thanks

  • Anonymous
    January 01, 2003
    Where are the pictures physically stored? In AD, in the db somewhere or in the user's mailbox on the Exchange server?

  • Anonymous
    January 01, 2003
    I'm confused... why does every single article on the internet state that this attribute is limited to 10 KB when it is actually 100 KB ? Look at the screenshot in this blog post of the thumbnailPhoto attribute properties and you can see the maximum is 102400 (bytes) which is 100 KB. I thought maybe I was missing something obvious but I just confirmed it by uploading an image into this attribute that was roughly 90 KB - it worked fine. When I tried to upload an image that was 120 KB however it failed with the error  "a constraint violation occurred" which is exactly what you would expect if the attribute is limited to 100 KB. I don't know if the powershell cmdlets that come with Exchange 2010 prevent you from actually choosing an image larger than 10 KB though... but if anyone wants a free easy to use GUI program for uploading single or multiple images, I've nearly finished making such a program. You can find more info on my blog here: cjwdev.wordpress.com/.../ad-photo-edit-a-program-for-uploading-images-into-the-active-directory-thumbnailphoto-attribute-used-by-outlook-2010

  • Anonymous
    January 01, 2003
    Thanks for the tip - nice feature, it would be really good if the clients could change this. Just a reminder (as it took me a while to remember/find) to set the attribute to sync, first register the schema plugin with "regsvr32 schmmgmt.dll" Run mmc, add Active Directory Schema

  • Anonymous
    January 01, 2003
    @ctobio: you dont need a forest prep or anything else to get this work....this works with a native 2003 ad, too. No need to prep

  • Anonymous
    January 01, 2003
    Information is stored in active directory database -Ilse

  • Anonymous
    November 12, 2010
    Hi, i have developed a GUI application for managing the thumbnailPhoto Attribute, too. You can find it on my blog here: www.starcoder.net/thumbnailphoto-tool

  • Anonymous
    November 17, 2010
    Yavuz, I'm a bit disappointed that your app won't even open if you are not running it on a computer that is a member of a domain. I wanted to try it out from my home PC against a test domain over a VPN.

  • Anonymous
    November 18, 2010
    hi, if we implement Outlook 2010 contact picture adding on Exch 2003, does anyone know what attribute in AD will the pics be stored?

  • Anonymous
    November 24, 2010
    Chris128, hello Chris thank you for your respond. The reason is, that the tool allows the current logged in user to change his photo or another persons /accounts photo in the ad. That emans the that it tries to connect top the ad with your current credentials. I will have a look for extending the application, so that you provide different credentials to connect to the ad. thank you. best regards Yavuz

  • Anonymous
    November 25, 2010
    The comment has been removed

  • Anonymous
    November 25, 2010
    Abbas, it still uses the same AD attribute - thumbnailPhoto

  • Anonymous
    January 07, 2011
    Codez: Updates two attributes so that it also shows up in Cisco Unified Presence as well as Outlook 2010. Cheers form1.cs ------------------------------------------   using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.DirectoryServices; namespace WindowsFormsApplication1 {    public partial class Form1 : Form    {        public Form1()        {            InitializeComponent();        }        private void button1_Click(object sender, EventArgs e)        {            AddPictureToUser("cn=" + txtUserName.Text + "," + txtLDAPString.Text, txtDomainController.Text, txtImageLocation.Text);        }        void AddPictureToUser(string strDN, string strDCName, string strFileName )        {            try            {                // Open file                System.IO.FileStream inFile = new System.IO.FileStream(strFileName, System.IO.FileMode.Open, System.IO.FileAccess.Read);                // Retrive Data into a byte array variable                byte[] binaryData = new byte[inFile.Length];                int bytesRead = inFile.Read(binaryData, 0, (int)inFile.Length);                inFile.Close();                inFile.Dispose();                // Connect to AD                System.DirectoryServices.DirectoryEntry myUser = new System.DirectoryServices.DirectoryEntry(@"LDAP://" + strDCName + @"/" + strDN);                // Clear existing picture if exists                if (myUser.Properties["jpegPhoto"] != null)                {                    myUser.Properties["jpegPhoto"].Clear();                }                // Update attribute with binary data from file                myUser.Properties["jpegPhoto"].Add(binaryData);                if (myUser.Properties["thumbnailPhoto"] != null)                {                    myUser.Properties["thumbnailPhoto"].Clear();                }                myUser.Properties["thumbnailPhoto"].Add(binaryData);                myUser.CommitChanges();                myUser.Close();                myUser.Dispose();                binaryData = null;                MessageBox.Show("Done!");            }            catch (Exception ex)            {                MessageBox.Show("Error: " + ex.Message, "FUUUUU... You are doing it wr-", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Error);            }        }        private void button2_Click(object sender, EventArgs e)        {            ofd.ShowDialog();            if (ofd.FileName.Length > 0)            {                this.txtImageLocation.Text = ofd.FileName;                try                {                    this.panel1.BackgroundImage = Image.FromFile(ofd.FileName);                    this.panel1.BackgroundImageLayout = ImageLayout.Stretch;                }                catch (Exception ex1)                {                    MessageBox.Show(ex1.ToString());                }            }        }    } }


namespace WindowsFormsApplication1 namespace WindowsFormsApplication1 {    partial class Form1    {        /// <summary>        /// Required designer variable.        /// </summary>        private System.ComponentModel.IContainer components = null;        /// <summary>        /// Clean up any resources being used.        /// </summary>        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>        protected override void Dispose(bool disposing)        {            if (disposing && (components != null))            {                components.Dispose();            }            base.Dispose(disposing);        }        #region Windows Form Designer generated code        /// <summary>        /// Required method for Designer support - do not modify        /// the contents of this method with the code editor.        /// </summary>        private void InitializeComponent()        {            this.button1 = new System.Windows.Forms.Button();            this.txtUserName = new System.Windows.Forms.TextBox();            this.txtImageLocation = new System.Windows.Forms.TextBox();            this.label1 = new System.Windows.Forms.Label();            this.label2 = new System.Windows.Forms.Label();            this.label3 = new System.Windows.Forms.Label();            this.txtLDAPString = new System.Windows.Forms.TextBox();            this.button2 = new System.Windows.Forms.Button();            this.ofd = new System.Windows.Forms.OpenFileDialog();            this.panel1 = new System.Windows.Forms.Panel();            this.label5 = new System.Windows.Forms.Label();            this.txtDomainController = new System.Windows.Forms.TextBox();            this.SuspendLayout();            //            // button1            //            this.button1.Location = new System.Drawing.Point(423, 194);            this.button1.Name = "button1";            this.button1.Size = new System.Drawing.Size(75, 23);            this.button1.TabIndex = 0;            this.button1.Text = "Save!";            this.button1.UseVisualStyleBackColor = true;            this.button1.Click += new System.EventHandler(this.button1_Click);            //            // textBox1            //            this.txtUserName.Location = new System.Drawing.Point(35, 73);            this.txtUserName.Name = "textBox1";            this.txtUserName.Size = new System.Drawing.Size(100, 20);            this.txtUserName.TabIndex = 1;            this.txtUserName.Text = "Paul Adams";            //            // textBox2            //            this.txtImageLocation.Location = new System.Drawing.Point(35, 167);            this.txtImageLocation.Name = "textBox2";            this.txtImageLocation.ReadOnly = true;            this.txtImageLocation.Size = new System.Drawing.Size(229, 20);            this.txtImageLocation.TabIndex = 2;            this.txtImageLocation.Text = "pick a jpg";            //            // label1            //            this.label1.AutoSize = true;            this.label1.Location = new System.Drawing.Point(21, 57);            this.label1.Name = "label1";            this.label1.Size = new System.Drawing.Size(272, 13);            this.label1.TabIndex = 3;            this.label1.Text = "Users Name as it appears in active directory (and LDAP)";            //            // label2            //            this.label2.AutoSize = true;            this.label2.Location = new System.Drawing.Point(21, 149);            this.label2.Name = "label2";            this.label2.Size = new System.Drawing.Size(164, 13);            this.label2.TabIndex = 4;            this.label2.Text = "Location of Image (300x300 max)";            //            // label3            //            this.label3.AutoSize = true;            this.label3.Location = new System.Drawing.Point(21, 9);            this.label3.Name = "label3";            this.label3.Size = new System.Drawing.Size(156, 13);            this.label3.TabIndex = 6;            this.label3.Text = "LDAP Location of user account";            //            // textBox3            //            this.txtLDAPString.Location = new System.Drawing.Point(35, 25);            this.txtLDAPString.Name = "textBox3";            this.txtLDAPString.Size = new System.Drawing.Size(264, 20);            this.txtLDAPString.TabIndex = 5;            this.txtLDAPString.Text = "ou=users,ou=corporate,dc=corp,dc=ad";            //            // button2            //            this.button2.Location = new System.Drawing.Point(268, 165);            this.button2.Name = "button2";            this.button2.Size = new System.Drawing.Size(28, 23);            this.button2.TabIndex = 9;            this.button2.Text = "...";            this.button2.UseVisualStyleBackColor = true;            this.button2.Click += new System.EventHandler(this.button2_Click);            //            // ofd            //            this.ofd.DefaultExt = "jpg";            this.ofd.FileName = "Picture.jpg";            this.ofd.InitialDirectory = "c:&quot;;            //            // panel1            //            this.panel1.BackColor = System.Drawing.Color.Silver;            this.panel1.Location = new System.Drawing.Point(323, 12);            this.panel1.Name = "panel1";            this.panel1.Size = new System.Drawing.Size(175, 175);            this.panel1.TabIndex = 10;            //            // label5            //            this.label5.AutoSize = true;            this.label5.Location = new System.Drawing.Point(21, 101);            this.label5.Name = "label5";            this.label5.Size = new System.Drawing.Size(130, 13);            this.label5.TabIndex = 12;            this.label5.Text = "Random domain controller";            //            // textBox4            //            this.txtDomainController.Location = new System.Drawing.Point(35, 117);            this.txtDomainController.Name = "textBox4";            this.txtDomainController.Size = new System.Drawing.Size(100, 20);            this.txtDomainController.TabIndex = 11;            this.txtDomainController.Text = "DC03";            //            // Form1            //            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;            this.ClientSize = new System.Drawing.Size(509, 226);            this.Controls.Add(this.label5);            this.Controls.Add(this.txtDomainController);            this.Controls.Add(this.panel1);            this.Controls.Add(this.button2);            this.Controls.Add(this.label3);            this.Controls.Add(this.txtLDAPString);            this.Controls.Add(this.label2);            this.Controls.Add(this.label1);            this.Controls.Add(this.txtImageLocation);            this.Controls.Add(this.txtUserName);            this.Controls.Add(this.button1);            this.Name = "Form1";            this.Text = "Picture-ater Gizmo";            this.ResumeLayout(false);            this.PerformLayout();        }        #endregion        private System.Windows.Forms.Button button1;        private System.Windows.Forms.TextBox txtUserName;        private System.Windows.Forms.TextBox txtImageLocation;        private System.Windows.Forms.Label label1;        private System.Windows.Forms.Label label2;        private System.Windows.Forms.Label label3;        private System.Windows.Forms.TextBox txtLDAPString;        private System.Windows.Forms.Button button2;        private System.Windows.Forms.OpenFileDialog ofd;        private System.Windows.Forms.Panel panel1;        private System.Windows.Forms.Label label5;        private System.Windows.Forms.TextBox txtDomainController;    } } {    partial class Form1    {        /// <summary>        /// Required designer variable.        /// </summary>        private System.ComponentModel.IContainer components = null;        /// <summary>        /// Clean up any resources being used.        /// </summary>        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>        protected override void Dispose(bool disposing)        {            if (disposing && (components != null))            {                components.Dispose();            }            base.Dispose(disposing);        }        #region Windows Form Designer generated code        /// <summary>        /// Required method for Designer support - do not modify        /// the contents of this method with th

  • Anonymous
    January 07, 2011
    email me if you need a working .exe that you can use to accomplish this without powershell or CLI commands. padams at sourcedirect dot com

  • Anonymous
    January 12, 2011
    I work with Windows 2003, I see that It is necessary register  schmmgmt.dll but I don't  find the dll, somebody can help me?

  • Anonymous
    March 31, 2011
    We have a free product available from our website that makes this very easy. www.exclaimer.com/.../Default.aspx

  • Anonymous
    July 07, 2011
    Exclaimer's Outlook Photo tool is AWESOME! It is a GUI and automatically links up the pictures to the users if the filenames are the same as the usernames! Great!

  • Anonymous
    November 21, 2011
    You can also use this free tool for importing and managing users' Active Directory photos. As shown in this vid: www.youtube.com/watch

  • Anonymous
    January 11, 2012
    try this free tool, very easy top use, auto image editing and you can import pictures based on different conditions. www.codetwo.com/.../active-directory-photos

  • Anonymous
    June 27, 2014
    if you already have a 20GB of ntds.dit and adding the photo of arround 2GB. Does it really going to create replication issues from there onwards? Also, if you push nearly 1.5Lakh employees together how about the data write/read going to effect the AD? Does it get stored in lync/outlook cache so that it doesnt require to read every time from AD. Really concerned about the ad replication once the db size is more than 21GB. Any suggesion on implimenting the changes on ad which has huge DB size already...

  • Anonymous
    December 03, 2015
    The comment has been removed