

You even have options to EXPORT them (from which you can also take them into Outlook).
Sumatra Development leads the field of migrating entire calendar servers to Exchange. We migrate Oracle Calendar Server, Oracle Beehive, Apple iCalendar, and Zimbra to Microsoft Exchange keeping all meeting information and resource bookings intact. We migrate calendars server-to-server between Exchange and Office 365 while keeping meetings live and doing incremental syncs quicker than any other solution.


You even have options to EXPORT them (from which you can also take them into Outlook).



In "New" Outlook I see this (we had no doubt our friends in New Zealand were correct about this, but we love the phrase "trust but verify"):
We did manage to extract the contact data and what we had to do was make it all REALLY EXPLICIT. Note that I also used two different versions of Outlook (2002 vs. 2003) just to keep the locations straight.
To start in OCFO select File-Import and Export:

You're exporting to a file





Now on the Exchange side, you can run the process in reverse, or you can use Data File Management

Point to your contacts.pst file,
And the end result is that you've got your contacts over:
So for the really curious calendar person: What the heck is going on here?
Let's take a look at the file structure of OCFO. Almost all the files under the /Outlook/Oracle Connector... directory are pretty small, except for the one I found called "mdb" which being within the same order of magnitude as the PST files we found makes it a good candidate for the location where OCFO data gets stored.

