Monday, June 3, 2013

MS Exchange web services, managed API and reading Global Addresses List (GAL)

Scenario:

A few days ago I came across a situation where there was a need to extract all exchange users from a hosted environment. The exchange solution did not have the capability to export users data so I had to dig into the issue to find out a solution of this problem.

Solution:

One solution of the above problem was to use the Exchange Web Services - EWS (see more details here, here and here) to read the Global Address List - GAL (see details here) using some C# code. While defining the structure of the C# code, I came across Exchange Web Services managed API (more here) which give us the capability to perform all web services operations without creating any proxy or tedious code structures.

Implementation:

In order to write the C# code to extract the GAL data from hosted exchange, you would need to
  1. Download the managed API (from here)
  2. Create a reference in your visual studio project (from "C:\Program Files\Microsoft\Exchange\Web Services\2.0\Microsoft.Exchange.WebServices.dll", if not shown in the available references.)
  3. Write the code (more details below)

Code layout:

Structure of the program and layout of the code depends on the project template and other factors though in general you will have something like below
  1. Add using directive for namespace
    1
    using Microsoft.Exchange.WebServices.Data;
    
  2. Create service object
    1
    ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);
    
  3. Provide credentials (replace [UserName], [Password] and [WebServiceURL] with actual user name, password and URL of the web service respectively. URL of the web service is usually like https://[DomainName]/EWS/Services.wsdl where [DomainName] is usually the actual domain name of your hosted exchange provider)
    1
    2
    service.Credentials = new WebCredentials("[UserName]", "[Password]");
    service.Url = new Uri("[WebServiceURL]");
    
  4. Query the web service (replace [SearchString] with the actual string to search in GAL)
    1
    service.ResolveName("[SearchString]", ResolveNameSearchLocation.DirectoryOnly, true).ToArray<NameResolution>()
    
  5. Step 4 will return a NameResolutionCollection type object containing all the data returned from the web service. Various properties can be used to access the object model of a NameRosolution type object which provide a handful of information about each and every contact returned from the service call.

Exchange GAL Extract

In order to address the above problem, the solution I implemented can be downloaded from here or binary utility from here. It is a windows forms application which allows extraction of contacts from a remote GAL and export of some core properties in CSV and XML formats. Feel free to download the code and play with it. Following is a screenshot of the utility. Enjoy!!!