Paul Calnan
Published April 8, 2013

I recently received an email from a client of mine. They decided to block all iOS 6.1.3 users from syncing with the corporate Exchange server. This isn't a problem with email as I was able to configure IMAP easily. This was, however, a big problem for my calendar. Being unable to have an up-to-date schedule on my iPhone was out of the question.

I first looked at DavMail but couldn't get it to work. Instead I decided to make a duplicate of my Exchange calendar in iCloud.

(Update 2013-04-16) This wound up causing lots of problems with iCloud. Around when the script ran, I noticed in Console.app reports of the CalendarAgent process crashing repeatedly every few seconds. I'm not sure why, and didn't really dig too deeply to find out. Fortunately, my client re-enabled iOS syncing with Exchange, so the need for this script has gone away.

Step 1: Create a new iCloud calendar

In Calendar.app (formerly iCal) on OS X, create a new calendar (File > New Calendar > iCloud). Call it whatever you like.

(Update 2013-04-09) You'll want to Ignore Alerts on this calendar on your computer. Otherwise you'll get double alerts for every event. Right-click the calendar in the list and select Get Info. Check the Ignore Alerts checkbox and click OK.

Step 2: Create an AppleScript

The pivotal piece here is an AppleScript that does the following:

  1. Deletes all events from the destination iCloud calendar (created in Step 1 above).
  2. Copies all events from your Exchange calendar to the iCloud calendar.

For the purposes of this example, we'll call the Exchange calendar "Source Calendar" and the iCloud calendar "Destination Calendar".

We first delete all of the events from the destination calendar. We're not really syncing the calendars, rather we're copying all events from one to another. If we didn't delete first, events removed from the source calendar would never be removed from the destination calendar. Just be careful to use the right calendar names so you don't accidentally delete from wrong one!

Copy and paste the script above into the AppleScript Editor (usually found in /Applications/Utilities) and change the calendar names as necessary. Try it out and make sure you don't get any error messages. Save it someplace convenient and remember where you put it.

Step 3: Schedule the script to run

This step is optional. If you prefer, you can just run the script whenever you think of it. I decided to schedule it using Cron. This Wikipedia article provides a reasonable rundown of how Cron works, if you're unfamiliar with it.

In the Terminal, run:

crontab -e

This will launch a text editor. In it, you specify the schedule. In my case, I wanted to run it every two hours, Monday through Friday.

* */2 * * 1-5 osascript $HOME/Dropbox/Scripts/Applications/Calendar/Exchange\ Sync.scpt

Change the path to your AppleScript to match where you put it in Step 2.

(Apparently, you can wrap an AppleScript with an Automator workflow and schedule it to run using Calendar.app, but I haven't tried this approach.)

Conclusion

On a relatively new MacBook Pro, the script takes a couple of minutes to sync around 200 events. Presumably fewer events will sync faster. It may take a couple of minutes for the iCloud sync to go through before you see the events on your iOS device.

The script is pretty basic. I was going to make the sync go incrementally, but AppleScript is such a pain to program, I decided to go the naive route and just delete everything and copy it back over.

As usual, questions and feedback are always welcome.