If you do a lot of maintenance within your exchange databases, such as clearing deleted items and auto archiving messages, it is worth while keeping an eye on the database whitespace. When the whitespace reaches zero your database will grow, so it’s an important indicator of database health and a predictive marker for disk space requirements.
Whitespace is created and reported during the online database maintenance routines. In Exchange 2007 this is normally completed nightly and reported into the event logs, in Exchange 2010 this is a 24x7 operation (which can be turned off) and can be reported via powershell. This means that we need to take two different approaches to obtaining the data and making it available for the SNMP collector.
Exchange 2007.
Firstly we need a script to extract the ‘1221’ event codes from the event viewer and parse them for the reported size.. This script takes in the required database name
Whitespace.vbs..
strComputer = "."
DataBase = Wscript.Arguments(0)
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
strOutput = "Time,Server,Database,WhiteSpace"
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_NTLogEvent Where Logfile='Application' and Eventcode = '1221'")
For each objEvent in ColItems
strMessage = objEvent.Message
strResult = 0
If Instr(strMessage,DataBase) > 0 Then
StartWhiteSpaceSize = Instr(1,strMessage,"has",1)
EndWhiteSpaceSize = Instr(1,strMessage,"megabytes",1)
ReturnSizeLength = ((EndWhiteSpaceSize-1)-(StartWhiteSpaceSize+4))
strResult = Mid(strMessage,(StartWhiteSpaceSize+4),(ReturnSizeLength))
Wscript.Echo strResult
Wscript.quit
End If
Next
Now we can call this via our counter.ini file.. eg..
[1.3.6.1.4.1.15.38]
type=exec
counter=cscript C:\Whitespace.vbs MyDatabaseName //nologo
Add a custom poller for the OID e.g. in the example above [1.3.6.1.4.1.15.38] using GET and assign to your exchange mailbox server node, then place on your nodes page as a chart.
Repeat the process for each database by using a different OID and passing in the different Database name into the Whitespace.vbs script.
Note the value will only change after every online maintenance routine.
Exchange 2010
Exchange 2010 requires us to run a powershell command to extract the information directly from the exchange subsystem. This presents some challenges as the time it takes to fire up powershell and load the exchange addin’s often takes longer that the SNMP query will allow before a timeout. The best method I have found is to use a scheduled task to periodically call a powershell script and store the whitespace stats in the registry. We can then use a quick VBS script to call the figures out of the registry when the SNMP collector requires.
Firstly make sure that your system will allow the execution of unsigned scripts, or if you know what you are doing go ahead and get the script signed.
PS:>Set-ExecutionPolicy Unrestricted
Now create your powershell script – The script below tests for the reg key where we are going to store the stats and if not found creates it. It then either sets or creates a string value for each database.
Whitespace.ps1
add-pssnapin Microsoft.Exchange.Management.PowerShell.E2010
if (!(Test-Path 'HKLM:\System\CurrentControlSet\Services\MSExchangeIS\DBWhiteSpace'))
{md 'HKLM:\System\CurrentControlSet\Services\MSExchangeIS\DBWhiteSpace'}
Get-MailBoxDatabase -status | foreach-object {Set-ItemProperty HKLM:\System\CurrentControlSet\Services\MSExchangeIS\DBWhiteSpace -name $_.Name -value ($_.AvailableNewMailboxSpace.ToBytes() / 1MB)}
Now set a scheduled task on the mailbox server to execute the script say every 10 minutes using an action such as.. powershell.exe c:\whitespace.ps1. Sit back and check the values are being written to the registry under the Information Store service key.
Now create a vbs script that will query the registry for the database name we are interested in.
Whitespace.vbs
Set WSHShell = CreateObject("WScript.Shell")
RegKEY = "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSExchangeIS\DBWhiteSpace\" & Wscript.Arguments(0)
Val = WSHShell.RegRead(RegKEY)
wscript.echo val
Now we can put an entry into our counters.ini file to call the vbs script. E.g.
[1.3.6.1.4.1.15.75]
type=exec
counter=cscript C:\whitespace.vbs MydatabaseName //nologo
Add a custom poller for the OID e.g. in the example above [1.3.6.1.4.1.15.75] using GET and assign to your exchange mailbox server node, then place on your nodes page as a chart.
Repeat the process for each database by using a different OID and passing in the different Database name into the Whitespace.vbs script.
I hope that helps someone out there.