In fact there are several of these throughout this directory structure. Those of you who ever had the pleasure of working in 1980's era dBase will feel deja-vu. I started doing correlations between GUIDs for the contacts in Outlook/OCFO and the data here using a binary viewer, but that got to be a hassle very quickly. Russ looked at running SOAP requests for contact data using the OCS API, which he rapidly decided was "obscure and painful."
We know the contact data is in there (somewhere), but the method we sketch above has the advantages of being simple, fast, and actionable without coding.
Penn's problem was that Zimbra is set up to handle Free-Busy data with Exchange 2003 via Public Folders (which are de-emphasized in Exchange 2007).
Exchange looking at Zimbra Free-Busy was no problem, but Zimbra looking at Exchange was generating an error like:
ERROR [EXCHANGE Free/Busy Sync Queue] [] fb - cannot modify resource
However, you can get it to work. The Magic PowerShell Command on the Exchange side is:fydibohf23spdlt)/"# Specify the Service Account
mcf zimbraFreebusyExchangeAuthUsername
zimbramcf zimbraFreebusyExchangeAuthPassword
[password]mcf zimbraFreebusyExchangeAuthScheme form
# Specify the url to Exchange 2007 CAS
servermcf zimbraFreebusyExchangeURL
https://cas.exchange.YOURDOMAIN.com/# Set the legacydn in Exchange 2007
mcf zimbraFreebusyExchangeUserOrg "/o=First
Organization/ou=Exchange Administrative Group (
Linux folk and Arthur C. Clarke fans: fydibohf23spdlt explained here.
To configure Free-Busy from Zimbra to Exchange:
1. Create a "Zimbra" OU in Active Directory. Make sure all your Zimbra users are in it. But let's define some rules for keeping everyone straight:
2. Set the Service Account ("zimbra") to update the Free-Busy folder. You do this in PowerShell on the Exchange side.
add-publicfolderclientpermission -identity "\NON_IPM_SUBTREE\SCHEDULE+ FREE
BUSY\EX:/o=First Organization/ou=Exchange Administrative Group
(FYDIBOHF23SPDLT)" -user zimbra -accessrights owner
3. Make Exchange 2007 aware of the Public Folders in the Zimbra domain. You do this in PowerShell on the Exchange side:
Add-AvailabilityAddressSpace -forestname zimbra.YOURDOMAIN.COM -accessmethod publicfolder
4. Update Zimbra accounts to be aware of the email accounts on the AD side. You do this in Zimbra.
# add link from elvis to elvis_zimbra mail contact in AD
ma elvis@zimbra.yourdomain.com +zimbraForeignPrincipal ad:elvis_zimbra
# add link to OU
ma zimbraFreeBusyExchangeUserOrg "/o=First Organization/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)"

Keep your eyes on your inboxes, folks.
And these are pretty much all the options you've got -- your only choice is order, and whether to take them or ignore them. Let's work with the defaults. An export of 1 standalone appointment, 1 meeting, and 1 repeating appointment (which I erroneously called a meeting in the screenshot) results in the following text file (split for ease of viewing):
There are very few surprises here. You have the date of the appointment, the start and end times, the title, notes, categories, and priorities. You can clearly read this into any spreadsheet of your choice and order / manipulate the data into something that almost any other client will accept. If you need iCalendar that will require some more work but it's computer science, not rocket science.
Next thing to notice.
Following down the path C:\Program Files\Now Software\Now Up-to-Date
I find that my data file (*.nud) is 62 KB in size, containing a total of three meetings / appointments of various sizes.
Following down the path to my server (C:\Program Files\Now Software\NSM\Servers\SumatraNUTDServer) where I have already created another user, some public categories, a Meeting Room, and a Resource, I find that file to be 4 KB in size. This size disparity between server and client speaks volumes.
Server Side Analysis
Pretty much the only thing you can do is start it, stop it, add / configure users, resources, and rooms, and a few other things. While there is an automated backup option, noticeable absent is any kind of server-side export capability (which allowed us to migrate Oracle and Meeting Maker wherever they need to go) or any tools for direct manipulation of data server-side.
So let's see what we can grab off the shelf.
First thing we'd notice is that on Windows this server file helpfully has a .DB extension, indicating that it is a database (d'oh), most probably relational (semi d'oh again - there are object-oriented calendar databases) and perhaps built with an off-the-shelf package whose judicious use of import / export and clever analysis might result in the schema and associated data structures.
Let's hold that last idea for a bit (because it will be quite a lot of work fumbling about for the right package and I already went through two candidates) and just let our ADHD selves open the server database with a binary file viewer, the curious calendar migrator's best friend. I like BinViewer.
The meeting "First Meeting" is definitely in here. I know on the client side that I associated it with Room222, Resource1, and my co-worked Russ....
... who also all exist in this database. I'll leave it as an exercise to the interested reader to determine if the Administrator passwords for these objects are in the clear or weakly encoded.

Most notably here where we see the name of the meeting in clear text and the human guest associated with it. A little additional work is required to see the relationship of the associated resource and room. Searching for the name of any appointment you created client-side comes up negative, confirming that the appointments are not present on the server. Notice I have not dug into the issue of recurrence patterns in meeting data server side yet because I already know where this is leading. 
Short answer: we know the relevant meeting data is present server-side, and we know if we start coding into the bit field of a shutdown server database we have very good odds of reconstructing it.
The more important issue is: DO WE WANT TO?
We already know that at the very least we're going to need to touch every client to extract their appointments, banners, tasks, etc. Running another server-side process to get at the live meeting data sounds questionable: it's running two disparate processes where one is almost always far and away preferable, and making sure both processes jibe with each other.
Conclusion
Unless you've got a few thousand NUTD users (which is hard to believe) who all absolutely need their guest lists and recurrence patterns, stay client-side and don't spend a lot other than scripting time when you decide to migrate.


But if we just delete him then his meetings will linger (with no way to cancel them). So in the Conference Room 222 calendar, Elvis is still very much alive!

Now, if we wanted to cancel all of Elvis's meetings BEFORE we deleted him from Active Directory, that would be easy. Just run our tool and click Test2: Report/CancelMtgs
You get options like

And let everyone know why.
BUT let's say users have been being deleted for a while or we deleted Elvis before removing his meetings. We can STILL clean out the resources (we can do the users, too, but let's focus on the rooms and resources).
Let's say we're looking to clear out the cruft from Conference Room 222.

It will find all instances of Elvis's recurring meetings in it (as well as any other broken meetings, but I happen to know the only ones in there just now belong to Elvis)



