none
How to get shared calendars using EWS RRS feed

  • Question

  • Hi,

    I want to monitor all calendars shared to a user via EWS. I know how to do this provided I know each of the user names. But I don't. So I need to get a list of all the users that have shared their calendar to one specific user. But how? I've searched around. Is it possible?

    If this is indeed not possible; is there a way to list all users? That way should be able to figure out which of them have shared their calendar with 'my' user, by trial and error if nothing else.

    Thank you and best regards,


    babu

    Wednesday, February 26, 2014 1:08 PM

Answers

  • There is no direct way to do this however you can enumerate the Shared Calendar folders a user has added by enumerating the Nav links in the Common Views folder see http://msdn.microsoft.com/en-us/library/ee157359(v=exchg.80).aspx. You can then get the Mailbox this link refers to use the PidTagWlinkAddressBookEID and extracting the X500 address from that property. The you can just bind to each of the Folders using that information.

    eg

            static Dictionary<string, Folder> GetSharedCalendarFolders(ExchangeService service, String mbMailboxname)
            {
                Dictionary<String, Folder> rtList = new System.Collections.Generic.Dictionary<string, Folder>();
                //GetSharedContacts
                FolderId rfRootFolderid = new FolderId(WellKnownFolderName.Root, mbMailboxname);
                FolderView fvFolderView = new FolderView(1000);
                SearchFilter sfSearchFilter = new SearchFilter.IsEqualTo(FolderSchema.DisplayName, "Common Views");
                FindFoldersResults ffoldres = service.FindFolders(rfRootFolderid, sfSearchFilter, fvFolderView);
                if (ffoldres.Folders.Count == 1)
                {
    
                    PropertySet psPropset = new PropertySet(BasePropertySet.FirstClassProperties);
                    ExtendedPropertyDefinition PidTagWlinkAddressBookEID = new ExtendedPropertyDefinition(0x6854, MapiPropertyType.Binary);
                    ExtendedPropertyDefinition PidTagWlinkFolderType = new ExtendedPropertyDefinition(0x684F, MapiPropertyType.Binary);
                    ExtendedPropertyDefinition PidTagWlinkGroupName = new ExtendedPropertyDefinition(0x6851, MapiPropertyType.String);
    
                    psPropset.Add(PidTagWlinkAddressBookEID);
    	            psPropset.Add(PidTagWlinkFolderType);
                    ItemView iv = new ItemView(1000);
                    iv.PropertySet = psPropset;
                    iv.Traversal = ItemTraversal.Associated;
    
                    SearchFilter cntSearch = new SearchFilter.IsEqualTo(PidTagWlinkGroupName, "Other Calendars");
                    FindItemsResults<Item> fiResults = ffoldres.Folders[0].FindItems(cntSearch, iv);
                    foreach (Item itItem in fiResults.Items)
                    {
                        try
                        {
                            object GroupName = null;
                            object WlinkAddressBookEID = null;
                            if (itItem.TryGetProperty(PidTagWlinkAddressBookEID, out WlinkAddressBookEID))
                            {
    
                                byte[] ssStoreID = (byte[])WlinkAddressBookEID;
                                int leLegDnStart = 0;
                                String lnLegDN = "";
                                for (int ssArraynum = (ssStoreID.Length - 2); ssArraynum != 0; ssArraynum--)
                                {
                                    if (ssStoreID[ssArraynum] == 0)
                                    {
                                        leLegDnStart = ssArraynum;
                                        lnLegDN = System.Text.ASCIIEncoding.ASCII.GetString(ssStoreID, leLegDnStart + 1, (ssStoreID.Length - (leLegDnStart + 2)));
                                        ssArraynum = 1;
                                    }
                                }
                                NameResolutionCollection ncCol = service.ResolveName(lnLegDN, ResolveNameSearchLocation.DirectoryOnly, true);
                                if (ncCol.Count > 0)
                                {
    
                                    FolderId SharedCalendarId = new FolderId(WellKnownFolderName.Calendar, ncCol[0].Mailbox.Address);
                                    Folder SharedCalendaFolder = Folder.Bind(service, SharedCalendarId);
                                    rtList.Add(ncCol[0].Mailbox.Address, SharedCalendaFolder);
    
    
                                }
    
                            }
                        }
                        catch (Exception exception)
                        {
                            Console.WriteLine(exception.Message);
                        }
    
                    }
                }
                return rtList;
            }

    Cheers
    Glen

    • Marked as answer by b48u Friday, February 28, 2014 7:58 AM
    Thursday, February 27, 2014 4:21 AM

