I’ve posted several IMF-related blog postings in the past — here, here, and here. In these posts, I’ve focused mainly on the gateway behavior of the IMF. This is because that’s really what the IMF is, of course… just the gateway behavior. But when your mailbox server is running Exchange 2003 or better, there’s a whole different angle to consider: Store behavior.
As I’d mentioned, through the IMF UI in ESM, you can set the Store Action Threshold. This sets a value in the AD that is read by the Information Store on Exchange 2003 (or newer) and controls the server-side Junk E-mail folder behavior. What this means is that if the mail makes it to the Store (ie – is not stopped by IMF at the gateway), it will have an SCL stamped on it. The Exchange 2003 Information Store will detect that there is an SCL value associated with the message. The store will then make a determination on whether or not the message SCL value means it needs to be moved into the mailbox’s Junk E-mail folder.
Important to note that this IMF/SCL related Store Action is totally separate from and unrelated to the Outlook client-side Junk E-mail evaluation. It’s a bit of a confusing interaction, but they really are separate. Even if you never log onto your mailbox with Outlook 2003 in cached mode and set the Junk E-mail options to be enabled, you can still have the Exchange Junk E-mail processing move messages to the Junk E-mail folder. There’s a bit more information on Outlook 2003 client-side Junk E-mail behavior in KB.842510.
Bonus: Outlook doesn’t use the IMF provided SCL values for its client-side (cached-mode only) anti-spam determination. Instead, it does its own Junk E-mail evaluation and determines whether or not to move the mail to the Junk E-mail folder based on the settings within the “Tools->Options” Junk E-mail settings.
Back to the StoreActionThreshold, much of the confusion I see in this area is around what has to be done to get the server-side Junk email processing to work. It’s important to understand that there is actually another requirement that has to be taken into account here. It’s not just the server realizing that the message processed by IMF has a particular SCL and moving it to the Junk E-mail folder… there actually has to be a special rule in place within each mailbox to make this move happen. The rule is made up of information about your junk email settings, safe senders, etc..
Now we’ve established that in order for the Store Action to work properly, you need to have both Exchange 2003 (or better) Information Store that knows to read the StoreActionThreshold value from the AD and ALSO a special rule set in the mailbox to tell the store how to process the Junk E-mail. That’s where most people run into trouble, and why sometimes it seems to work and sometimes it doesn’t. It’s all about how this special rule gets set (or doesn’t)!
So, in short, if you’re not having all of your users login to the server with Outlook 2003 in cached mode already, the rule probably isn’t already created and won’t be automatically created just because you implement IMF.
What to do? If you’re not using Outlook 2003 or if you only have a handful of users affected by this behavior, the best option is probably to go into the affected mailboxes (or have the end-user do it) with OWA2003 and set the Filter Junk E-mail checkbox. This will set the special rule in the mailbox, and Junk E-mail folder will begin to function.
But what if you have a BUNCH of mailboxes to set this on? Unfortunately, there’s no built-in way to bulk set this rule on each mailbox directly. But one of my Microsoft colleagues (Jerry Wang) put together a VBScript that will automate the process of spinning through the mailbox in OWA and setting up the special rule. This script was subsequently modified a bit by Xavier Coppin to make it work in more end-user cases. Some credit also belongs with Glen who posted some of these details back in December: http://gsexdev.blogspot.com/2004/12/setting-outlook-2003-junk-email.html. This script might be useful if you’ve a need to set this on a large number of mailboxes. This script comes with no warranty, etc and please review it before you use it, and of course you use it at your own risk!
You feed this script a file containing a list of mailboxes (alias or SMTP address), one per line. If you can’t connect to the mailbox OWA with /exchange//">http://<servername>/exchange/<line-from-the-input-file>/ it won’t work, so construct the input file accordingly and change the strURL value in the script if you need to adjust the URL. The script will prompt for the server, username, password, etc if you don’t provide them according to the usage: cscript JunkEnable.vbs servername domain\user <file name> [Password]
SCRIPT UPDATED Feb 8, 2005
'=======================================================================' Microsoft provides programming examples for illustration only, ' without warranty either expressed or implied, including, but ' not limited to, the implied warranties of merchantability ' and/or fitness for a particular purpose. This article assumes ' that you are familiar with the programming language being ' demonstrated and the tools used to create and debug procedures. ' Microsoft support professionals can help explain the functionality ' of a particular procedure, but they will not modify these examples ' to provide added functionality or construct procedures to meet your ' specific needs. If you have limited programming experience, you may ' want to contact a Microsoft Certified Partner or the Microsoft fee-based ' consulting line at (800) 936-5200. For more information about Microsoft ' Certified Partners, please visit the following Microsoft Web site: ' http://www.microsoft.com/partner/referral/ '=======================================================================
'==========================================================================' VBScript Source File '' NAME: JunkEnable.vbs'' AUTHOR: Xavier Coppin (http://xavblog.net/)' DATE : 8/Feb/2005'' COMMENTS: ' Enable Junk Email filter at mailbox level'==========================================================================
Option Explicit'==========================================Dim ServerName, AdminUserName, Password, oArgs, ArgNumber, TextFileNameSet oArgs = Wscript.ArgumentsArgNumber=CInt(oArgs.Count)If ArgNumber > 0 Then If oArgs(0)="/?" Or oArgs(0)="?" Then Usage() End IfEnd If'WScript.echo "oArgs.count=" & oArgs.countIf ArgNumber < 1 Then ServerName=InputBox("Can you please enter the Exchange Back-End server name ?","ServerName","ServerName")Else ServerName=oArgs(0)End IfIf ArgNumber < 2 Then AdminUserName=InputBox("Can you please enter an Exchange Administrator account name ?","AdminUserName","DOMAIN\USERNAME")Else AdminUserName=oArgs(1)End IfIf ArgNumber < 3 Then TextFileName=InputBox("Can you please enter the name of the plain text file ?","Text File Name")Else TextFileName=oArgs(2)End IfIf ArgNumber < 4 Then Password=InputBox("Can you please enter the Password of " & AdminUserName,"Password")Else Password=oArgs(3)End IfDim oFileObject, oLogDim strLine,strURLSet oFileObject = CreateObject("Scripting.FileSystemObject")Set oLog = oFileObject.OpenTextFile(TextFileName,1)Do Until oLog.AtEndOfStream strLine = oLog.ReadLine strLine = Trim(strLine) strURL = "HTTP://" & ServerName & "/Exchange/" & strLine ForceJunkEmailFolder strURL, AdminUserName, PasswordLoopoLog.CloseSet oLog = NothingSet oFileObject = Nothing
'==========================================' Print the usage'==========================================Public Sub Usage() WScript.Echo "Usage:" WScript.Echo "Enable Filter Junk Email at mailbox level ." WScript.Echo " cscript JunkEnable.vbs servername domain\user <file name> [Password]" WScript.Quit 0 End Sub
'=========================================='Logon to specified mailbox by OWA'==========================================Public Sub ForceJunkEmailFolder(strURL,strUserName,strPassword)On Error Resume NextDim XmlHttpStr, ObjXmlHttpSet ObjXmlHttp = CreateObject("Microsoft.XMLHTTP")XmlHttpStr = ""xmlHttpStr = xmlHttpStr & "Cmd=options" & vbLfxmlHttpStr = xmlHttpStr & "junkemailstate=1" & vbLfXmlHttpStr = XmlHttpStr & "cmd=savejunkemailrule" & vbLfObjXmlHttp.Open "POST", strURL,false,strUserName,strPasswordObjXmlHttp.SetRequestHeader "Accept-Language","en-us"ObjXmlHttp.SetRequestHeader "Cache-Control","no-cache"ObjxmlHttp.setRequestHeader "Content-type:","application/x-www-UTF8-encoded"ObjxmlHttp.setRequestHeader "Content-Length:", Len(XmlHttpStr)ObjXmlHttp.SetRequestHeader "Accept", "*.*"ObjXmlHttp.Send XmlHttpStrIf Err <> 0 Then WScript.Echo "Filter Junk Email failed at " & strURL & " Failed!" WScript.Echo "Error number" & Err.Number WScript.Echo "Description : " & Err.Description Exit SubEnd If If ObjXmlHttp.Status <> 200 Then Wscript.Echo "Filter Junk Email failed at " & strURL & " Failed!" WScript.Echo "Http status code =" & ObjXmlHttp.statusElseif ObjXmlHttp.responsetext <> "" Then WScript.Echo "It seems an error occured during the Send Command. Are you sure you have the correct permissions on this mailbox ?" WScript.Echo "Response of the server was " & ObjXmlHttp.responsetext Else WScript.Echo "Filter Junk Email enabled for mailbox " & strURL End If
Set ObjXmlHttpStr = nothingEnd Sub