Meeting room reservations - integrate SharePoint 2010 with Exchange 2010

A few weeks ago from our customers we received the task of creating a service for booking meeting rooms. The company of the customer is satisfied with a large and very advanced in terms of IT. The customer has many branches throughout Russia and each has 5-6 meeting rooms, employees often fly to hold meetings from one branch to another, and finding a free audience “on the spot” is a real problem. Therefore, it would be nice for an employee to “stake out” a conversation directly from his workplace in Moscow, for example, in Tula and with a clear conscience to fly on a business trip. We want to share the experience of creating such a service with the habrosociety.

Analysis

We knew that the customer’s company has an internal portal made on Microsoft SharePoint 2010, which is used by about 1,500 employees every day. Plus, the company has Exchange configured.

As you know, Exchange already has a feature for booking resources in the company. All this business was realized by means of room mailboxes. In fact, each meeting room has its own mailing address, and the employee must plan a meeting with this room. Other users using the mail client can connect to calendars and look at what date and time an appointment is made. In addition, Outlook 2010 has the functionality of Room Finder.

You can read in more detail here about the mailbox in Exchange http://technet.microsoft.com/en-us/library/bb124952(v=exchg.141).aspx

And here - about Room Finder'e http://support.microsoft.com/kb/2673231
It seems that everything looks cool and convenient. However, there are several drawbacks: firstly, the employee needs Outlook. Secondly, the description of the room is very poor; you cannot add a description of the resources (board, conference system, etc.) in a visual form.

Accordingly, the thought arose: how could we take out all the visual representation in SharePoint without losing the functionality of Exchange? At the same time, I wanted to write less code. But as practice has shown - it could not do without it :)
In general, let's
go!

SharePoint

To create the service, we made three lists: Divisions, Meeting rooms, Booking meeting rooms.

Units are branches in cities.

Meeting rooms are a list for storing rooms and their characteristics, such as:
  • name;
  • subdivision;
  • capacity;
  • the presence in the room of the projector, marker conference board, etc.
  • mailing address used for integration with MS Exchange.

And finally, the list of armor:
  • room;
  • date of the meeting;
  • start time;
  • end time;
  • author of the reservation.

So, we have lists, but someone should fill these lists, so we divided the users into roles:
  • Users can plan their meetings and meetings, book rooms or do a specialized search by parameters.
  • The administrator of the meeting rooms of a unit can transfer / cancel existing reservations within his unit.
  • The administrator creates and edits meeting rooms, as well as a directory with their characteristics - number of seats, projector, board, etc. Has the ability to switch between departments and act as the administrator of the meeting rooms.

UI

Because the customer’s design was already pulled onto the portal, our designers had to work a little bit. What they did very well:
1. The user’s main page:
2. By a separate link, you can go to the list of rooms. This list displays basic information. Detailed information about the room is displayed by clicking on the name of the room.



3. The “Audience Search” link displays a two-week calendar. Each cell displays the time, by whom the room is reserved and for what time.



4. By a separate click on the “plus sign” it will be possible to book a meeting room.



Implementation

To make this beauty, we needed to write a WCF service that returns json and at the same time works in the context of SharePoint. This problem is solved by the correct web.config and the presence of SVC in the ISAPI folder. A lot has been written about how to properly configure web.config to send json. For example, here:
http://www.codeproject.com/Articles/105273/Create-RESTful-WCF-Service-API-Step-By-Step-Guide
Next, we made several ASPX pages, added them to the module and implemented all the logic of working with a WCF service through javascript using a knockout framework.

The main problems we had with Exchange. Almost all the necessary functionality is implemented through calls to the EWS Managed API methods . However, we needed to automatically create mailboxes when creating an item in the list of rooms.

On the Internet, it was found that mailbox can only be created through powershell, and calling a command from a C # code is not a problem in principle.

We wrote an event receiver on the list of rooms and tried to call the powershell command on the remote server using Runspace and WSManConnectionInfo. However, firstly, it is not safe, and secondly, we did not succeed in doing this because of problems with access denied during connection.

As a result, we decided to write another WCF service and deploy it on a server with Exchange. In essence, this service has only one method:

public void CreateRoom(ExchangeRoom Room)
        {
            RunspaceConfiguration runspaceConfig = RunspaceConfiguration.Create();
            PSSnapInException snapEx = null;
            PSSnapInInfo psinfo = runspaceConfig.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.E2010", out snapEx);
            using (Runspace runSpace = RunspaceFactory.CreateRunspace(runspaceConfig))
            {
                runSpace.Open();

                if (!(MailBoxAlreadyExist(Room.Email, runSpace)))
                {
                    Command createMailbox = new Command("New-Mailbox");
                    createMailbox.Parameters.Add("UserPrincipalName", Room.Email);
                    createMailbox.Parameters.Add("Name", Room.Name);
                    createMailbox.Parameters.Add("Room");

                    using (Pipeline pipeLine = runSpace.CreatePipeline())
                    {
                        pipeLine.Commands.Add(createMailbox);
                        pipeLine.Invoke();
                    }                
                }
                else
                {
                    throw new Exception("Комната с таким адресом уже создана");
                }
            }
        }


As we wrote above, all the logic of work is implemented through the WCF service, so it was logical to supplement our service with methods for booking a room in Exchange. To do this, we called the service method to create our reservation in Exchange. All the necessary information was placed in Microsoft.Exchange.Data.Appointment, and then using the API a meeting was created in the Exchange calendar.

public static void CreateReservation(Reservation reservation)
        {        
            InitService();

            var appointment = new Appointment(service);
            appointment.Subject = "Meeting";
            appointment.Start = new DateTime(reservation.Date.Year, reservation.Date.Month, reservation.Date.Day, reservation.FromTime, 0, 0);
            appointment.End = new DateTime(reservation.Date.Year, reservation.Date.Month, reservation.Date.Day, reservation.ToTime, 0, 0);            
            
            string roomMailboxAddress = string.Format("room_{0}@{1}",reservation.RoomId, SharePointConstantString.MailDomain);
            appointment.Location = reservation.RoomName;            
            appointment.Resources.Add(roomMailboxAddress);
            appointment.RequiredAttendees.Add(reservation.User.Email);            

            appointment.Save(SendInvitationsMode.SendToAllAndSaveCopy);
        }


The problem of “reverse” synchronization (that is, when an employee in his calendar booked a room through Outlook) was decided to be solved through a timer job. This job collected all the information from Exchange and created the missing armor, and deleted the canceled ones.

Total

We managed to create such an architecture that allows you to get a scalable and flexible solution, built on the Microsoft technology stack and using all the advantages of an integrated solution. The system is customizable and comes with standard platform tools.

Because м образом, сегодня
  • the company's management receives common collaboration tools that increase the efficiency of a large number of employees;
  • employees of the company plan their work and key meetings and meetings easier, faster and without nerves;
  • IT staff got a flexible, scalable solution, which is accompanied by standard tools and makes the most of out-of-box functionality. So, when switching to new versions of SharePoint and Exchange, there will not be any special problems.