All replies

  • There is no direct way to do this however you can enumerate the Shared Calendar folders a user has added by enumerating the Nav links in the Common Views folder see http://msdn.microsoft.com/en-us/library/ee157359(v=exchg.80).aspx. You can then get the Mailbox this link refers to use the PidTagWlinkAddressBookEID and extracting the X500 address from that property. The you can just bind to each of the Folders using that information.

    eg

            static Dictionary<string, Folder> GetSharedCalendarFolders(ExchangeService service, String mbMailboxname)
            {
                Dictionary<String, Folder> rtList = new System.Collections.Generic.Dictionary<string, Folder>();
                //GetSharedContacts
                FolderId rfRootFolderid = new FolderId(WellKnownFolderName.Root, mbMailboxname);
                FolderView fvFolderView = new FolderView(1000);
                SearchFilter sfSearchFilter = new SearchFilter.IsEqualTo(FolderSchema.DisplayName, "Common Views");
                FindFoldersResults ffoldres = service.FindFolders(rfRootFolderid, sfSearchFilter, fvFolderView);
                if (ffoldres.Folders.Count == 1)
                {
    
                    PropertySet psPropset = new PropertySet(BasePropertySet.FirstClassProperties);
                    ExtendedPropertyDefinition PidTagWlinkAddressBookEID = new ExtendedPropertyDefinition(0x6854, MapiPropertyType.Binary);
                    ExtendedPropertyDefinition PidTagWlinkFolderType = new ExtendedPropertyDefinition(0x684F, MapiPropertyType.Binary);
                    ExtendedPropertyDefinition PidTagWlinkGroupName = new ExtendedPropertyDefinition(0x6851, MapiPropertyType.String);
    
                    psPropset.Add(PidTagWlinkAddressBookEID);
    	            psPropset.Add(PidTagWlinkFolderType);
                    ItemView iv = new ItemView(1000);
                    iv.PropertySet = psPropset;
                    iv.Traversal = ItemTraversal.Associated;
    
                    SearchFilter cntSearch = new SearchFilter.IsEqualTo(PidTagWlinkGroupName, "Other Calendars");
                    FindItemsResults<Item> fiResults = ffoldres.Folders[0].FindItems(cntSearch, iv);
                    foreach (Item itItem in fiResults.Items)
                    {
                        try
                        {
                            object GroupName = null;
                            object WlinkAddressBookEID = null;
                            if (itItem.TryGetProperty(PidTagWlinkAddressBookEID, out WlinkAddressBookEID))
                            {
    
                                byte[] ssStoreID = (byte[])WlinkAddressBookEID;
                                int leLegDnStart = 0;
                                String lnLegDN = "";
                                for (int ssArraynum = (ssStoreID.Length - 2); ssArraynum != 0; ssArraynum--)
                                {
                                    if (ssStoreID[ssArraynum] == 0)
                                    {
                                        leLegDnStart = ssArraynum;
                                        lnLegDN = System.Text.ASCIIEncoding.ASCII.GetString(ssStoreID, leLegDnStart + 1, (ssStoreID.Length - (leLegDnStart + 2)));
                                        ssArraynum = 1;
                                    }
                                }
                                NameResolutionCollection ncCol = service.ResolveName(lnLegDN, ResolveNameSearchLocation.DirectoryOnly, true);
                                if (ncCol.Count > 0)
                                {
    
                                    FolderId SharedCalendarId = new FolderId(WellKnownFolderName.Calendar, ncCol[0].Mailbox.Address);
                                    Folder SharedCalendaFolder = Folder.Bind(service, SharedCalendarId);
                                    rtList.Add(ncCol[0].Mailbox.Address, SharedCalendaFolder);
    
    
                                }
    
                            }
                        }
                        catch (Exception exception)
                        {
                            Console.WriteLine(exception.Message);
                        }
    
                    }
                }
                return rtList;
            }

    Cheers
    Glen

    • Marked as answer by b48u Friday, February 28, 2014 7:58 AM
    Thursday, February 27, 2014 4:21 AM
  • Glen,

    Thank you.

    Two quick questions you may have quick answers for..:

    What are the version requirements for this workaround? (I'm struggling somewhat with it on exchange server 2010... Is it too old?)

    Is it possible to retrieve a list of all users through ews? (My plan B)

    Again, thank you for your time.



    babu

    Thursday, February 27, 2014 10:21 AM
  • It should work okay on 2010 as long as you version your requests to Exchange 2010 (otherwise you won't be able to query the associated items collection).

    >> Is it possible to retrieve a list of all users through ews? (My plan B)

    Not in 2010 if you have less the 100 users in the GAL then you can use ResolveName and search for "SMTP:" and this will return the first 100 objects in the GAL with a SMTP address

    Cheers
    Glen

     

    Friday, February 28, 2014 4:31 AM
  • Hi Bro,

       Can you please share the code how to monitor all the shared calendars vis EWS . I look around the whole Internet but no use. Please do share your code .....

    Regards,

    Jaya Krishna

    Wednesday, November 5, 2014 10:25 AM