The more astute among you will recognize there are some additional subtleties to this, but I'll save those for another blog posting.
Editorial addition (Sept 14, 2008)
The "Export Mailbox" cmdlet will archive all Elvis's data to a PST, but it does NOT cancel his meetings. See this discussion.

So let's look at one of them.
Content-class: urn:content-classes:appointment Subject: private noon Date: Wed, 2 Apr 2008 05:35:01 -0400 Message-ID: <F47225046904E34AAA50D7CFB96277FC03AED5@trout.sumatra.local> X-MS-Has-Attach: MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----_=_NextPart_001_01C894A4.D2E612E0" X-MS-TNEF-Correlator: Thread-Topic: private noon Thread-Index: AciUpNLoQOwqLSklRJaoHMVqqUnkhQ== Sensitivity: Private x-mimeole: Produced By Microsoft Exchange V6.5 From: "zyg furmaniuk" <zyg@sumatra.local> METHOD:REQUEST PRODID:Microsoft CDO for Microsoft Exchange VERSION:2.0 BEGIN:VTIMEZONE TZID:(GMT-05.00) Eastern Time (US & Canada) X-MICROSOFT-CDO-TZID:10 BEGIN:STANDARDDTSTART:16010101T020000TZOFFSETFROM:-0400TZOFFSETTO:-0500RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=11;BYDAY=1SUEND:STANDARDBEGIN:DAYLIGHTDTSTART:16010101T020000TZOFFSETFROM:-0500TZOFFSETTO:-0400RRULE:FREQ=YEARLY;WKST=MO;INTERVAL=1;BYMONTH=3;BYDAY=2SUEND:DAYLIGHTEND:VTIMEZONEBEGIN:VEVENTDTSTAMP:20080414T173637ZDTSTART;TZID="(GMT-05.00) Eastern Time (US & Canada)":20080402T120000 SUMMARY:private noon UID:040000008200E00074C5B7101A82E00800000000E072D44B8394C801000000000000000 0100000002D6C78C6FF3E504D8F29FB17733C0F74 ORGANIZER;CN="zyg furmaniuk":MAILTO:zyg@sumatra.local LOCATION: DTEND;TZID="(GMT-05.00) Eastern Time (US & Canada)":20080402T130000 SEQUENCE:0 PRIORITY:5 CLASS:Private CREATED:20080402T093448Z LAST-MODIFIED:20080402T093501Z STATUS:TENTATIVE TRANSP:OPAQUE X-MICROSOFT-CDO-BUSYSTATUS:BUSY X-MICROSOFT-CDO-INSTTYPE:0 X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY X-MICROSOFT-CDO-ALLDAYEVENT:FALSE X-MICROSOFT-CDO-IMPORTANCE:1 X-MICROSOFT-CDO-OWNERAPPTID:-1 X-MICROSOFT-CDO-APPT-SEQUENCE:0 X-MICROSOFT-CDO-ATTENDEE-CRITICAL-CHANGE:20080402T093501Z BEGIN:VALARM ACTION:DISPLAY DESCRIPTION:REMINDER TRIGGER;RELATED=START:-PT05H00M00S END:VALARM END:VEVENT END:VCALENDAR |
So you remove everything that is not iCalendar (i.e., the email header and that small footer following the END:VCALENDAR) and swap out your email address or domain if necessary. I didn't in the example that follows and it didn't come in properly.
Upload to Zimbra using something like curl, and your before and after shots look like this:


