Skip to main content


Showing posts from June, 2004

Reporting on Inbox Rules with OWA via Script

I've been looking at inbox rules lately and how you can manipulate them via script. Not a really easy thing currently, there is a rule.dll you can use with CDO to create rules but management and reporting are hard tasks. Firstly I wanted to just know how many people on my server where actually using inbox rules. I looked at doing a query of all the rule messages in the inbox but I found this wasn't too accurate a way of reporting on Inbox rules because you tended to pick up all the junk email rules and any other rules whether it was active or not and I really only wanted to know about user created server side inbox rules. I had a look at how OWA was doing it and this seemed to be something I could make use of, all it did was make one get /inbox/?cmd=rules and then this returned a list of all the active inbox rules. So all I needed to put together was a ADSI query of all the users on the Exchange box and put something that would parse the result returned from the OWA get and th

Recover Deleted Items from the Dumpster Programmatically

I started looking at this because I thought it would be a good way of finding any spam that was getting past my IMF filter that users weren't reporting. So I went of and hit the ESDK and CDO doco for any clues also did a Google crawl and didn't really turn up much except that CDO was not going to do the trick. The next step was to look at OWA and see if I could reuse any of the stuff it uses. After examining some of the conversations my browser was having with OWA I found that OWA was issuing a query with a scope of softdeleted eg "from scope ('SOFTDELETED traversal of ""') . I Googled this which turned up this Blog post from KC which started to fill in a few of the blanks. The next thing I tried to do was use a Softdeleted traversal in a Exoledb script which although it seemed to be a valid query it didn't work or more to the point the query worked but instead of returning a record set of soft deleted items I just got all normal folder items. I

Using Bcopy with WebDav in a script

There are a bunch of Batch commands in WebDav that allow you to perform multiple actions with one request this is explained here . I was looking at this today for another script I was writing and although the response and requests are documented in the Exchange SDK unfortunately no code examples exist. A wider search of the web didn't really show anything up either. Although its not extremely hard to use it did take me a little while to work out the correct way to use it so I thought I'd post it as I found it helpful. The script copies multiple items in one mailbox folder to another folder in the same mailbox with one XML request. sDestinationURL = "http://yourserver/exchange/yourmailbox/targetfolder/" Set XMLreq = CreateObject("Microsoft.xmlhttp") "BCOPY", "http://yourserver/exchange/yourmailbox/inbox/", False XMLreq.setRequestHeader "Destination", sDestinationURL xmlstr = "<?xml version=""

Feeding the simple Html Calendar with Exoledb

Man this was a lot harder then I expected it would be, When it comes to representing time in anything you are really starting to deal with a different dimension (I think time is the third dimension). Eg you can select all the records in a calendar with the startdate greater then the first of the month and a startdate less then the end of the month but this is going to miss all multi-day appointments. Also in my example say I wanted to know if there where any appointments that where on the 5th then just looking at the start date of an appointment wouldn't necessarily tell me this because I could have a multiday event that started on the 4th and finished on the 6th. The other problem i faced is i wanted to show all the days where there was some appointments scheduled as bold and clickable trying to do this you also run into the same problem where appointments span Multiple days (Also a lot of advanced aggregate functions aren't available in Exoledb). To solve this problem my

Simple Html Calendar VB script

One of the cool things that I like about blogging is the little calendar you see on left side of most blogs. They resemble a lot the calendars you see in Outlook and Outlook Web Access. I always thought they we some funky Activex control that you had to sell your first born to buy but they are actually really easy to create using a little bit of script and html. The hardest thing in this script was working out what week day the first day of the month is fortunately there are a couple of functions in VBS that help you out. This is a ASP sample that displays a small calendar The next step is to see if I can get it to use a Exoledb script as a source for the calendar. <table border="0" id="table1" cellpadding="2" width="147"> <tr><b><% response.write "<td style=""padding: 0"" width=""112"" align=""center"" colspan=""7"">

Finding Unused Mailboxes with CDO 1.2

A while ago I posted this script on OutlookExchange that uses Exoledb to find unused mailboxes on a Exchange 2000 server by looking at the unread mail count in the inbox for the last 50 days. Since then I've have a few questions for people wanting to know if they could do this also in Exchange 5.5 mainly to assist in migrations and cleanups. The answer is yes you can but not with Exoledb which is only available on Exchange 2000 and up, what you can use is CDO 1.2 to do something similar. Another good thing about using CDO 1.2 to do this is you can go a bit further then I did with the simple Exoledb sample by using some of CDO 's cool little built in methods. This is an example of a CDO script that will display the received time of the newest email in the inbox, the sent time of the last mail sent from this mailbox and the unread count for the last 50 days. It logs on to a mailbox using a dynamic profile you supply the alias name as a command line parameter and you need to

Public folder RSS Feed Event sink

