Tuesday, June 29, 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 this is the result. To do this im reusing some OWA commands and the (Microsoft.XMLHTTP) Object i described this method is this blog entry

set rootDSE = GetObject("LDAP://rootDSE")
defaultNamingContext = rootDSE.Get("defaultNamingContext")
Set objSysInfo = CreateObject("ADSystemInfo")

GALQueryFilter = "(&(&(& (mailnickname=*) (| (&objectCategory=person)(objectClass=user)(|(homeMDB=*)(msExchHomeServerName=*)))
strQuery = "<LDAP://" & objSysinfo.domaindnsname & "/" & defaultNamingContext & ">;" & GALQueryFilter & ";samaccountname;subtree"

Set oConn = CreateObject("ADODB.Connection") 'Create an ADO Connection
oConn.Provider = "ADsDSOOBJECT" ' ADSI OLE-DB provider
oConn.Open "ADs Provider"

Set oComm = CreateObject("ADODB.Command") ' Create an ADO Command
oComm.ActiveConnection = oConn
oComm.Properties("Page Size") = 1000
oComm.CommandText = strQuery
oComm.Properties("Sort on") = "givenname"

Set rs = oComm.Execute
while not rs.eof
cmdexe = rs.fields("Samaccountname")

function getrules(mname)
on error resume next
Set oXmlHttp = CreateObject("Microsoft.XMLHTTP")
oXmlHttp.Open "get", "http://mgnms01/exchange/" & mname & "/inbox/?cmd=rules",False, "", ""
oXmlHttp.setRequestHeader "Accept-Language:", "en-us"
oXmlHttp.setRequestHeader "Content-type:", "application/x-www-UTF8-encoded"
oXmlHttp.setRequestHeader "Content-Length:", Len(szXml)
oXmlHttp.Send szXml
slen = instr(oXmlHttp.responseText,"<TABLE id=""tblRules""")
elen = instr(slen,oXmlHttp.responseText,"</TABLE>")
pstring = mid(oXmlHttp.responseText,slen,elen-slen)
slen1 = 1
rules = "no"
rcount = 0
do until stopit = 1
if instr(slen1,pstring,"nowrap") then
slen1 = instr(slen1,pstring,"nowrap")+13
elen1 = instr(slen1,pstring,"</TD>")
rnames = rnames & "," & mid(pstring,slen1,elen1-slen1)
slen1 = elen1
rules = "yes"
rcount = rcount + 1
stopit = 1
end if
wscript.echo mname & "," & rules & "," & rcount & rnames

end function


Imel Rautenbach said...

Hi Glen, I am looking for a script that can show mailbox usage & count for all users in the Message store.

Do you happen to have some code handy?
None of the examples I have found so far works for me.


Glen said...

What version of Exchange do you need it for in Exchange 2003 you can do this pretty easily using WMI something like (watch the cut and paste its awfull)

On Error Resume Next
Dim cComputerName
Const cWMINameSpace = "root/MicrosoftExchangeV2"
Const cWMIInstance = "Exchange_Mailbox"
cComputerName = "."
Dim strWinMgmts ' Connection string for WMI
Dim objWMIExchange ' Exchange Namespace WMI object
Dim listExchange_Mailboxs ' ExchangeLogons collection
Dim objExchange_Mailbox ' A single ExchangeLogon WMI object
strWinMgmts = "winmgmts:{impersonationLevel=impersonate}!//" & cComputerName&"/" & cWMINameSpace
Set objWMIExchange = GetObject(strWinMgmts)
Set listExchange_MailboxSizes = objWMIExchange.ExecQuery("Select * FROM Exchange_Mailbox",,48)
For each objExchange_MailboxSize in listExchange_MailboxSizes
wscript.echo objExchange_MailboxSize.MailboxDisplayName
wscript.echo objExchange_MailboxSize.TotalItems
wscript.echo objExchange_MailboxSize.size

Otherwise have a look at


or my other article



Anonymous said...

Hi Glen,

Interestin articles you have! -A lot of stuff for beginners like me!

Well, I am trying to create a tool to list Inbox Rules. I tried your script, but can not list all the mailboxes using OWA (Probably a security issue).

So my question is: Is there a property for some class that can show this (So I can use a VB-script). There is a description in http://support.microsoft.com/kb/200162 using c++. But it is impossible to open Information Store: -It returns "unknown error"
We are using Exchange 2003.

Regards Asle Skage

Glen said...

You what to look at using rule.dll and cdo 1.2 which allows reading that table. If you google rule.dll you should find a few good samples and information.

