Utilizing Workplace 365 Teams throughout the EWS Managed API

Utilizing Workplace 365 Teams throughout the EWS Managed API Workplace365 Teams (or unifiedmodern teams) is a brand new characteristic the was launched in Workplace365 that Alternate On-line is an lively participant in by offering the E-mail/Dialog and calendar parts of this characteristic. Just lately there was a brand new unified REST API launched in preview https://msdn.microsoft.com/en-us/workplace/workplace365/howto/office-365-unified-api-overview that I am going to take a look at one other day however with this put up I wish to take a look at simply accessing the Alternate portion of the unified Teams utilizing EWS and in addition we are going to check out how the config is saved within the mailbox.

Accessing utilizing the EWS Managed API

In case your following the modifications to the EWS Managed API open supply repository https://github.com/OfficeDev/ews-managed-api assist for studying the accessible Unified teams a Mailbox is a member of was added in April. That is carried out utilizing the but to be documented GetUserUnifiedGroups EWS operation. So when you have a model of the Managed API compiled from this supply that features these updates (there’s a pattern one from considered one of my different put up right here ) . You’ll be able to then use the next code to get all of the Unified Teams a Mailbox is a member of

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
            RequestedUnifiedGroupsSet Group = new RequestedUnifiedGroupsSet();
Group.FilterType = UnifiedGroupsFilterType.All;
Group.SortDirection = SortDirection.Ascending;
Group.SortType = UnifiedGroupsSortType.DisplayName;
Checklist<RequestedUnifiedGroupsSet> reqG = new Checklist<RequestedUnifiedGroupsSet>();
reqG.Add(Group);
Assortment<UnifiedGroupsSet> ugGroupSet = service.GetUserUnifiedGroups(reqG,"jcool@domain.com");
foreach (UnifiedGroupsSet ugset in ugGroupSet)
{
foreach (UnifiedGroup ugGroup in ugset.Teams)
{
Console.WriteLine(ugGroup.SMTPAddress);
}
}
 

or in PowerShell

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
$Group = New-Object Microsoft.Alternate.WebServices.Information.Teams.RequestedUnifiedGroupsSet
$Group.FilterType = [Microsoft.Exchange.WebServices.Data.Groups.UnifiedGroupsFilterType]::All;
$Group.SortDirection = [Microsoft.Exchange.WebServices.Data.SortDirection]::Ascending;
$Group.SortType = [Microsoft.Exchange.WebServices.Data.Groups.UnifiedGroupsSortType]::DisplayName;
$reqG = New-Object -TypeName 'System.Collections.Generic.Checklist[Microsoft.Exchange.WebServices.Data.Groups.RequestedUnifiedGroupsSet]'
$reqG.Add($Group);
$ugGroupSet = $service.GetUserUnifiedGroups($reqG,"jcool@domain.com");
foreach ($ugset in $ugGroupSet)
{
foreach ($gGroup in $ugset.Teams)
{
$gGroup.SmtpAddress
}
}

(Be aware as I am scripting this I feel there’s a bug on this operation when utilizing the Mailbox overload)

After getting the SMTPAddress of the Group you’ll be able to simply Bind to the Group utilizing a standard Folder bind eg both the Inbox (for conversations) or the Calendar

1
2
$folderid= new-object Microsoft.Alternate.WebServices.Information.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Calendar,$gGroup.SmtpAddress)   
$Calendar = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)

Technical Bit

For these individuals within the how this get carried out in your mailbox here is what it seems to be like. Within the Mailbox Non_IPM_Subtree there’s a folder known as MailboxAssociations this will get created eg

Then within the regular Messages assortment of this folder once you subscribe to a bunch (or are made a member of 1) an merchandise of sort IPM.MailboxAssociation.Group shall be created. On this Merchandise’s prolonged properties get set with the related info for the group eg

So when you have an older model of the Managed API the place you do not have entry to the newer updates you’ll be able to nonetheless get the Group memberships for a mailbox by accessing these IPM.MailboxAssociation.Group objects after which studying the prolonged properties. Eg first to bind to the MailboxAssociations use the next prolonged property which gives you the HexId of the folder which you’ll then convert to an EWSId to bind to the folder.

1
2
3
4
5
6
7
8
            ExtendedPropertyDefinition MailboxAssociationFolderEntryId = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.Widespread, "MailboxAssociationFolderEntryId", MapiPropertyType.Binary);
PropertySet fldPropSet = new PropertySet(BasePropertySet.FirstClassProperties);
fldPropSet.Add(MailboxAssociationFolderEntryId);
Folder rtFolder = Folder.Bind(service, new FolderId(WellKnownFolderName.Root,"jcool@datarumble.com"), fldPropSet);
Byte[] MAFldId = null;
rtFolder.TryGetProperty(MailboxAssociationFolderEntryId, out MAFldId);
AlternateId aiEWS = (AlternateId)service.ConvertId(new AlternateId(IdFormat.HexEntryId, BitConverter.ToString(MAFldId).Exchange("-", ""), "jcool@datarumble.com"), IdFormat.EwsId);
Folder MbAssoc = Folder.Bind(service,new FolderId(aiEWS.UniqueId));

When you bind to the MailboxAssoications Folder you’ll be able to then simply use a FindItem op with a search filter to restrict the outcomes to simply the Group associations. Then pull the prolonged property for the LegacyDN of the MailboxAssoication then you definately simply must resolve that to the SMTPAddress eg

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
            PropertySet itmPropSet = new PropertySet(BasePropertySet.FirstClassProperties);
ExtendedPropertyDefinition MailboxAssociationExternalId = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.Widespread, "MailboxAssociationExternalId", MapiPropertyType.String);
ExtendedPropertyDefinition MailboxAssociationLegacyDN = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.Widespread, "MailboxAssociationLegacyDN", MapiPropertyType.String);
ExtendedPropertyDefinition MailboxAssociationIsMember = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.Widespread, "MailboxAssociationIsMember", MapiPropertyType.Boolean);
itmPropSet.Add(MailboxAssociationExternalId);
itmPropSet.Add(MailboxAssociationLegacyDN);
itmPropSet.Add(MailboxAssociationIsMember);
SearchFilter sfFilter = new SearchFilter.IsEqualTo(ItemSchema.ItemClass, "IPM.MailboxAssociation.Group");
ItemView ivMbAsView = new ItemView(1000);
ivMbAsView.PropertySet = itmPropSet;
FindItemsResults<Merchandise> GroupAssoications = MbAssoc.FindItems(sfFilter, ivMbAsView);
Checklist<String> GroupSMTPAddresses = new Checklist<string>();
foreach (Merchandise itItem in GroupAssoications.Objects)
{
String mbAssoicatedDn = "";
bool MailboxAssociationIsMemberValue = false;
itItem.TryGetProperty(MailboxAssociationIsMember, out MailboxAssociationIsMemberValue);
if (MailboxAssociationIsMemberValue)
{
if (itItem.TryGetProperty(MailboxAssociationLegacyDN, out mbAssoicatedDn))
{
NameResolutionCollection ncCol = service.ResolveName(mbAssoicatedDn, ResolveNameSearchLocation.DirectoryOnly, true);
if (ncCol.Depend > 0)
{
GroupSMTPAddresses.Add(ncCol[0].Mailbox.Deal with);
}
}
}
}

In order you’ll be able to see it is just a little extra sophisticated this fashion so attempt to use the opposite op the place you’ll be able to.

Leave a Reply