My HTML Calendar Generating Script for Exchange 2003

In my office, we have over 60 different resources that can be booked online. These resources (including conference rooms, laptops and LCD projectors) can all be scheduled via Outlook and Microsoft Exchange, using Microsoft's latest Auto-Accept Agent. The main draw back is that you can't really tell who has what room for how long. With the previous version of Exchange (5.5) there where issues with users having permissions to the calendars. Outlook would corrupt the conference room calendar and cause the free/busy information to become corrupted.
I developed this script to query the resource calendars and not conflict with the free/busy info. This latest version uses WebDAV to query the calendar (similar to if the user is accessing via OWA!). I have scheduled the script to run every 15 minutes using a Windows Scheduled Task. To export a calendar with 270 items take around 5 seconds.
To configure the script:

  1. Create your conference room mailboxes and configure for the AAA to run
  2. Create a service account in your environment. It will need to have an Exchange Mailbox associated with it.
  3. Via Outlook, grant the service account "REVIEWER" permissions to the conference room calendar. (Right-click | Properties | Permissions | Add...)
  4. On your IIS server, create a new shared folder, and grant the Service Account - Full Control permissions to this folder.
  5. Download and extract the ZIP file below to a server in your environment.
    • (11/21/2005) I've just uploaded an update to the script. This version includes a settings file, which eliminates the code modifcation listed below. Extract this file to the same folder, and modify the corresponding SETTINGS.TXT file.

    Note: Try to avoid putting system variables (? * and \) in the Display Name field.

  6. Double-click on the VBS file and see if it successfully generates the HTML file in the UNC path. If not, verify permissions to the folder. Keep troubleshooting until the HTML file is successful generated.
  7. Now that you have an HTML file, modify the INDEX.HTML file to point to this new resource.
    We've broken our rooms into physical areas.
    Copy the code below for each area, then modify the
     
    a href=
    tags to point to each resource.

            Building A
    <ul id="Bldg A">
    <li><a href="TestResourceMailbox.HTML" target="main">Test mailbox</a>
    <li><a href="Home.HTML" target="main">Home Page</a>
            </ul>

    The JavaScript code will make it into a collapsible tree only showing resources they are looking for.
  8. On the server where you placed the VBS file, create a scheduled task to run the VBScript. This scheduled task should run at regular intervals. I've scheduled them to run, Daily starting at 6AM, repeating every 15 minutes, for 15 hours.
  9. Create a virtual web site, referring to the Index.HTML file, and advertise it to your employees.
  10. You can hide the service account mailbox until you need to add a new conference room to the web page.

That's it! Fairly easy to create and maintain. In a future release I plan to have the script update the local Application Event Logs. This would allow products like NetIQ to monitor the script. Currently a log file is written locally.
Let me know what you think. I won't provide any support for your environment, but can help troubleshoot via e-mail.
6-20-2006: Finally uploaded revision including modification for day-light savings. This version reads the Day light settings from the local server, calculates the difference from DLS and modifies the time accordingly. This has been tested on Exchange 2003 successfully in Pacfic Time Zone.

Revision 3.3: If you downloaded the script, check out my article on the changes to Daylight Savings calculation here in the US. It may cause problems with entries booked on your calendar.

AttachmentSize
WebCalendarHTML.zip10.38 KB
ConferenceRoomWebsite.zip7.93 KB
settings.txt831 bytes

Microsoft Auto-Accept Agent Accepts Anything!

Microsoft has an Auto-Accept Agent (or AAA) that can be used on Exchange 2003 servers to process incoming meeting requests to resource mailboxes. Simply send the resource an invitation and within 10-30 seconds, the room will respond back with an acceptance or denial of your request.

For the last 2 months we've been using this script to process the 61 various resources in the environment (conference rooms, laptops and LCD projectors). Combine that with my own home-brewed calendar export script, the company has a complete resource tool for virtually all items in the environment. Unfortunately over the last few weeks, we've had new issues.

Corrupted CDO Free/Busy Cache: First we had users reporting getting declined responses when the calendar shown free, and canceled meetings were still showing as busy. Why? My best results were pulled from a technical article (kb886760). Now, if you read this article VERY closely, pay attention to:

Hotfix installation information
After users apply this hotfix, they may have to wait until the end of the month before they stop experiencing the symptoms that are described in the ""Symptoms"" section. This is because the EXCDO component keeps free/busy information cached until the last day of the month. The free/busy cache is rebuilt on the first day of the month.

GREAT!! So end-users will need to wait until the end of the month to view the correct free/busy information on our resource calendars as the CDO free/busy cache is only completely rebuilt once a month. There has to be a better way...

