<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Carlos&#039; Corner &#187; ExchangeWebServices</title>
	<atom:link href="http://cars.lostroncos.org/category/exchangewebservices/feed/" rel="self" type="application/rss+xml" />
	<link>http://cars.lostroncos.org</link>
	<description>The tired geek-dad in the corner</description>
	<lastBuildDate>Wed, 11 May 2011 03:33:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>Generating an ATOM feed from an Exchange 2007/10 calendar</title>
		<link>http://cars.lostroncos.org/2010/01/25/generating-an-atom-feed-from-an-exchange-calendar/</link>
		<comments>http://cars.lostroncos.org/2010/01/25/generating-an-atom-feed-from-an-exchange-calendar/#comments</comments>
		<pubDate>Tue, 26 Jan 2010 06:58:43 +0000</pubDate>
		<dc:creator>cars</dc:creator>
				<category><![CDATA[Exchange]]></category>
		<category><![CDATA[ExchangeWebServices]]></category>
		<category><![CDATA[Home Lab]]></category>
		<category><![CDATA[ATOM]]></category>
		<category><![CDATA[EWS]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[RSS]]></category>
		<category><![CDATA[SOAP]]></category>
		<category><![CDATA[wsdl]]></category>

		<guid isPermaLink="false">http://cars.lostroncos.org/?p=262</guid>
		<description><![CDATA[<p>I was in a meeting a little while back where we had a brief discussion regarding the ability to get data out of Exchange 2007/2010 from a non-Windows OS. The example thrown out was the ability to get an RSS feed from Google Calendar for use elsewhere. I&#8217;ve know about Exchange Web Services (EWS) [...]]]></description>
			<content:encoded><![CDATA[<p>I was in a meeting a little while back where we had a brief discussion regarding the ability to get data out of Exchange 2007/2010 from a non-Windows OS. The example thrown out was the ability to get an RSS feed from Google Calendar for use elsewhere. I&#8217;ve know about Exchange Web Services (EWS) for a while and always wanted to look into using it in a project just to get some familiarity with it. With Exchange 2010 coming out this seemed like a good opportunity to try to see if I could generate an RSS feed from my calendar in a lab environment using a non-.Net language on Linux. I decided to try doing this using PHP, (incorrectly) assuming that there&#8217; be some easily discoverable examples I could download and tweak to do what I wanted.</p>
<p>I did discover some snippets and information that helped point me in the right direction, but no simple complete &#8220;here run this&#8221; kind of examples. I initially came across an article by Thomas Rabaix on using SOAP PHP and NTLM authentication (<a href="http://rabaix.net/en/articles/2008/03/13/using-soap-php-with-ntlm-authentication">http://rabaix.net/en/articles/2008/03/13/using-soap-php-with-ntlm-authentication</a> ). This code used cURL to help handle NTLM authentication to an IIS server. That then led me to an article by Erik Cederstrand <a href="http://www.howtoforge.com/talking-soap-with-exchange">http://www.howtoforge.com/talking-soap-with-exchange</a> that built on Thomas&#8217; work. Between them these two extend the PHP SOAPClient and then override some of the methods to use curl to handle the NTLM authentication that EWS uses by default. Using these examples as a starting point and some other bits of info I&#8217;ve come across I&#8217;ve been able to put together a couple of scripts that will generate an ATOM based feed using a user&#8217;s calendar. What I&#8217;ve managed to cobble together works but is not something I&#8217;d describe as robust. The solution is briefly described below. I&#8217;m hoping to follow up with a few other posts that go into a bit more detail about how all the pieces work. <em>[the code is available <a href="http://cars.lostroncos.org/wp-content/uploads/2010/01/ews-cal-rss.tar.gz"> from here </a> or from <a href="http://code.google.com/p/exchange-calendar-rss/">Google Code</a> ]</em></p>
<h2>The scripts in action</h2>
<p>In my example Exchange environment I&#8217;ve created a user called (imaginatively enough)<em> ctronco</em>. Opening up Outlook for the user I can see the following events on this weeks calendar.</p>
<p><img src="http://cars.lostroncos.org/wp-content/uploads/2010/01/012610_0657_Generatinga1.png" alt="" /></p>
<p>Turning now to the Ubuntu box where I&#8217;ve installed the PHP scripts. Firing up a browser and pointing it to the correct URL (http://192.168.1.175/ewscalendarfeed/getfeed/ctronco) I get the following results in Firefox, Internet Explorer and Opera (Chrome doesn&#8217;t appear to like feeds so I haven&#8217;t included it).</p>
<table border="0">
<tbody>
<tr>
<td style="text-align: center;"><strong>Output in Firefox</strong></td>
<td style="text-align: center;"><strong>Output in Internet Explorer</strong></td>
<td style="text-align: center;"><strong>Output in Opera</strong></td>
</tr>
<tr>
<td><a href="http://cars.lostroncos.org/wp-content/uploads/2010/01/012610_0657_Generatinga2.png" target="_blank"><img class="aligncenter size-medium wp-image-253" title="Firefox Output" src="http://cars.lostroncos.org/wp-content/uploads/2010/01/012610_0657_Generatinga2-226x300.png" alt="Firefox Output" width="226" height="300" /></a></td>
<td><a href="http://cars.lostroncos.org/wp-content/uploads/2010/01/012610_0657_Generatinga3.png" target="_blank"><img class="aligncenter size-medium wp-image-254" title="Output in IE" src="http://cars.lostroncos.org/wp-content/uploads/2010/01/012610_0657_Generatinga3-229x300.png" alt="Output in IE" width="229" height="300" /></a></td>
<td><a href="http://cars.lostroncos.org/wp-content/uploads/2010/01/012610_0657_Generatinga4.png" target="_blank"><img class="aligncenter size-medium wp-image-255" title="Output in Opera" src="http://cars.lostroncos.org/wp-content/uploads/2010/01/012610_0657_Generatinga4-220x300.png" alt="Output in Opera" width="220" height="300" /></a></td>
</tr>
</tbody>
</table>
<p><span id="more-262"></span><br />
Clicking on the link of any of the individual entries will return a web a page with the same information about the individual appointment as well:</p>
<p><img src="http://cars.lostroncos.org/wp-content/uploads/2010/01/012610_0657_Generatinga5.png" alt="" /></p>
<h2>How it works (at a high level)?</h2>
<p>Rather than keeping each user&#8217;s credentials around I decided to use a non-privileged account. This means that that account has to have <strong>Reviewer</strong> permissions for every calendar that will have a feed generated for it. Adding permissions for the account is a relatively straightforward proposition if you&#8217;re using Outlook. It can also be done via EWS for non-Outlook folks, I just haven&#8217;t gotten that piece done yet.</p>
<p><img src="http://cars.lostroncos.org/wp-content/uploads/2010/01/012610_0657_Generatinga6.png" alt="" /></p>
<p>The configuration file for the scripts has a list of known calendar &#8220;names&#8221; and the identifying information to retrieve the calendar from Exchange. Each accessible calendar has to have a unique name as far as the scripts are concerned. This is because each user can have more than one calendar available for generating a feed and I wanted to be able to support showing more than one per user.</p>
<p><img src="http://cars.lostroncos.org/wp-content/uploads/2010/01/012610_0657_Generatinga7.png" alt="" /></p>
<p>The naming convention you use will be up to you. Using the four calendars shown above in my test user&#8217;s mailbox either of the following example schemes would work for creating unique name for each of the calendars.</p>
<div>
<table border="1">
<tbody>
<tr>
<td>Original &#8220;Outlook&#8221; name</td>
<td>+1 scheme</td>
<td>descriptive</td>
</tr>
<tr>
<td>Calendar</td>
<td>ctronco</td>
<td>ctronco-calendar</td>
</tr>
<tr>
<td>Calendar2</td>
<td>ctronco1</td>
<td>ctronco-calendar2</td>
</tr>
<tr>
<td>Cal-sub-1</td>
<td>ctronco2</td>
<td>ctronco-cal-sub-1</td>
</tr>
<tr>
<td>fed</td>
<td>ctronco3</td>
<td>ctronco-fed</td>
</tr>
</tbody>
</table>
</div>
<p>In addition to the unique name the configuration file also needs to be given the unique Folder Id and Changekey values from EWS to retrieve them. These values aren&#8217;t easily accessible via Outlook (as far as I can tell)so I&#8217;ve included a web form (list_calendars.html) which will prompt for a user&#8217;s credentials and then list the calendars in their mailbox as well as the associated <strong>Folder Id</strong> and <strong>ChangeKey.</strong> Example output is shown:</p>
<p><img src="http://cars.lostroncos.org/wp-content/uploads/2010/01/012610_0657_Generatinga8.png" alt="" /></p>
<p><em>If you install the package php5-cli, list_calendars.php (the script called by the html file) can also be run from a shell on the Ubuntu box by passing the username and password as parameters.</em></p>
<h2>Setting things up</h2>
<h3>Exchange</h3>
<p>The first thing I had to do was set up Windows 2008 and Exchange 2007 in my home lab (at the time I had hardware that wouldn&#8217;t support 64-bit VMs so I couldn&#8217;t do Exchange 2010). I set up a single machine as both an AD Domain Controller and an Exchange server with the HUB, CAS, and Mailbox roles on it. Based on my initial testing this will also work just fine with Exchange 2010.</p>
<h3>Ubuntu</h3>
<p>For my test PHP environment I set up another VM running Ubuntu 9.10 Server with the LAMP option chosen at installation.</p>
<p><img src="http://cars.lostroncos.org/wp-content/uploads/2010/01/012610_0657_Generatinga9.png" alt="" /></p>
<p>Once the OS install was complete I also had to install the<strong><em> libcurl3</em></strong> and <strong><em>php5-curl</em></strong> packages.</p>
<p>The initial version of the source code is available<a href="http://cars.lostroncos.org/wp-content/uploads/2010/01/ews-cal-rss.tar.gz"> here as a zip file</a>. In addition I&#8217;ve created a<a href="http://code.google.com/p/exchange-calendar-rss/" target="_blank"> project on Google Code </a>where the most recent versions can be retrieved as I work on it further.</p>
<p>To install it simply unzip the tar file in a location where apache (or the web server of your choice) can read the files. It will uninstall into a directory called ews-cal-rss. You&#8217;re welcome to change this to whatever you desire.</p>
<p><img src="http://cars.lostroncos.org/wp-content/uploads/2010/01/012610_0657_Generatinga10.png" alt="" /></p>
<p>In the example I&#8217;ve also changed the ownership of the directory so that it&#8217;s owned by the same login the web server runs under.</p>
<p>In the directory where the extracted files are you&#8217;ll find cfg_options.php. This contains almost all the configurable values. The following values need to be defined:</p>
<ul>
<li>$cfg_option['user'] &#8211; Login Id of the non-privileged account that will used to read all the calendars</li>
<li>$cfg_option[''] -</li>
<li>$cfg_option['authmethod'] &#8211; the scripts support both Basic and NTLM authentication when talking to EWS. NTLM required installation of curl</li>
<li>$cfg_option['wsdl'] &#8211; path to the appropriate Exchange Web Services WSDL file.</li>
<li>$cfg_option['installpath'] &#8211; full path to the scripts</li>
<li>$cfg_option['urlpath'] &#8211; URL for the scripts. If the script URL is http://host/ews-cal-rss/getfeed.php this would be &#8220;/ews-cal-rss&#8221;</li>
<li>You also need to populate the variable $PFIDs using the list_calendars.html file as shown above.</li>
</ul>
<p>In addition you need to modify the appropriate WSDL file for your environment. WSDL files are included for both Exchange 2007 and 2010. They are in<em><strong> &lt;installdir&gt;/e2k7_wsdl</strong></em> or <strong><em>&lt;installdir&gt;/e2kx_wsdl</em></strong> respectively. The services.wsdl needs to be modified to point to your Exchange server. At the end of the services.wsdl file you&#8217;ll find the following:</p>
<div class="codecolorer-container xml blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/wsdl:operation<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/wsdl:binding<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;wsdl:service</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;ExchangeServices&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;wsdl:port</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;ExchangeServicePort&quot;</span> <span style="color: #000066;">binding</span>=<span style="color: #ff0000;">&quot;tns:ExchangeServiceBinding&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;soap:address</span> <span style="color: #000066;">location</span>=<span style="color: #ff0000;">&quot;https://exchange.company.com/EWS/Exchange.asmx&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/wsdl:port<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/wsdl:service<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/wsdl:definitions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></div>
<p>You need to modify the soap:address entry to point to your Exchange server. In my case that would be</p>
<div class="codecolorer-container xml blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/wsdl:operation<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/wsdl:binding<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;wsdl:service</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;ExchangeServices&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;wsdl:port</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;ExchangeServicePort&quot;</span> <span style="color: #000066;">binding</span>=<span style="color: #ff0000;">&quot;tns:ExchangeServiceBinding&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;soap:address</span> <span style="color: #000066;">location</span>=<span style="color: #ff0000;">&quot;https://e2k7.exchange.lostroncos.org/EWS/Exchange.asmx&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/wsdl:port<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/wsdl:service<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/wsdl:definitions<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></div>
<h2>A few miscellaneous notes:</h2>
<ul>
<li>It is also possible to use calendars in a public folder to generate the feeds. However listing them is slightly more involved than it is for a users calendars.</li>
</ul>
<ul>
<li>Re: the use of NTLM. It is also possible to modify the Exchange server&#8217;s web server configuration to enable the use of &#8216;Basic&#8217; authentication in addition to NTLM. Since by default communication with the Exchange server takes place over HTTPS this may or may not be acceptable in your environment. Using basic authentication gets you out of having to install the cURL bits, but may or may not be acceptable from a security perspective depending on your environment.</li>
<li>This is a test to see if this works better than the 32 bit version of IE does in full screen visual mode with wordpress&#8230;.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://cars.lostroncos.org/2010/01/25/generating-an-atom-feed-from-an-exchange-calendar/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