Anonymous said...

Hi Glen,
Thank you for your last answer.
I found a number of examples (also posted by you!).
I think the most of my job is done. But every time I get this message:
Collaboration Data Objects: The attempt to log on to the Microsoft Exchange Server computer has fai
led. [Microsoft Exchange Server Information Store - [MAPI_E_FAILONEPROVIDER(8004011D)]]
after executing this code within a script:
Sub procmailboxes(servername,mailboxname)

set objSession = CreateObject("MAPI.Session")

wscript.echo "Mailbox: " & mailboxname

objSession.Logon "","",false,true,true,true,servername & vbLF & mailboxname

Set objInfoStores = objSession.InfoStores

set objInfoStore = objSession.GetInfoStore
set Inbox = objSession.Inbox

The error occurs on every mailbox I am trying.

There is a lot of information about this error, but not a single clue that can help me.
I am running this script from an administrator user.

Do you have any suggestions??

Thank you.

Asle Skage

Glen said...

How are you trying to run the code eg are you running from a normal script or from a ASP page ?. That error can mean a number for different things


Anonymous said...

A number of things, -yes I understood that from what I foun.
This script is run from a command line script with .VBS extention..


Glen said...

The first place to start is with Permission by default a user with administrative rights will be denied access to every other mailbox other then there own. see http://www.petri.co.il/grant_full_mailbox_rights_on_exchange_2000_2003.htm

Anonymous said...

Hi - this seemed to fullfill my needs. Unfortunately I get an error on execution (line 18: Provider: One or more errors occurred during processing ogf command.) - what is needed to run these commands? I'm running it directly on an exchange 2003-box, where I want to report the use of forwarding rules.

Glen said...

A better method of reporting on rules is to use Mapi I've been talking about this script with someone else over the past weeks and i've got an updated version because there was some problems with that original version in that it just read the hidden rule object in folder associated contents and not the Mapi rules table itself. It was also a very crude parser then seemed to error on different objects. To fix this i came up with a version that used redemption instead you can get a copy from http://www.dimastr.com/redemption/download.htm the advantage of this is this actually can read the Rules table in a mailbox so there's no need for the unreliable parser. Unfortunately for this particular guy and i've had a few other people report this sometime is that this would work but after about 32 mailboxes the script would stop because of the Open Mapi Session limit. I couldn't reproduce this and the code looked good in that it should have released the Mapi session when logoff method was called. To work around this problem i created a two script method the premise being that all the mapi code was in one script and the mapi session would get destroyed when the script finished running. I got a mail this morning from this guy and he said it worked okay. I've posted this two script example on http://msgdev.mvps.org/rdombxrules.zip if your interested in the one script its still their as well http://msgdev.mvps.org/rdombxrulesold.zip.


Thomas said...

Hi Glen . thanks for quick answer. Unfortunately the new scripts seems not to work. Tryed it on one server with only a few mailboxes with positive rules for forwarding to the internet. Resulting csv is empty. Have installed Redemption offcourse. Something else to be done? No errors, but no results either. Regards Thomas

Glen said...

Firstly its important that you have full rights to the mailbox in question. The first script does a ADSI query for all mailboxes on a server so you would need to make sure when you run the script you pass the servername of the server you want to run it against eg

cscript rdombxrules1.vbs yourservername

Make sure you use the netbios name not the FQDN.

If you want to test the second script against just one mailbox you can do this also using something like

cscript rdombxrules2.vbs mailbox yourservername


Andrew Matthews said...

Glen - you have produced a great script and a lof of Exchange Admins should run this regularly to ensure un-authorised messages aren't leaving their organisations.

Many thanks

VAOR said...

Hi Glen,

Would this work on Exchange 2007? If not, do you have a script that would allow me to list the Inbox Rules on users mailboxes remotely (or from the exchange server)?



Glen said...

No it wont work on 2007 have a read of the other comments re using Mapi to do this.


Johny said...

Could this, or the mapi method mentioned in the previous comments, be used to get ALL rules (includng client-only) from a users Exchange 2007 mailbox? We have successfully used the mapi/redemption approach to gather forwarding rules, but we have been unable to gather client-only rules to see if they are fowarding, or whatever other action they are completing. I have been able to change a few things in the script to retrieve client-only rules, but i can only retrieve the conditions.. not the actions.

Unknown said...

hey Johny, did you find a way to do this? If so, would you mind sharing. If not, can you share what you have so using the mapi/redemption approach