Microsoft Exchange Connector Tool – Find operation examples

Introduction

This article will give a variety of Find operation examples which can be adapted to specific business process requirements.  Functionality implemented in version 4.3 of the Microsoft Exchange Connector Tool will be used here.

The Find operation works identically across all the supported versions of Exchange, 2013; 2016; and Exchange Online.  This operation is important to understand as it returns the unique identifier for the objects matching the specified criteria and thereby allows the retrieval of additional detail using the Get operation.

Example 1 – Message Item Find using the Subject field

In this example, emails are received in the Inbox for a mail account which may – or may not – relate to Invoices.  Only invoice-related messages are required:

The Find operation across all objects in Exchange exposes a similar series of fields:

SupplementaryReferenceThis field can be used to pass a value through to appear in the response from Exchange. This can be especially useful when a series of Find operations are looped and each response needs to be connected to the source request.
MailBoxEmailAddressHere we are searching inside a mailbox, so this field is required. If it is not supplied, the focus of the Find moves to the public folders on the Exchange server (public folders are not linked to any individual mailbox).
SearchFieldThis is the field that is being used to conduct the Find on and is mandatory (as indicated by being bold in the InputData tree). In this example, the ‘Subject’ field will be used. To get an idea of what fields are potentially available, look at the fields exposed by the response to a Get operation for the object in question. If a field is selected that searches cannot be conducted on, Exchange will either pass back an error message that will be displayed when the task is queued, or simply return no matches. Exchange may also require the pluralised version of the field where multiple values can be applied, for example Categories, not Category (see example 3).
SearchExpressionThis is the second mandatory field (again bolded in the InputData tree). It is the value to search for. In this example, the value ‘invoice’ will be used – Exchange treats this field as case-insensitive so the search will also return where ‘Invoice’, ‘invoice’, or ‘INVOICE’ are found.
SearchOperatorBy default, Exchange looks for the SearchExpression value at any point within the SearchField. This operator is called ‘ContainsSubstring’. The SearchOperator field only appears for objects that support it – but where it does – the following additional operators are available:

IsEqualTo
IsGreaterThanOrEqualTo
IsGreaterThan
IsLessThan
IsLessThanOrEqualTo
IsNotEqualTo

These additional operators appear to be ideally suited to numeric rather than string values, but there are caveats. Please see example 2 for more information.

SearchFolderAs this field is nested inside a parent SearchFolders node it can be looped – multiple SearchFolder values can be provided in a single Find (see example 3). If it is not supplied, the default folder for the object type will be used by the Find, which for Messages is the Inbox. All searches are ‘shallow’ and only search the given folder, not other folders deeper in the structure. In this example, if the ‘Sub-Inbox’ folder (as seen in the screenshot above) also needed to be searched, a second SearchFolder would be required.

Returning to the invoice scenario, the following XML can be used as the source for the Exchange step (three variables containing the values could also have been used):

<?xml version="1.0"?>
<InputData>
  <MessageItem>
    <MailboxEmailAddress>mecuser1@exch2016.local</MailboxEmailAddress>
    <SearchField>Subject</SearchField>
    <SearchExpression>invoice</SearchExpression>
  </MessageItem>
</InputData>

When a task containing these steps is queued, the response containing the two messages of interest are returned:

<OutputData>
  <MessageItems>
    <SupplementaryReference />
    <MailboxEmailAddress>mecuser1@exch2016.local</MailboxEmailAddress>
    <SearchField>Subject</SearchField>
    <SearchExpression>invoice</SearchExpression>
    <SearchOperator>ContainsSubstring</SearchOperator>
    <MessageItem>
      <ExchangeMessageId>AAM…bAAA=</ExchangeMessageId>
      <ExchangeMessageChangeKey>CQ…RCR9</ExchangeMessageChangeKey>
      <LastModified>2016-11-03T10:13:17</LastModified>
    </MessageItem>
    <MessageItem>
      <ExchangeMessageId>AAM…ZAAA=</ExchangeMessageId>
      <ExchangeMessageChangeKey>CQ…RCR7</ExchangeMessageChangeKey>
      <LastModified>2016-11-03T09:57:58</LastModified>
    </MessageItem>
  </MessageItems>
</OutputData>

If further information is required on the items found, this output – with the ExchangeMessageIds returned – could be used as the source for a Message Item > Get:

Example 2 – Task Item Find using the Mileage field

In the second example, mileage is recorded for projects in a custom task folder.  Any mileage greater than 10 needs to be retrieved:

