Edit: We have compiled this program for those without coding tools.

Recently, we had a migration for a customer that did not want to bring some older email accounts into the new email system. This occurs often and we recommend removing these inactive accounts if there are not any compelling reasons to keep them. The customer initially just wanted all the emails saved onto disk so that they could search them if desired.

A follow on request to extract all the email addresses from the mailboxes was new for us. After a bit of scoping and examining the Outlook object model, we saw that this should be fairly easy. Fairly easy usually means that we can go to TechNet and get a solution to solve our problem. We did find solutions but they did not work or failed us in a few areas. Therefore, we wrote our own solution to the problem.

This post will cover a considerably pared down version of that solution so that you can accomplish the base task without much difficulty. In this version we are only looking at emails in and under the Inbox root folder.

Create a console project and add a reference to your installed version of the Outlook interop via Microsoft.Office.Interop.Outlook. We also need something to store the email addresses before we save them to a CSV. I like dictionary objects in situations like this because I can be lazy and not need to write code to check for duplicates.

This is what we have so far.

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using Outlook = Microsoft.Office.Interop.Outlook;

namespace SyllogisticGroup.Operations.Outlook.ExtractEmailAddress
    class Program
        //Static Variables

        // Dictionary to store the emails
        public static Dictionary<string, string> EmailAddresses = new Dictionary<string, string>();
        // To store the sorted addresses
        public static SortedDictionary<string, string> SortedAddresses = new SortedDictionary<string, string>();

        static void Main()

Note that instead of typing out Microsoft.Office.Interop.Outlook each time we created an alias of Outlook on line 5.

We are now going to look at the heart of the program, the Main method.

We want to tell our users what is happening by changing the display periodically and so you will notice a copious amount of Console.WriteLines in the code to do just that. I personally hate programs that sit there, appearing to be idle, because they fail to provide some type of feedback to the user.

The first thing we will do is grab the currently running Outlook instance as an application. If Outlook is not running, then this will start a new application.

       static void Main()
            //Kick off the program
            Console.WriteLine("Outlook Address Extractor");

            //If Outlook is not running already, this will also start it
            Outlook.Application application = Activator.CreateInstance(Type.GetTypeFromProgID("Outlook.Application")) as Outlook.Application;

Next, we are first going to check that the application variable is not null. Then we are going to pull all the accounts from the profile and create a way cool, ah, simple menu to choose from. If this was a GUI application, then we could make a cool menu.


            if (application != null)
                //Lets get the accounts in the active Outlook profile
                Outlook.Accounts accounts = application.Session.Accounts;

                while (true)
                    // We clear the dictionary here, so that we don't mix the emails up with other
                    // if we ran it more than twice

                    //This next section generates the cool selector list :)
                    int id = 1;
                    foreach (Outlook.Account account in accounts)
                        Console.WriteLine(id + ":" + GetAccountEmailAddress(account));
                    Console.WriteLine("Q: Quit Application");

We will then wait for the user to make a selection. Notice that again, we keep checking for null values. You should always try to make your application crash proof. Well, reasonably crash proof. We will analyze the selection to determine which account the user selected. We also ensure that their selection matched one of the selections presented.

                    //Now we wait for a selection to be made
                    var readLine = Console.ReadLine();
                    if (readLine != null)
                        //We examine the selection to determine which account to use or quit
                        string response = readLine.ToUpper();
                        if (response == "Q")
                        if (response != "")
                            if (Int32.Parse(response.Trim()) >= 1 && Int32.Parse(response.Trim()) < id)
                                Console.WriteLine("Processing: " +
                                Console.WriteLine("Processing: " +

                                //Here we parse the response and move on to getting our email addresses
                                Outlook.Folder selectedFolder = GetFolder(@"\\" + accounts[Int32.Parse(response.Trim())].DisplayName);

                                //Now will sort the results
                                Console.WriteLine("Sorting the results.");

                                //Now saving the results
                                Console.WriteLine("Saving the results.");

                                //And finally, we tell the user what we found
                                Console.WriteLine("Finished Processing " +
                                Console.WriteLine(EmailAddresses.Count + " addresses Found");
                                Console.WriteLine("Invalid Selection");

In the snippet above, notice that after we validated that the user selected a proper account, we get the display name of the account and send that to a method called GetFolders. In addition, you see that we will call methods to sort, save, and then display messages to the user about the results. We will briefly cover those later.

The GetFolders method is a doozy! It calls itself repeatedly in the middle of the method. What is going on here? We of course know that this is recursion. Recursion simply means that the method or function calls itself. It is great for dealing with situations like this. We do not know how many child folders a user may have in their inbox or how many folders those folders may have. Instead of just counting folders and keeping a list of them, we use recursion. If a folder has a child folder, then we call GetFolders with that folder’s name. Eventually, we get to the bottom of the tree and at that point, we start getting messages by using the GetMessages method. As each child folder completes, the folder above it gets focus again. Once all the child folders in that folder are processed, then it is that folders turn.

So let us say that our user has the following folder tree.


  • Contracts
    • Signed
  • Personal
    • Fishing Tips
    • Vacation Ideas

What would be the expected processing order of the folders? If you said, Signed, Contracts, Fishing Tips, Vacation Ideas, Personal, and then Inbox, pat yourself on the back as you understand how recursion works! Yeah!

After all that, now you see why the first thing the method does is look for child folders. You may ask why we are not using the term subfolder instead of child folder. Simple, Outlook does not. We are trying to use the names that the Outlook object model uses. The method is below and I hope that it is easy to understand now.

        // We will recursion to dive through the entire Outlook tree
        private static void GetFolders(Outlook.Folder folder)
            Outlook.Folders childFolders = folder.Folders;
            if (childFolders.Count > 0)
                foreach (Outlook.Folder childFolder in childFolders)
                    /* This is where we limit ourselves to the inbox
                     *  This can easily be changed to look at the entire mailbox
                     *  And every object in it but we won't do that here 
                    if (childFolder.FolderPath.Contains("Inbox"))
                        // So the user some progress indicators

                        // Now this function calls itself, which is recursion, to again look for subfolders

            // If there are not any more subfolders, then we start looking at messages
            // This will eventually run on every folder due to the recursion without us having to write
            // a lot of code structure to handle it
            Console.WriteLine("Checking in " + folder.FolderPath);

Jump to the next page so that we can continue.