Category Archives: Exchange development

Reading extended properties using EWS managed API

Having been working with Exchange 2007 Web Services (EWS) for a couple af years a recent bug led me to testing various scenarios regarding appointment items using the EWS Managed API instead of the proxy classes that I have grown used to working with.

One of my struggles was to read the extended properties that we use. Having gotten it all to work I though that I’d create this post. Below you will find my code sample:

This first snippet set up the service connection using autodiscover.

        private ExchangeService GetService()

        {

            ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2007_SP1);

            service.Credentials = new NetworkCredential(Settings.Default.ConnectingUser, Settings.Default.ConnectingUserPassword, Settings.Default.ConnectingUserDomain);

            service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SID, Settings.Default.ImpersonatedUserSID);

            service.Url = new Uri(Settings.Default.EWSURL);

            return service;

        }

This second snippet defines and fetches the standard properties as well as the extended properties.

        private void btnGetItem_Click(object sender, EventArgs e)

        {

            string itemId = txtItemId.Text;

            ExchangeService service = GetService();

            AlternateId sourceId = new AlternateId(IdFormat.EwsLegacyId, itemId, Settings.Default.ImpersonatedUserMailbox);

            AlternateId destinationId = service.ConvertId(sourceId, IdFormat.EwsId) as AlternateId;

            //reference: http://social.technet.microsoft.com/Forums/en-US/exchangesvrdevelopment/thread/e01fe982-83c2-49ee-b900-78d49c47323c/

            //define the extended properties that should be fetched

            ExtendedPropertyDefinition rmsIsRms = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.PublicStrings, “RMS-IsRMS”, MapiPropertyType.Boolean);

            ExtendedPropertyDefinition rmsCustomerProp = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.PublicStrings, “RMS-CustomerProp”, MapiPropertyType.String);

            ExtendedPropertyDefinition rmsInternalProp = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.PublicStrings, “RMS-InternalProp”, MapiPropertyType.Boolean);

            ExtendedPropertyDefinition rmsProjectProp = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.PublicStrings, “RMS-ProjectProp”, MapiPropertyType.String);

            ExtendedPropertyDefinition rmsActivityProp = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.PublicStrings, “RMS-ActivityProp”, MapiPropertyType.String);

            ExtendedPropertyDefinition[] userFields = new ExtendedPropertyDefinition[] { rmsIsRms, rmsActivityProp, rmsCustomerProp, rmsInternalProp, rmsProjectProp };

            //get the item and it’s extended properties

            PropertySet extendedPropertySet = new PropertySet(BasePropertySet.FirstClassProperties, userFields);

            Appointment item = (Appointment)Item.Bind(service, new ItemId(destinationId.UniqueId), extendedPropertySet);

            //having the item – get the extended properties

            object isRMS;

            object customerProp;

            object isInternalProp;

            object projectProp;

            object activityProp;

            //Print properties

            rtItemProps.AppendText(“ItemClass: “ + item.ItemClass + “\n”);

            rtItemProps.AppendText(“Subject: “ + item.Subject + “\n”);

            rtItemProps.AppendText(“CalendarItemType: “ + item.AppointmentType.ToString() + “\n”);

            rtItemProps.AppendText(“Organizer: “ + item.Organizer.Name + “\n”);

            rtItemProps.AppendText(“OrganizerEmail: “ + item.Organizer.Address + “\n”);

            rtItemProps.AppendText(“Start: “ + item.Start + “\n”);

            rtItemProps.AppendText(“End: “ + item.End + “\n”);

            rtItemProps.AppendText(“Location: “ + item.Location + “\n”);

            rtItemProps.AppendText(“Free/busy: “ + item.LegacyFreeBusyStatus.ToString() + “\n”);

            rtItemProps.AppendText(“—————RMS INFO————–\n”);

            //extended properties are printed only if they exist

            if (item.TryGetProperty(rmsIsRms, out isRMS) && isRMS != null)

            {

                rtItemProps.AppendText(“IsRMS: “ + isRMS.ToString() + “\n”);

            }

            if (item.TryGetProperty(rmsCustomerProp, out customerProp) && customerProp != null)

            {

                rtItemProps.AppendText(“Customer: “ + customerProp.ToString() + “\n”);

            }

            if (item.TryGetProperty(rmsProjectProp, out projectProp) && projectProp != null)

            {

                rtItemProps.AppendText(“Project: “ + projectProp.ToString() + “\n”);

            }

            if (item.TryGetProperty(rmsActivityProp, out activityProp) && activityProp != null)

            {

                rtItemProps.AppendText(“Activity: “ + activityProp.ToString() + “\n”);

            }

            if (item.TryGetProperty(rmsInternalProp, out isInternalProp) && isInternalProp != null)

            {

                rtItemProps.AppendText(“IsInternal: “ + isInternalProp.ToString() + “\n”);

            }

        }