To do this, the following XML will be used as the source for the Exchange step:

<?xml version="1.0"?>
<InputData>
  <TaskItem>
    <MailboxEmailAddress>mecuser1@exch2016.local</MailboxEmailAddress>
    <SearchField>Mileage</SearchField>
    <SearchExpression>10</SearchExpression>
    <SearchOperator>IsGreaterThan</SearchOperator>
    <SearchFolders>
      <SearchFolder>Chargeable Tasks</SearchFolder>
    </SearchFolders>
  </TaskItem>
</InputData>

New for this example is the explicit <SearchOperator /> which we will try to use to look for values over a specific number and the <SearchFolder /> which is required to point to the non-standard folder used. With an XML document import as the source for the step – and this XML – the mappings will be:

When the task is queued, it might be expected that there would be two matching responses:

  1. Project Beta (15)
  2. Project Delta (35)

Actually there are four:

  1. Project Beta (15)
  2. Project Delta (35)
  3. Project Epsilon (Nine)
  4. Project Gamma (5)

This is because Exchange doesn’t perform a numeric evaluation, but rather a digit-by-digit comparison.  The first digit of our search (‘1’) is compared against the first digit of each of the Mileage values (‘1’, ’1’, ’5’, ‘3’, ‘N’, ‘0’).  Because we have a second digit in our search (the ‘0’ in the ‘10’) any that are equal are not yet discarded until the second digit has been evaluated.  The end result is that ‘Nine’ and ‘5’ are greater than ‘10’ and are therefore returned.  If a resilient business process was being developed here, clearly more work would be required post-Find.

Example 3 – Contact Item Find over multiple SearchFolders

This final example will perform a search for Contact Items using the Categories field.  The actual search repeats the methodology already seen in the previous two examples, but here the location of the contacts we are searching for could be in five different locations:

  1. Contacts – the default location for contacts.  This location only needs to be explicitly stated when a Find is over multiple locations.  Otherwise leaving the SearchFolder field unmapped would perform the search there regardless.
  2. Contacts\Clients – a ‘custom’ folder within the main default folder.  As all searches are ‘shallow’ this needs to be provided to capture contacts in this sub-location.
  3. Backup\Saved Contacts – a ‘custom’ contact folder inside another ‘custom’ folder.
  4. myContacts – a ‘custom’ folder at the same level as the main Contacts folder.
  5. PublicFoldersRoot:Public Folder Root\Public Contacts – a public contacts folder.  The ‘PublicFoldersRoot:’ part of this path is an Exchange prefix and is only required because we will map the MailboxEmailAddress and therefore need to tell Exchange that this isn’t a local folder.  If the MailboxEmailAddress wasn’t mapped the prefix part wouldn’t be required (as will be seen later).

Our source XML with the five <SearchFolder /> elements therefore looks like:

<?xml version="1.0"?>
<InputData>
  <ContactItem>
    <MailboxEmailAddress>mecuser1@exch2016.local</MailboxEmailAddress>
    <SearchField>Categories</SearchField>
    <SearchExpression>Client</SearchExpression>
    <SearchFolders>
      <SearchFolder>Contacts</SearchFolder>
      <SearchFolder>Contacts\Clients</SearchFolder>
      <SearchFolder>Backup\Saved Contacts</SearchFolder>
      <SearchFolder>myContacts</SearchFolder>
      <SearchFolder>PublicFoldersRoot:Public Folder Root\Public Contacts</SearchFolder>
    </SearchFolders>
  </ContactItem>
</InputData>

In the Exchange Tool, the mappings using this as a source will now be familiar:

Any task containing an Exchange step using this source will search across all of these locations and return any ExchangeContactIds where a match was found.  If the local folder searches were not required and only the public folder was to be searched, the XML and the mappings could be simplified to:

<?xml version="1.0"?>
<InputData>
  <ContactItem>
    <SearchField>Categories</SearchField>
    <SearchExpression>Client</SearchExpression>
    <SearchFolders>
      <SearchFolder>Public Folder Root\Public Contacts</SearchFolder>
    </SearchFolders>
  </ContactItem>
</InputData>

Note that the MailboxEmailAddress is no longer required as the Find is only being performed on a public folder and the SearchFolder prefix has also been removed for the same reason.

Microsoft Exchange Integration Brochure

Microsoft Exchange Integration Brochure

Learn how integrating Microsoft Exchange with business applications increases the visibility of key information and enhances employee productivity.

Download Brochure