How to REALLY monitor SMTP, POP3 and IMAP on Exchange 2003

Even though Microsoft Exchange Server 2010 has already been released, many organizations still use Exchange 2003. In this article I’ll explain how to thoroughly monitor the various Internet protocols that Exchange 2003 offers, including SMTP, POP3, IMAP (and NNTP for that matter). The reason why I’ll only be looking at Exchange 2003 is because there is a significant difference in architecture between Exchange 2003 and later versions.

It is a common misconception that you can effectively monitor the W3SVC service (commonly referred to as IIS, though IIS encompasses a lot more than just a web server) and other services provided through IIS, such as SMTP and POP3, by simply monitoring their associated service. It’s a misconception, because a given IIS-based service may contain multiple instances – most commonly the case with the World Wide Web Service which often hosts multiple independent web sites. The status of these instances can be controlled independently of the hosting service, though that service needs to be running of course.

Don’t despair though, most server-based windows applications, fortunately, can be monitored by ensuring that their respective service is – well – running. For example, to ensure that the Apache service is up, you “simply” make sure that the Apache service is running. The same goes for countless other services such as MySQL – even SQL Server (of course you can still detach individual databases in SQL Server).

Exchange 2003, due its partnership with the Internet Information Services 6.0, is different though. Yes, IIS and Exchange 2003 are tightly coupled, and if you intend to have your Exchange Server 2003 communicate with any other server using a standard Internet protocol such as SMTP, then you will need IIS.


The screenshot above shows that the inetinfo.exe process hosts all the major services (bold name), and that each service can host one or more instance. For more details please see

The three most common Internet services your Exchange 2003 server is running are probably SMTP, POP3 and IMAP4. While a lot of attention is being paid to the core Exchange services such as

• Microsoft Exchange Information Store (MSExchangeIS)
• Microsoft Exchange System Attendant (MSExchangeSA)

The services providing SMTP, POP3 and IMAP4 connectivity are usually similarly important, especially the SMTP service. Looking at the EventSentry service status page immediately reveals that the SMTP, POP3 and IMAP4 services are managed by IIS:

Thumbnail image for eventlogblog_2010_01_es_services.png

As you can see, IMAP4Svc, POP3Svc and SMTPSvc all use inetinfo.exe (Executable column) for their host process. So why is this important again?

Since all of these services support multiple instances INSIDE the service (inetinfo.exe), the host process will continue to run even when one or more instances inside the service are stopped. Since most installations only have one instance, stopping that one instance inside the service will still leave the service up and running. The effect of course is the same; the service is not available to the end users while the Windows service will happily continue to run.

A screen shot from the System Manager application shows instances listed inside:


As you can see with the IMAP4 protocol, we have two virtual servers setup that are both hosted inside the “Microsoft Exchange IMAP4” service. To stubbornly illustrate my point further I took a screenshot that shows both IMAP4 instances stopped while the service itself is running:


So I think we’re all in agreement now that monitoring the POP3, SMTP etc. services in Exchange 2003 is not enough if you want to ensure that these services are actually available. So how do we monitor all of these instances?
The easiest way is actually with a VBScript, which is included below. VBScript works well since the cscript.exe interpreter is readily installed on Windows 2003, so no additional installation of tools is required. The script enumerates all instances of a given protocol, and checks whether they are running or not. If at least one instance is not running, the tool will return 1, thus setting the ERRORLEVEL to 1.

This VBScript can then be embedded into EventSentry, which will then run the script at set intervals using the application scheduler, notifying you via email (with the proper filter setup) when an instance is stopped. There’s a screencast for that, you can view it at It shows you how to create an embedded script and setup EventSentry to notify you when the scripts returns an error. Note that the screencast uses an older version of the script which only monitored web sites (not SMTP, IMAP4, …), but the process of setting up the script with EventSentry is exactly the same.

You should be able to use the script as-is, just configure which protocols are monitored by adjusting the values in the “Define which protocols to monitor here” section. The script always prints all installed instances and their status, and any stopped instance is prefixed with an asterisk. Below is what an email from EventSentry looks like:


The line with the stopped instance won’t be yellow in the actual email, I just added this for readability. The script can also easily be modified to automatically start any stopped instances – simply add the line


after line 102. This will still trigger an email (or error) to notify you that it was stopped, but a subsequent run of the script at the next monitoring interval should not trigger an error again if the start was successful.