Advertisements

Retrieving user SID using DirectoryEntry and DirectorySearcher

Recently I was working on one of main projects that amongst other things retrieves some user properties from Active Directory.

In order to use Exchange 2007 Webservices I needed to retrieve the SID because the SID was needed when impersonating a given user. This articke describes how to retrieve the SID into a byte array and using P/Invoke.

Step 1 – Search the AD

    1 public SearchResultCollection getUserInfo(string ldapPath)

    2         {

    3             string ADUserName = ConfigurationManager.AppSettings[“UserName”];

    4             string ADPassword = ConfigurationManager.AppSettings[“Password”];

    5             DirectoryEntry rootEntry = new DirectoryEntry(ldapPath, ADUserName, ADPassword);

    6             DirectorySearcher searcher = new DirectorySearcher(rootEntry);

    7             //add the properties to retrieve

    8             //accountstatus

    9             searcher.PropertiesToLoad.Add(“userAccountControl”);

   10             //mail

   11             searcher.PropertiesToLoad.Add(“mail”);

   12             searcher.PropertiesToLoad.Add(“accountExpires”);

   13             searcher.PropertiesToLoad.Add(“proxyaddresses”);

   14             searcher.PropertiesToLoad.Add(“SAMAccountName”);

   15             searcher.PropertiesToLoad.Add(“objectSid”);

   16             SearchResultCollection results;

   17             results = searcher.FindAll();

   18             return results;

   19         }

 

Step 2 – loop the SearchResultCollection retriveing the “objectSid”

    string sidStringValue=””;

    foreach (SearchResult result in src)

             {

                  //reset SID

                  byte[] SID = null;

                  if (result.Properties[“objectSid”].Count > 0)

                  {

                      SID = (byte[]) result.Properties[“objectSid”][0];

                  }

                  sidStringValue = GetSidString(SID); 

             }//end foreach

Step 3 – In the code example above a call to the method “GetSidString” is made – this method looks like this:

        [DllImport(“advapi32”, CharSet = CharSet.Auto, SetLastError = true)]

        static extern bool ConvertSidToStringSid([MarshalAs(UnmanagedType.LPArray)] byte[] pSID, out IntPtr ptrSid);

 

        public static string GetSidString(byte[] sid)

        {

            IntPtr ptrSid;

            string sidString;

            if (!ConvertSidToStringSid(sid, out ptrSid))

                throw new System.ComponentModel.Win32Exception();

            try

            {

                sidString = Marshal.PtrToStringAuto(ptrSid);

            }

            finally

            {

                Marshal.FreeHGlobal(ptrSid);

            }

            return sidString;

        }

    }

Retrieve SID from domain user

I do a lot of Exchange development and integrations. Doing that I often need to use a specific users SID. From the Exchange Management Console the SID can’t be retrieved easily. I have found a tool, that makes the task of fetching a user SID very easy. It is called GetSid  and you can download it from here: http://www.softpedia.com/get/Internet/Other-Internet-Related/GetSID.shtml