1
votes

I have an application that creates appointments in calendars in Exchange Online for Office 365. I'm using EWS Managed API.

public void CreateAppoitment(string principalName, int taskId) {
  ExchangeService service = createService(principalName);

  ItemView itemView = new ItemView(1000);
  itemView.PropertySet = new PropertySet(BasePropertySet.IdOnly);

  List<Appointment> toCreate = new List<Appointment>();

  // Create the appointment.
  Appointment appointment = new Appointment(service);

  // Set properties on the appointment.
  appointment.Subject = "Test Appointment";
  appointment.Body = "The appointment ...";
  appointment.Start = new DateTime(2014, 6, 18, 9, 0, 0);
  appointment.End = appointment.Start.AddDays(2);

  ExtendedPropertyDefinition epdTaskId = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.Appointment, "TASK_Id", MapiPropertyType.Integer);
  appointment.SetExtendedProperty(epdTaskId, taskId);
  appointment.IsResponseRequested = false;
  toCreate.Add(appointment);
  ServiceResponseCollection<ServiceResponse> createResponse = service.CreateItems(toCreate, WellKnownFolderName.Calendar, MessageDisposition.SaveOnly, SendInvitationsMode.SendToNone);
}

Note I'm setting ExtendedPropertyDefinition "TASK_Id"

I'm using impersonate to create appointments in users's calendars:

private ExchangeService createService(string principalName) {
  ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013);
  service.Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx");
  service.UseDefaultCredentials = false;
  service.Credentials = new WebCredentials("XXXX", "YYYY");
  service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.PrincipalName, principalName);

  return service;
}

Then, given a taskId, I want to delete all appointments with this taskId:

public void DeleteAppointment(string principalName, int appointmentId) {
  ExchangeService service = createService(principalName);
  ItemView itemView = new ItemView(1000);
  itemView.PropertySet = new PropertySet(BasePropertySet.IdOnly);

  ExtendedPropertyDefinition epdTaskId = new ExtendedPropertyDefinition(
    DefaultExtendedPropertySet.Appointment, "TASK_Id", MapiPropertyType.Integer);

  SearchFilter filterOnTaskId = new SearchFilter.IsEqualTo(epdTaskId, appointmentId);
  FindItemsResults<Item> appointments = service.FindItems(WellKnownFolderName.Calendar, filterOnTaskId, itemView);
  List<ItemId> toDelete = appointments.Select(item => item.Id).ToList();
  if (toDelete.Count > 0) {
    ServiceResponseCollection<ServiceResponse> response = service.DeleteItems(
      toDelete, DeleteMode.MoveToDeletedItems, SendCancellationsMode.SendToNone,
      AffectedTaskOccurrence.SpecifiedOccurrenceOnly);

    foreach (ServiceResponse del in response) {
      if (del.Result == ServiceResult.Error) {
        //...
      }
    }
  }
}

But this way service.FindItems() only returns the principalName's appointment with TASK_Id = taskId and I want appointments of all users. Is there a way to to this?

1

1 Answers

0
votes

The Exchange Managed API and Exchange Web Services only give access to the calendar of one user at a time -- either directly by using the credentials of a user or indirectly by using impersonation to give a service account access to a user's calendar.

To search multiple calendars at once requires a different technique. One option that comes to mind is using the eDiscovery operations in Exchange 2013. Although they are usually used to find email for legal reasons, you may be able to use the same process. Unfortunately, the documentation for eDiscovery is pretty sparse right now, but you can see the EWS operations that are available here: eDiscovery in EWS in Exchange, and you can find the corresponding EWS Managed API methods on the ExchangeService object.