A note of caution here though – I have seen the script hang indefinitely with this line added when an instance that is currently stopped can’t be started because it’s not configured correctly. Hence, it’s not included by default.


‘ Lists the state of all IIS protocols configured on the local machine
‘ and returns an %ERRORLEVEL% of 1, if at least one instance is not in
‘ the “Started” state.

‘ When scheduling this script with EventSentry’s application scheduler,
‘ make sure that the interpreter is set to “cscript.exe”

Option Explicit

Dim allInstancesAreRunning

Dim monitorSMTP, monitorPOP3, monitorIMAP4, monitorNNTP, monitorFTP, monitorWWW

‘ Define which protocols to monitor here

monitorSMTP  = 1
monitorPOP3  = 1
monitorIMAP4 = 1
monitorNNTP  = 1
monitorFTP   = 1
monitorWWW   = 1

‘ Define which protocols to monitor here

‘ ==================== EXECUTION STARTS HERE ====================
allInstancesAreRunning = EnumerateAllInstances

If allInstancesAreRunning = 0 Then
WScript.Echo vbCRLF & “WARNING: One or more IIS components are not running” & vbCRLF
End If

If allInstancesAreRunning = 0 Then
WScript.Quit 1
End If

‘ ==================== FUNCTIONS ====================
Function EnumerateAllInstances

EnumerateAllInstances = 1

If monitorSMTP = 1 Then
EnumerateAllInstances = EnumerateAllInstances And EnumerateInstances(“localhost”, “SMTPSVC”)
End If

If monitorPOP3 = 1 Then
EnumerateAllInstances = EnumerateAllInstances And EnumerateInstances(“localhost”, “POP3SVC”)
End If

If monitorIMAP4 = 1 Then
EnumerateAllInstances = EnumerateAllInstances And EnumerateInstances(“localhost”, “IMAP4SVC”)
End If

If monitorNNTP = 1 Then
EnumerateAllInstances = EnumerateAllInstances And EnumerateInstances(“localhost”, “NNTPSVC”)
End If

If monitorFTP = 1 Then
EnumerateAllInstances = EnumerateAllInstances And EnumerateInstances(“localhost”, “FTPSVC”)
End If

If monitorWWW = 1 Then
EnumerateAllInstances = EnumerateAllInstances And EnumerateInstances(“localhost”, “W3SVC”)
End If

End Function

Function MapServiceToInstance( Service )

If Service = “SMTPSVC” Then
MapServiceToInstance = “IIsSmtpServer”
ElseIf Service = “POP3SVC” Then
MapServiceToInstance = “IIsPop3Server”
ElseIf Service = “IMAP4SVC” Then
MapServiceToInstance = “IIsImapServer”
ElseIf Service = “W3SVC” Then
MapServiceToInstance = “IIsWebServer”
ElseIf Service = “NNTPSVC” Then
MapServiceToInstance = “IIsNntpServer”
ElseIf Service = “FTPSVC” Then
MapServiceToInstance = “IIsFtpServer”
End If

End Function

Function EnumerateInstances( Server, Service )
On Error Resume Next

Dim VirtualServerService
Dim Instance, InstanceID

EnumerateInstances = 1

Set VirtualServerService = GetObject(“IIS://” & Server & “/” & Service)

If Err.Number = 0 Then
InstanceID = MapServiceToInstance(Service)

For Each Instance in VirtualServerService

If Instance.KeyType = InstanceID Then

If SiteIsNotRunning(Instance.ServerState) Then
WScript.StdOut.Write “*”
EnumerateInstances = 0
End If

WScript.StdOut.Write Instance.ServerComment & ” (” & Service & “): ” & State2Desc(Instance.ServerState) & vbCRLF
End If
End If

End Function

Function SiteIsNotRunning( nState )

If nState <> 2 Then
SiteIsNotRunning = 1
SiteIsNotRunning = 0
End If

End Function

Function State2Desc( nState )

Select Case nState
Case 1
State2Desc = “Starting”
Case 2
State2Desc = “Running”
Case 3
State2Desc = “Stopping”
Case 4
State2Desc = “Stopped”
Case 5
State2Desc = “Pausing”
Case 6
State2Desc = “Paused”
Case 7
State2Desc = “Continuing”
Case Else
State2Desc = “Unknown state”
End Select

End Function


You can also download the script from here.

Until next time,