Skip to main content


Showing posts from 2004

Showing how much whitepace is in your database via script

Continuing on from some of my last weeks entries, When the Information Store maintenance process runs it logs to the windows eventlogs the results of its retention and de-fragmentation operations. More importantly it tells you how much space is held in deleted item retention (and how much it just released). How much space is held in deleted mailbox retention and how much it just released. And finally how much free-space there is in the database after the online de-fragmentation has just run. So what this script does is query AD for all the mail and public folder stores in your domain. Then it querys each servers event log for 3 specific events that contain the details of the 3 maintenance operations and then parses the result out of that text and displays the result at the commandline. Event “1221” is logged after an online de-fragmentation is run on a mailbox or public folder store. Event “1027” is logged after the deleted item retention cleanup is done and the result of starting and

Finding when a Exchange Store last backed up via script

There are a couple of ways you can determine when the last time a particular exchange store was backed up if you're using a program that backs up via the Exchange Backup API (Veritas,Brightstore etc). With Exchange 2003 a new function was added into System Manager to allow you to see the "Time of Last Full Backup" on the database tab. This property is also available in CDOEXM (if you have the 2003 version of system manager loaded on the machine). The ".LastFullBackupTime" property was added to the IMailStoreDB and IPublicStoreDB interfaces. Using this is pretty easy all you have to do is to open the mailstore using the LDAP DN path and access the property eg set mdbobj = createobject("CDOEXM.MailboxStoreDB") "LDAP://mbdDNpath" Wscript.echo "Last Backed Up : " & mdbobj.LastFullBackupTime I've put this together with a similar query from my previous post and this script selects all the exchange stores in

Listing the file sizes of all Exchange Stores on all Exchange Servers in a Domain V2