Keep in mind, this will happen one meeting or activity at a time.
Have we rigorously tested every aspect of this? HECK NO! But this gave us enough to go on that we knew if we needed to modify something (like possibly recurrence patterns, exceptions, or maybe the GUID format) that we'd able to figure it out. Again, this is meant to suggest a more general methodology for moving calendar data out of Exchange 2000/2003.
Of course you can do pretty much the same thing with your email as well. We tested that and got attachments to come over. BUT, we learned to add an additional tag X-Zimbra-Received as per this article.
For a masterful discussion of using the M: drive in Exchange for a migration see: Migrating from POP3/SMTP servers using the M Drive
So to modify Delegate programmatically you need to take care of ALL of these.
Folder Security Descriptors
For Exchange 2000 and 2003, see Modifying Store Permissions in Exchange 2000 and 2003
For Exchange 2007 you use the Management Shell.
Every object (and a folder is an object with other objects potentially inside it) in the Exchange database has a security descriptor that determines who can access it. One of the main sources of confusion in all this is that from WebDAV Exchange can SEEM like it's a filesystem (remember the (in)famous M: drive?) but it never acts like one in any API. PFDAVAdmin does a great job at modifying access permissions for both Exchange 2003 and 2007.
Active Directory
Send-As permissions are kept in AD. The field publicdelegates contains the list of URLs of all users with access to the mailbox. Active Directory does a BIG favor here by maintaining backlinks in other users' publicDelegatesBL.
So by checking any user's publicDelegatesBL property, you can find out for whom they are a delegate. This was put to creative use in Listing Which Exchange Users Have or Are Delegates and Finding delegates in Active Directory (sic).
The perceptive among you will realize that if you are a delegate to someone and they have subsequently been removed from Active Directory you might still have some kind of zombie connection to them. Such is often indeed the case.
NON_IPM_SUBTREE
The file NON_IPM_SUBTREE/Freebusy Data/LocalFreebusy.EML which not surprisingly contains Free-Busy data (but be careful trying to read it) also contains three MAPI properties which define Delegates.
Private items have PR_SENSITIVITY =2, Public items have PR_SENSITIVITY = 0. Confidential items have PR_SENSITIVITY =3, but Outlook does not do anything with Confidential items and the Exchange server does nothing to enforce Private items leaving this to the client (ever read me write that this was all designed and implemented by some committee somewhere?). So those of you looking to migrate this capability from Oracle Calendar Server where there is a client side distinction between Private and Confidential, you can migrate it, but it will do you no good.
BTW, Google has picked up on how useful it is to document MAPI tags.
Modifying the AD values has NO EFFECT on the values in the NON_IPM_SUBTREE. You have to take care of that separately. The incomparable Glen Scales blogged on how to in Accessing the NON_IPM_Subtree folders in Exchange Web Services .
Server-Side Rule
Like all SSRs this is in the INBOX for the user doing the forwarding (which means the client does not need to be running for it to be invoked, which is exactly what you want from an end-user perspective).
By way of comparison, PR_RULE_MSG_PROVIDER is
For managing rules in E2K7, check out http://msexchangeteam.com/archive/2008/04/14/448687.aspx and Glen has also already blogged on the topic.
I am hugely indebted to the work Ximian did in reverse-engineering all of this before it was absorbed by Novell.
# ************************************************************************ # Created for PFDAVAdmin 2.8 # Friday, August 29, 2008 3:47:25 PM # ************************************************************************ # # This export format is only usable with PFDAVAdmin 2.0 and later. # # ************************************************************************ SETACL Mailboxes\riuliano\Freebusy Data VM\zyg Reviewer NT AUTHORITY\ANONYMOUS LOGON None NO SETACL Mailboxes\riuliano\Top of Information Store\Calendar VM\zyg Reviewer NT AUTHORITY\ANONYMOUS LOGON None NO SETACL Mailboxes\zyg\Freebusy Data VM\riuliano Reviewer NT AUTHORITY\ANONYMOUS LOGON None NO SETACL Mailboxes\zyg\Top of Information Store\Calendar VM\riuliano Reviewer NT AUTHORITY\ANONYMOUS LOGON None NO |

THEN it will show up in the Exchange Management Console!
What do you do with it now?
Either one will get you there.
We also insert data into the Billing field (for the technically inclined, they're the GUIDs of the calendar objects so we're sure we're acting on the correct objects when migrating).
We also know of at least one other application that uses the Mileage field for internal purposes - so keep an eye out.
