Adding and removing meetings in Outlook using PowerShell

Over a couple of posts I plan to describe how I have used PowerShell to add and, more importantly, cancel meetings in a third party’s Outlook Calendar using PowerShell.

As is typically the case for these sorts of posts, it represents a distillation of and extension to a number of blog posts and forum answers that I have trawled through over a number of days working on this problem.  Unusually, I did not find any one source that provided the basis for the solution. Instead there are a number of sources that address various aspects of the problem, often several contributors saying pretty much the same thing. However, I have been struck by the relative paucity of PowerShell specific guidance on this sort of thing, and have found myself having to translate C# code into PowerShell on more than one occasion. Perhaps this indicates that this approach to managing meetings in Exchange is not best practice, but as PowerShell is starting to pervade all aspects of the Microsoft stack I thought it might be interesting to pass on my experience of stitching together hints and pointers from may sources.

The scenario

This development is part of a much larger service management system. As part of the service clients can book a range of appointments with relevant practitioners either directly online or through reception staff who will take the details and enter them into the online system on the client’s behalf. The online system handles the allocation of time slots among practitioners and appointment types, but here the requirement was that the practitioners wanted their appointments to appear in their personal Outlook calendar, and for cancelled appointments to be properly flagged.

In other settings it might have been appropriate to use a shared calendar or for practitioners to add a SharePoint calendar. Alternatively a separate interface within the online system could have provided personalised information to each practitioner. However these practitioners were often accessing their workload data remotely, and they have considerable autonomy in their choice of technologies to support their work, so in our setting it was necessary for the practitioners to have appointments in their own personal Exchange calendar without using any additional or added calendars.

The solution, inspired by a similar system developed by colleagues at the University of St. Andrews, was to create all the Exchange appointments in a central calendar managed by the admin team. The practitioner would then be added as a required attendee at the meeting. This would trigger the appointment to appear in the practitioner’s calendar. If the practitioner deleted or edited the appointment this would be flagged in the central calendar for the admin team to investigate. When appointments were cancelled in the central calendar the practitioner would see that the appointment had been cancelled in their calendar and could remove the entry.

Why PowerShell?

Given that the bookings that need to be synchronised with an Outlook calendar are made through an online form PowerShell is not the only, or even the most obvious, option, however in our setting it was an attractive one for various reasons:

1 PowerShell is self-contained

As we shall see it does required some additions, but fundamentally it does not rely on the CMS or any other system to perform these tasks; all it needs is access to the source data and the Exchange Web Services. While we run the script on the same host as the CMS it is not necessary and we could, in theory, have a dedicated VM just running our scheduled PS scripts.

2 it is easy to schedule

While the CMS has support for scheduling actions, as we have access to the host OS it is simpler to set up scheduled tasks in Windows than to create something that would run from the CMS. There are already other PS scripts scheduled so it also makes it simpler to choreograph them when they are all in the one place. There is an argument for making the setting and cancelling of appointments a real time push from the online forms to Outlook, and this would be possible if we developed something within the CMS. However, in our environment there are disadvantages to a real-time sync. Very often the booking is part of a discussion or at least deliberation where the client might be exploring several options. In this case bookings can be made and then cancelled almost immediately as the client weights up the implications of the booking. The appointment being booked is also at least one and often several days in advance for a fixed number of time slots, so the practitioners do not need to know immediately who is attending a particular session, they just need to know in time. There is no danger of the delay in synchronisation causing problems with bookings as all bookings are handled through the CMS.

3 it is easy to write

The relative ease or difficulty of any scripting task is primarily a function of the developer’s skill and experience in a particular language and environment. Working with the Microsoft stack there are a wide range of languages and frameworks to choose from. When you add the additional complexity of working within a software platform like SharePoint or DNN developers experienced in the underlying language often find the environment makes life even more complex; just ask .NET developer what it is like to work inside SharePoint for the first time.

In this enviroment PowerShell can play the role as common denominator or lingua franca. In a team where developers and devops work in different languages and on different software platforms on the Microsoft stack, it can be difficult to write custom code that can be supported by anyone in the team. As PowerShell becomes ever more ubiquitous across the stack, most professionals have some exposure to the language and can quickly get to grips with a self-contained script.

The anatomy of the script

The essence of the script is quite simple, performing two basic actions

  • Read the CMS database for appointments that have yet to be created in Exchange and create them
  • Read the CMS database for appointments that have been created in Exchange and have subsequently been cancelled and cancel them

(in our production environment these two actions are actually separate and embedded in larger scripts that perform a number of other actions; I will highlight the code that is common to both)

In the following posts I will describe