[updated fixed new bug when there's more then one mailbox store on a server] I've had a bit of feedback about the first version of the script that i posted here so I decided to give it a quick revise and add some additional functionality. The additional functionality added to this script is that instead of just returning the size of each store file it also now returns the freespaces left of the disk where the file is located and the percentage of the diskspace that is free. Also there are some fixes for it to allow the script to work when there are more then 1000 mailboxes. I've posted a copy of the new code up here set conn = createobject("ADODB.Connection") set com = createobject("ADODB.Command") Set iAdRootDSE = GetObject("LDAP://RootDSE") strNameingContext = iAdRootDSE.Get("configurationNamingContext") rangeStep = 999 lowRange = 0 highRange = lowRange + rangeStep Conn.Provider = "ADsDSOObject" Conn.Open "ADs Provi

Setting Outlook 2003 Junk Email Options Programmatically

[If you are trying to do this using Exchange 2007 please see ] The Outlook 2003 Junk email filter has a number of different options that can be configured through (tools-options) that determine how the filter will treat email it detects as spam in your inbox. The configuration settings are stored on a hidden extendedrule message in a user’s inbox. The options settings are held in two MAPI properties on this hidden message the first one being which stores a long value that sets that level of junk email protection you want the long values for each of the setting are No Automatic filtering = -1 Low = 6 High = 3 Safe Lists only = -2147483648 The “Permanently delete suspected junk e-mail instead of moving it to the Junk E-mail folder” is stored in the as Disabled = 0 Enabled = 1 On a new mailbox or a mailbox where

Setting the Appointment Label Text Programmatically

Last week I blogged this Appointment label Colour Changing Event Sink and I mentioned that the appointment label text is located in the property in an undocumented binary form. Well I had a crack at working out what that format is this week and I've come up with the following sample. Before I start though I must give the following warning, the following piece of code and method is completely unsupported and completely untested. Playing around with binary properties is very unwise unless you really have a good enough grasp to be able to undo any damage you may do trying to set them. The third and last bit is that this will only work if your using the ASCII character set. If you're using other types of character sets (eg a lot of Asian character sets) this wont work. Because this property is stored in a binary format to work with this in VBS we need something that can read binary and convert it to a hex string which makes it u

Appointment label Colour Changing Event Sink

[2/2/2005 updated this post and script to use named property instead the custom Mapi prop] One of the cool features that was implemented in Outlook 2002 was the ability to change the colour of appointment labels to help distinguish between different types of appointments. (see for a good description of this feature). But because of the laziness factor I find that I rarely use this feature because I usually forget to set it. One of the things that I really wanted this to do also was be able to show me at a glace which meetings in my calendar where internal meeting (only contained internal attendees) and which meeting contained external attendees (this can be usefull in the morning). Putting this into an event sink turned out to be a really easy solution. All I needed was some code that would go though the attendees collection of a appointment object when the appointment was created and check each of the address's of the attendees to s

Deleting old email with a Exoledb Script

This question pops up now and again from people who want to be able to scheduled a script that will delete mail in a folder that was received more then say 30 days ago. Typically this could be used on a postmaster mailbox (hopefully people are reading these mails before they get deleted) or on a mailbox that is doing auto replies when you want to keep the original emails for a period of time. Going about this is quite simple in Exoeldb all you really need to do is query on the desired folder for all the mail where the urn:schemas:httpmail:datereceived is older then 30 days. Once you have all these mails in a record set you can loop though the recordset and delete the email. The thing to remember when you are deleting mail this way is that the deleted mail goes into the dumpster of whatever folder you are deleting them from mailboxurl = "file://./backofficestorage/yourdomain/MBX/mailbox/inbox" set Rec = CreateObject("ADODB.Record") set Rs = CreateObject("ADODB.R

Finding what Resources are being used from a Meeting Request

I've blogged about resources in meetings before but this question came up last week about how do you tell which resources have been booked from a calendar request message(meeting invitation). When someone creates a meeting the resources that are booked (or attempting to be booked) with the meeting get stored in the BCC field of the appointment object. In the calendar request messages (invitations) that go out to the users (and resource mailboxes if your using some sort of auto accept system) the resources aren't included in the calendar request message (not even in the recipients collection even when the resource mailbox is receiving the calendar request). If you use Outlook to do the booking it does copy the resources display name into the location property but with OWA the location field is left blank unless the user specifically enters something . So from a calendar request message you received from a meeting organized by OWA how could you tell which resources where being bo

Last 5 received/Sent Emails IPAQ pocket IE page/script

I been playing around with some WebDAV code with Pocket IE (on a IPAQ)to display a screen that shows me the last 5 emails I received and the last 5 I sent. Because my IPAQ sits on my desk most of the day doing nothing I found this pretty handy as it alloys me to see at a glance which bit of email I need to take action on and what I've replied to recently. Geting the code to work inside of pocket IE was a little bit of a challendge had to switch to using Jscript and I found out that a few things that worked fine in the desktop version of IE don't work the way you really want them to (or at all) in the pocket version of IE but I did manage to come up with the following piece of working code. Basically what it does is performs two separate WebDAV queries the first one of the Inbox and then the Sent Items folder. I used the Range header to limit the result set of the queries to 5 rows. The Range header is pretty cool it kind of a sudo SQL TOP statement. I've added some simple H

Listing the file sizes of all Exchange Stores on all Exchange Servers in a Domain

One of the things that I've found missing from the Exchange Management GUI's has been the ability to get the physical size of the database files (especially when you have multiple servers to manage). None of the Exchange API's accessible with script offer this type of information either. I've found two methods you can use to grab this information via a script, the first is when the information store performs a backup via the Exchange Backup API one of the events it logs is event code 220 which states the size of each file before it is backed up. The other method is to connect to the file using the FSO object in VBS and grab the size of the file directly. I've expanded this second method into a script that first queries for all the msExchPrivateMDB and msExchPulicMDB objects in Active Directory using ADSI. Then using the msExchEDBFile, msExchSLVFile and msExchOwningServer AD properties constructs the URL to be able to connect to each file remotely and report on th

Getting Meeting Attendee status and roles through WebDAV

When you send out meeting or appointment invites to people and they are accepted or denied by users the status of there acceptance (and their role in the Meeting) is stored in the recipients collection of the appointment object. In CDOEX you have a few interfaces that allow you to interrogate and retrieve this information via the IAppointment and IAttendee interfaces. EG set apptobj = createobject("CDO.Appointment") "file://./backofficestorage/" for each attend in apptobj.Attendees wscript.echo attend.address wscript.echo attend.role wscript.echo attend.status next In WebDAV access to the recipients collection of a message is very limited and usually all you can retrieve is the email address and or displayname of each attendee. A while ago I blogged this about a method of accessing a meeting resource's email address by using the vCalendar body part of an appointment. The attendee statu

Scripting Contact folder Distribution List though OWA

Contact folder distribution lists presents some what of a challenge when it comes to scripting and programmatic access. The members in these lists are held in a couple of binary MAPI properties and there are no direct interfaces to modify these lists using CDOEX. Modifing the properties directly using Exoledb or WebDAV is possible in some cases just not very easy or flexible. Fortunately OWA does provide a method to create and modify these contact distribution lists which can easily be used in a automation script. Creating a DL, This is the one thing that you can do easily using CDOEX,ADO or WEBDAV but one extra thing you can do with OWA is create a DL and add a member to it at the same time. The one restriction I found for this is you can only add one member at a time per request. The following script creates a new DL in a public folder using the save cmd. You need to put the name of your new DL in Set ObjxmlHttp = CreateObject("

Copying Contacts from One Mailbox to Another via Script

I had this request from one of my customers recently who wanted me to copy all the contacts from one mailbox into another. The easiest way to do this would have been to use outlook to export the contacts folder to a pst and then just import them back into the other mailbox using Outlook. Because i manage this client remotely and there's no Outlook on the Exchange server itself (and i really didn't feel like talking the users though this) I came up with the following Exoledb/CDOEX script to do the copy. The challenge when copying anything between mailbox's or public folders is you cant do a direct copy (eg ADO copyrecord only works within a mailbox or public store) so you have to use another solution. What this script does is first does a query to get all the URL's of contacts in the mailbox's contact folder. Then it opens up each contact using the CDO.Person interface and then access's the vcard stream on each contact object . The script then copies this vcard s

Simple HTML calendar feed from Users Free/Busy data

A while ago I posted this about creating a simple html calendar like the ones you see in OWA. I was looking though some OWA captures today and noticed the following command is called when you manipulate the calender object in OWA. ?Cmd=monthfreebusy&start=2004-07-25T00:00:00+10:00&end=2004-09-05T00:00:00+10:00 (the +10:00 at the end I believe refers to the time zone offset which you need to adjust to your own timezone or put some code in that does it) What this does is return a single string of numbers with each day in-between the &start and &end variables represented by a 0 if there are no appointments that day, a 1 if there is and a 2 is no freebusy data has been published. I took this function and combined it with some WebDAV in a ASP page and was able to feed the simple html calendar and make it bold all the dates in the calendar that there where appointments on, I also created a few functions so you could change months back and forth. The limitations of this metho

Public folder RSS Feed Event sink v2

From the feedback I've received about the first public folder RSS feed sink I've come up with another version that incorporates many bug fixes and add's in some additional functionality. The main functionality change and bug fix revolves around the publishing of the content of each public folder message. In the original sink I was using the Textdescription field which represented the text body of the email. The problem with this is that firstly the carriage returns weren't interpreted right in the XML file so if you had a long message it just appeared all stuck together with no formatting. To fix this there where two options the first was to continue using the textdescription field and then just replace any ASCII 13 characters (Line breaks in a email) with html line break characters eg replace(Rs.fields("urn:schemas:httpmail:textdescription"),chr(13),"<br/>") The second option and the one I've gone for is to use the urn:schemas:httpmail:htm

Processing Meeting requests remotely with WebDAV and OWA

This was something interesting I learned this week. If you want to process meeting requests remotely the same way you can locally with CDOEX then using a combination of WebDAV and some OWA commands can make this happen. Process the request Basically when someone invites you to a meeting you will get sent a calendar message that contains all the invitation information. You can differentiate this from a normal message by looking at the DAV:Contentclass and seeing if its set to urn:content-classes:calendarmessage. Now if you want to scan a inbox for any of these messages you could do a WebDAV search against that mailbox for any messages that have this particular content class and also who’s outlookmessage class was set to IPM.Schedule.Meeting.Request which delineates this as a meeting request. Eg server = "servername" mailbox = "mailbox" strURL = "http://" & server & "/exchange/" & mailbox & "/inbox/" strQuery = " &quo

Creating a new folder in a mailbox if one doesn't exist

I've had this question from a few people that wanted to do this in a event sink, its acually really simple to do with a little bit of ADO/Exoledb code. To create a folder in a mailbox using ADO you can use the adCreateCollection option in your record open statement. The following two lines would create a folder in a mailbox. set rec = createobject("ADODB.Record") "file://./backofficestorage/", ,3,8192 The options included in the open statement are 3 which is adreadwrite and 8192 which is adCreateCollection (hex 0x2000) If you try this code and the folder already exists you will get an error returned stating that the object already exists. So if you want to run the above code to create the folder only if the folder doesn't exist and not return an error if it does all you need to do is combine adCreateCollection with adOpenIfExists. eg set rec = createobject("ADODB.Record") "fil

vCalendar with CDO and Script

I’ve been playing with vCalendar and iCalendar with Exchange to solve a few problems and I found it was pretty interesting so I decided to write about a few things I’ve learned. Background Some good background information on vCalendar can be found here vCalendar and Outlook (good general background on what it is) IMC Product Development Information (This is the best site for vCalendar info and contains documentation of the current implementation) IMC ietf-calendar page (Good read on iCalendar) And last but not least this from the exchange SDK Basically with Exchange each appointment in your calendar has a vCalendar formatted body part. Putting it to use. There are plenty of things you can do with vCalendar formated files the most obvious is to use them to import and export calendar appointments where other methods can’t be used. A simple CDO/ADO script that would go though and export all the appointments in a calendar for the past year (past and future
All sample scripts and source code is provided by for illustrative purposes only. All examples are untested in different environments and therefore, I cannot guarantee or imply reliability, serviceability, or function of these programs.

All code contained herein is provided to you "AS IS" without any warranties of any kind. The implied warranties of non-infringement, merchantability and fitness for a particular purpose are expressly disclaimed.