Implementing Join/Leave link (part 1): Group Membership

Recently in a Proof-of-Concept I need to implement functionality that would identify one's membership in a group (Exchange in particular) and then provide a join or leave link based on that membership.  I'll cover this in three parts covering (to facilitate getting some of it done sooner rather than later) the functionality first, the join/leave functionality secondly, and the request mechanism lastly.  Overall this is a pretty simple task, but when I was searching for some reference information I kept coming up dry.  I'm hoping this post will simplify the matter for others.

To start, a little background info on decisions:

  1. I decided I would use the Managed API for Exchange Web Services (EWS) to the extent it would solve the problem in an effort to familiarize myself with it.
  2. I could have implemented the EWS piece using System.DirectoryServices.
  3. You will need sufficient privileges for the account executing the code in order to use objects and methods that affect the Directory.

The first thing that you one will have to do is download and install the SDK (for reference) and API info for EWS: EWS SDK and the EWS Managed API.  After those are installed you will need to reference the appropriate libraries for EWS ans System.DirectoryServices:

EWS and DS References

The next two pieces were to get the count of the members in the group and then identify whether or not the user was in the group.  It turns out that, from what I can tell, that the easiest way to do that using EWS is via the API call to expand the Distribution Group.  Make sure to include the proper using statements:

using

Microsoft.Exchange.WebServices.Data;
using System.DirectoryServices;

A reference to the ExchangeService object is needed.  I placed this as member of the class, but one could have done the same by instantiating it in the method call.

ExchangeService ExSvc =

new ExchangeService();

The following function has been modified slightly for reading on the post and may not compile as is, but will hopefully convey the means by which the task can be accomplished.  Don't forget this can also be accomplished, likely more efficiently, through DirectoryServices, but I specifically wanted to use EWS.

        public bool IsInGroup(string ParentDG, string UserEmail)

        {

            bool CurrentMember = false;

            if (thisDG.Trim().Length > 0)

            {

                try

                {

                    //Expand the group passed in in order to the count of group membership

                    ExpandGroupResults ExpandedGroupList = ExSvc.ExpandGroup(ParentDG);

                    //defined elsewhere in the class

     _memberCountString = ExpandedGroupList.Count.ToString();

                    //Now loop through comparing the passed in email and

                    //the name of the requester based on network credentials

                    int loopCount = 0;

                while (!CurrentMember && loopCount < ExpandedGroupList.Members.Count)

                    {

string auth_user = Request.ServerVariables["AUTH_USER"].ToString();

                       CurrentMember = auth_user.Contains(ExpandedGroupList.Members[loopCount].Name.Trim())

            || UserEmail.Trim() == ExpandedGroupList.Members[loopCount].Address.Trim();

                        loopCount++;

                    }

                }

                catch (Exception ex)

                {

                    Debug.WriteLine(ex.Message);

                }

            }

            return CurrentMember;

        }

 

This turns out to be a rather heinous means of accomplishing the task since a loop through the expanded list is required. I could have done some better matching for email or user name, but the point is that I'd rather have done something a little more targeted on my end. If I were to implement this functionality again I would have not used EWS and used DirectorySearcher instead to get the user and compare the user's membership to the Distribution Group being passed in. It could be done with DirectoryServices similarly to how I implemented it here with EWS, grabbing the group and then testing its members, but in most cases a user's membership list will be shorter than a group's members list and as such most often it will be more efficient to work from the member instead of from the list.