I've gone a bit RSS mad of late for today's edition I created an Event sink for public folders so when a new mail or post arrives into that folder it will fire a script that updates a feed with the last 7 days of posts. I guess the cool thing here is you can stick this on all the important public folders in your org and then use one web page to aggregate across all the feeds and present this back to the user as one single web page. Also it lets people subscribe to folders and receive notification of updates etc. Sub ExStoreEvents_OnSave(pEventInfo, bstrURLItem, lFlags) on error resume next set DispEvtInfo = pEventInfo set ADODBRec = DispEvtInfo.EventRecord set objdom = CreateObject("MICROSOFT.XMLDOM") Set objField = objDom.createElement("rss") Set objattID = objDom.createAttribute("version") objattID.Text = "2.0" objField.setAttributeNode objattID objDom.appendChild objField Set objField1 = objDom.createElement("ch

RSS Feed for Outgoing Mail

Further to my post yesterday with the IMF Blocked mail RSS feed script which I found quite useful I decided to create a feed for all outgoing email. To do this I used tracking ID 1020 which gets logged when mail is transferred to another server and then did a filter using a if statement to see if the mail is coming from the sending domain. The changes I made are as follows Changed the Feed Title and Description Set objField3 = objDom.createElement("title") objfield3.text = "Outbound Mail Feed" Set objField5 = objDom.createElement("description") objfield5.text = "Outbound Mail Feed" Changed the time scope of the script from 1 day to 2 hours by changing the following line dtListFrom = DateAdd("h",-2,dtListFrom) Changed the Query to look for 1020 message ID's str = "Select * FROM Exchange_MessageTrackingEntry where entrytype = '1020' and OriginationTime > '" & strStartDateTime &

Exchange Message Tracking Logs Rss Feed Script

To do Message Tracking Log Reporting I wrote a little application using a Access database and some ASP pages which I posted up on OutlookExchange a while ago. This works pretty well but when it comes to constant monitoring of a mailbox it can be a little bit of a pain to keep logging on and checking. RSS offers a real alternative for this type of functionality, it can give users the ability to be able to subscribe to a feed of new items going into a common mailbox. To create a rss feed its just a simple manner of creating a xml file that is formatted in the expected RSS format which can be found here . As a first go at this what I did was take the my spam reporting script for this post and instead of creating a Html table as Ive done in this previous script what I do instead is produce a RSS feed file of all the SPAM that has been deleted via the IMF. Then all you need to do is publish this xml file on a web server and then subscribe to the feed in your aggregator of choice.

Setting OOF status and Text using a OWA Script

I created this blog entry a couple of days ago about using the Microsoft.XMLHTTP to do some automation scripting with exchange in regards to adding entries into the junk email whit lists. This same method can also be used to set a variety of other settings as well, one of these is a user OOF ( Out of office ) setting. You can also set this via a script using CDO 1.2 and also via Exoledb/WebDAV but this does offer a simple alternative. To set the OOF setting of a user you just issue the following commands Cmd=options OofReply=Im Out of the Office OofState=1 An example of using this in a script would be szXml = "" szXml = szXml & "Cmd=options" & vbLf szXml = szXml & "OofReply=Im Out of the Office" & vbLf szXml = szXml & "OofState=1" & vbLf Set oXmlHttp = CreateObject("Microsoft.XMLHTTP") oXmlHttp.Open "POST", "http://youserver/exchange/youruser/", False, "", "&

Post IMF Archiving Event Sink

Once the IMF has achieved a message this is pretty final in regards to the delivery of this message, but it doesn't have to be so what you can do is create a WMI consumer on the archive directory so every time a message gets archived it will then trigger an event.  After this you can then open the new mail that was just archived using CDO have a look at who it was going to or do further inspection on the content and if you think that this message should have been delivered move it back into the pickup directory and have it delivered. The logic and things you can do with this is up to your own imagination one simple example is if you have an account that you want to allow all mail though no matter what this script will check the x-receiver field if the mail is going to that user it will then move the email into the pickup directory. You can set this up as a permanent consumer using a Mof file or my preference is to use Srvany and create a service that this script runs as. strCompu

Importing Entries into Safe Senders, Safe Recipients and Blocked Senders via Script

Outlook 2003 and OWA (Exchange 2003) have the ability to create and maintain White/Black lists that work in conjunction with the IMF to filter Spam.Now that I'm using the IMF to do my spam management theses personal white lists have come up as an issue. Sometimes its necessary to globally white list an address or domain for all users or upload a number of entries into one users whitelist or ensure that as new mailboxes get created any necessary white-list entries get created for users. So a script or programmatic way to do this becomes a bit of a necessity. From a server perspective the lists are all stored in a binary property on a message in the users inbox (junk E-mail rule), so you can use Exoledb and Webdav to get at this property but because its just a binary blob of data decoding and/or adding to it from a script would be quite hard (not that I didn't try). One solution that I found that works is to re-use some OWA commands in a script using the XML parser (Microsoft

Copying RTF messages from Mailboxes to Public Folders

Copying messages from a mailbox to a public folder programmatically has never been a really easy task in Exchange, copying within one mailbox is okay you can use the basic ADO copy record and move record but between mailboxes or mailbox to public folder you start to hit some issues. One method that I found that works is to use the message stream object, this gets you a serialized version of the message that is easier to deal with. The problem with this method is that if the mail has any Rich Text formatting (or any other custom MAPI properties) then these properties don't get copied with the stream (what usually happens is the email just gets set to HTML). To solve this problem you need to look at which MAPI properties you need to copy over and copy these manually in your code. For example my problem was that i needed to copy the RTF formatting of a message over when I copied an item between a mailbox and the public folder. Using MDBvu32 to examine a message I found the MAPI pr

IMF message tracking ID's and Spam Report script

If you have Message Tracking Logging enabled on your server then Exchange records details about the message transfer process into the message tracking logs which can then be searched via Exchange System Manager - Message Tracking Center. A full list of Tacking ID and descriptions for Exchange 2003 can be found in the Exchange FAQ . With the release of the IMF there are now some new Tracking ID's that get logged when the IMF takes action on a message at the gateway level. The ID's look like this 1039 SMTP:Message Deleted by Intelligent Message Filtering 1040 SMTP:Message Rejected by Intelligent Message Filtering 1041 SMTP:Messgae Archived by Intelligent Message Filtering Depending on how you have your Gateway actions set you will get 1 or 2 of theses events logged when a gateway action is performed , Eg if you have your gateway action set to archive you get a 1041 logged and then a 1039 logged. Apart from System Manager the Message tracking logs can be accessed via WMI
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.