After talking with Microsoft PS Support, I got this answer..

  1. Set the CalendarRecovery registry value to 1 on the Exchange 2003 computer. To do this, follow these steps:
    • Click Start, click Run, type regedit in the Open box, and then click OK.
    • Locate and then click the following registry subkey:
        HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\EXCDO\Parameters<br />
    • On the Edit menu, click Add Key, type EXCDO, and then press ENTER.
    • On the Edit menu, click Add Key, type Parameters, and then press ENTER.
    • On the Edit menu, point to New, click DWORD Value, type CalendarRecovery, and then press ENTER.
    • Double-click CalendarRecovery, type 1 in the Value data box, click Decimal, and then click OK.
    • Quit Registry Editor.
  2. Start Outlook on a client computer and log on by using the resource mailbox profile.
  3. Right-click the Calendar folder, and then click Properties.
  4. Click the General tab, type CleanupExpansionCachesInTheCalendarFolder in the Description box, and then click OK.

Notes

  • If the Description box already includes CleanupExpansionCachesInTheCalendarFolder, clear the Description box, click Apply, type CleanupExpansionCachesInTheCalendarFolder in the Description box, and then click OK.
  • After you complete steps 1 through 4, you may have to run Outlook with the /CleanFreeBusy command-line switch. This will update the free/busy information. To do this, click Start, click Run, type Outlook.exe /cleanfreebusy , and then click OK.

I needed to touch every mailbox, so it was (going to be) quite a tedious task of creating a profile and opening each mailbox. Luckily, I do have a script also for that.

Alright, that problem solved. On to the next one..

Faulty Replication: At the same time the free/busy information was not replicating, users were reporting other issues with the calendars. This fix was applied 891509.

Unplanned for behavior: OK, patched and meetings are processing. Now meetings are booking, and the calendars look really good. What do we find out? That the, wait, really, you won't believe it. Meeting requests booked on the calendar as FREE, are actually booked on the calendar as FREE. Hu? What? Users can successfully book the conference room, get an acceptance back from the room and still be booked over by other requesters who book the room as "tentative", "BUSY" or "Out of Office".

According to our Microsoft TAM, this functionality is by design.

A customer requested functionality to send a 'free' request to resources to get a accepted/denied response back, then the end-user would use other means to officially book the room.

So, now we are in the uncomfortable place of telling our users that the conference rooms will accept your meeting request marked "FREE" and very likely you will get booked over. (Don't change it to FREE later on either, it has the same effect.) I still wish we went with SWINC's product Exchange Resource Manager or ERM as it was fully configurable. it would have accepted those "FREE" requests and converted them to "BUSY" with a simple click of a check box.

So much for saving $$!

Saving More Daylight!!

Thanks to a recent change, Americans will soon be getting more daylight. Yes, we will start saving daylight approximately 3 weeks earlier this year. Previously, Daylight Savings started the first Sunday in April, now it will be the second Sunday in March!

What does that mean for IT? Nothing, and a bunch. First Outlook bases DST calculations on the local operating systems settings. So, if you book a meeting at 10AM PST after March 11th, 2007, it will actually be an hour off. Why? The calendar stores it stores it in Greenwhich Mean Time (GMT). (10AM + 8hrs for GMT = 6PM). When in actuallity (because it's after DST starts), that meeting should be on the calendar for 5PM GMT. In addition, all applications that use straight CDO will have issues (like my script and Blackberry servers).

Nicely, Microsoft has provideed a web page specifically addressing these issues. (see here)

To fix my HTML Generating Script, search for these two functions Function GetDSTStartDate(llevel) and Function GetDSTEndDate(llevel) and replace it with this code:

Function GetDSTEndDate(llevel)
' In the US, Daily Savings Ends at 2AM on the First Sunday in November.
'
This function is to determine the next date.
Dim DSTYear
Dim DSTDate
DSTYear = CStr(Year(Now))
DSTDate = dateadd("d",(8-weekday(cdate("11/1/"&DSTYear))),cdate("11/1/"&DSTYear & " 02:00:00"))
If now() > DSTDate then
        DSTYear = CStr(Year(DateAdd("yyyy",1,Now)))
        DSTDate = dateadd("d",(8-weekday(cdate("11/1/"&DSTYear))),cdate("11/1/"&DSTYear & " 02:00:00"))
End If
If llevel >0 Then GenLogFile "Daylight savings ends:" &DSTDate
GetDSTEndDate = DSTDate
End Function

Function GetDSTStartDate(llevel)
' In the US, Daily Savings starts at 2AM on the Second Sunday of March.
'
This function is to determine the next date.
Dim DSTYear
Dim DSTDate
DSTYear = CStr(Year(Now))
DSTDate = dateAdd("d",7,dateadd("d",(8-weekday(cdate("3/1/"&DSTYear))),cdate("3/1/"&DSTYear & " 02:00:00")))
If now() > DSTDate then
        DSTYear = CStr(Year(DateAdd("yyyy",1,Now)))
        DSTDate = dateAdd("d",7,dateadd("d",(8-weekday(cdate("3/1/"&DSTYear))),cdate("3/1/"&DSTYear & " 02:00:00")))
End if
If llevel >0 Then GenLogFile "Next Daylight savings is:" &DSTDate
GetDSTStartDate = DSTDate
End Function

Hopefully, we all get to enjoy a bit more of this saved up daylight by playing outside. I declare from this date forward that 3PM is beginning of recess. Now just need to decide what time zone that's in....