0

the web shows dozens of examples to query the exchange's global address list but i want to query the specific address lists! So every user in our Enterprise is ofcourse listed in our global address list but i want to query the address list of a specific company within our Enterprise.

In the example below, Aswebo, Cosimco, etc.. are address lists.

  1. How do I list these address lists?
  2. How do I list the people within these address lists?

enter image description here

Jan Doggen
  • 8,799
  • 13
  • 70
  • 144
Tiele Declercq
  • 2,070
  • 2
  • 28
  • 39

2 Answers2

1

I don't have exchange setup to test this code, so it will need modifications but it should give you a starting point to explore.

The idea is that you set the ItemView to the ContactSchema to retrieve results by company.

// Get the number of items in the Contacts folder. To keep the response smaller, request only the TotalCount property.
ContactsFolder contactsfolder = ContactsFolder.Bind(service,
                                                    WellKnownFolderName.Contacts,
                                                    new PropertySet(BasePropertySet.IdOnly, FolderSchema.TotalCount));

// Set the number of items to the smaller of the number of items in the Contacts folder or 1000.
int numItems = contactsfolder.TotalCount < 1000 ? contactsfolder.TotalCount : 1000;

// Instantiate the item view with the number of items to retrieve from the Contacts folder.
ItemView view = new ItemView(numItems);

view.PropertySet = new PropertySet(ContactSchema.CompanyName, ContactSchema.EmailAddress1);

// Retrieve the items in the Contacts folder that have the properties you've selected.
FindItemsResults<Item> contactItems = service.FindItems(WellKnownFolderName.Contacts, view);

foreach(var contact in contactItems)
{

            Contact contact    = item as Contact;
            // Filter / Group by company name
            // contact.Companyname
}

You can also use service.FindItems(WellKnownFolderName, SearchFilter, ViewBase) to provide additional filtering.

See this MSDN blog for a code example.

Amicable
  • 3,115
  • 3
  • 49
  • 77
  • Thank you for your answer and if i understand it correctly this approach might work but this requires to loop through all contacts of the global address list and save it's 'Company' name. So this does not use the actual address lists. – Tiele Declercq Aug 22 '13 at 11:45
  • @TieleDeclercq You can also use [service.FindItems(WellKnownFolderName, SearchFilter, ViewBase)](http://msdn.microsoft.com/en-us/library/jj221996(v=exchg.80).aspx) to provide additional filtering, so the processing will take place on the Exchange server. See [this link](http://blogs.msdn.com/b/akashb/archive/2010/03/05/how-to-build-a-complex-search-using-searchfilter-and-searchfiltercollection-in-ews-managed-api-1-0.aspx) for an example. – Amicable Aug 22 '13 at 12:32
0

I've been searching all afternoon and came up with the code below. It works.. but looking dirty. I would like an entire Principal approach but it seems I'm too dumb :-)

Anyone that wants to translate this code to 100% 'System.DirectoryServices.AccountManagement'?

using System;
using System.Collections.Generic;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;

namespace ConsoleApplication3
{
    class Program
    {
        static void Main(string[] args)
        {
            DirectoryEntry ldap;
            DirectorySearcher ldap_search;
            SearchResultCollection ldap_results;
            PrincipalContext ctx = new PrincipalContext(ContextType.Domain);

            var addressLists = new Dictionary<string, string>();


            // Flexible way (but visually complex!) for building the path LDAP://CN=All Address Lists,CN=Address Lists Container,CN=First Organization,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=DOMAIN,DC=local
            ldap = new DirectoryEntry("LDAP://RootDSE");
            ldap_search = new DirectorySearcher(new DirectoryEntry("LDAP://CN=Microsoft Exchange, CN=Services," + ldap.Properties["configurationNamingContext"].Value), "(objectClass=msExchOrganizationContainer)");
            ldap_search = new DirectorySearcher(new DirectoryEntry("LDAP://CN=All Address Lists,CN=Address Lists Container," + ldap_search.FindOne().Properties["distinguishedName"][0]), "(objectClass=addressBookContainer)");
            ldap_search.Sort = new SortOption("name", SortDirection.Ascending);

            // Find All Address Lists alphabetically and put these into a dictionary
            ldap_results = ldap_search.FindAll();
            foreach (SearchResult ldap_result in ldap_results)
            {
                var addressList = new DirectoryEntry(ldap_result.Path);
                addressLists.Add(addressList.Properties["name"].Value.ToString(), addressList.Properties["distinguishedName"][0].ToString());
            }

            //// list Address Lists
            //foreach (var addressList in addressLists) Console.WriteLine(addressList.Key);

            // List all users from Address List "Aswebo"
            ldap = new DirectoryEntry("LDAP://" + ldap.Properties["defaultNamingContext"].Value); // rename ldap to LDAP://DC=DOMAIN,DC=local
            ldap_search = new DirectorySearcher(ldap, string.Format("(&(objectClass=User)(showInAddressBook={0}))", addressLists["Aswebo"])); // Search all users mentioned within the specified address list
            ldap_results = ldap_search.FindAll();
            foreach (SearchResult ldap_result in ldap_results)
            {
                // Fetch user properties using the newer interface.. just coz it's nice :-)
                var User = UserPrincipal.FindByIdentity(ctx, IdentityType.DistinguishedName, ldap_result.Path.Replace("LDAP://", ""));
                Console.WriteLine(User.DisplayName);
            }

            Console.ReadLine();
        }
    }
}
Tiele Declercq
  • 2,070
  • 2
  • 28
  • 39