Skip to main content

Displaying the Store file usage Trends via Script using the Event log

Continuing on from some of my previous scripts last month around mail store file usage and backup results this script expands on this idea a little. As I’ve mentioned previously when the backup runs on an Exchange server (as long as it’s using the Exchange backup API eg Brightstore, Veritas etc). It logs to the event log a whole lot of useful information about when it started when it stopped and how much data (the size of each database file) that is going to be backed up. Because the event log is a historical record depending on how you have your eventlogs setup you will have a record that goes back of a number of weeks or months of how large the database store files where when each of the backups occurred. All this information is stored in the eventid 220.

So what this script does is like the others scripts before it is query AD for all the mail and public folder stores in your domain. Then query the exchange server’s event log for all the 220 events for a configured time period. I’ve set the period to 60 days in the script but you can increase or decrease this amount depending on your needs. Increasing the number of days will slow the script down because it will have more entries to filter though (the real limitation is going to be your actually event log size). The information about each day’s backup is stored in a multi dimensional array which stores the date of the event, the size of the data file and the usage between this backup and the last backup. Once the array has been fully populated with all the available events a report is then displayed to the command line showing the full usage for the number of days measured (just compares the lower array entry and the upper array entry). After this trend information is shown by looping though the array and showing the amount of usage in groups of 7 days as well as a daily average at the end. This allows you to see the amount of growth your experience each week and see where your spikes and troughs are.

Ive posted a downloaded copy of the code here

The script looks like

set conn = createobject("ADODB.Connection")
set com = createobject("ADODB.Command")
Set iAdRootDSE = GetObject("LDAP://RootDSE")
strNameingContext = iAdRootDSE.Get("configurationNamingContext")
rangeStep = 999
lowRange = 0
highRange = lowRange + rangeStep
Conn.Provider = "ADsDSOObject"
Conn.Open "ADs Provider"
mbQuery = ";(objectCategory=msExchPrivateMDB);name,distinguishedName;subtree"
pfQuery = ";(objectCategory=msExchPublicMDB);name,distinguishedName;subtree"
Com.ActiveConnection = Conn
Com.CommandText = mbQuery
Set Rs = Com.Execute
Wscript.echo "Mailbox Stores"
wscript.echo
While Not Rs.EOF
objmailstorename = "LDAP://" & Rs.Fields("distinguishedName")
set objmailstore = getObject(objmailstorename)
servername = mid(objmailstore.msExchOwningServer,4,instr(objmailstore.msExchOwningServer,",")-4)
wscript.echo Rs.Fields("name")
wscript.echo
getbackupdata = queryeventlog(servername,objmailstore.msExchEDBFile,objmailstore.msExchSLVFile)
Rs.MoveNext

Wend
Wscript.echo "Public Folder Stores"
Wscript.echo
Com.CommandText = pfQuery
Set Rs1 = Com.Execute
While Not Rs1.EOF
objmailstorename = "LDAP://" & Rs1.Fields("distinguishedName")
set objmailstore = getObject(objmailstorename)
servername = mid(objmailstore.msExchOwningServer,4,instr(objmailstore.msExchOwningServer,",")-4)
wscript.echo Rs1.Fields("name")
wscript.echo
getbackupdata = queryeventlog(servername,objmailstore.msExchEDBFile,objmailstore.msExchSLVFile)
Rs1.MoveNext

Wend
Rs.Close
Rs1.close
Conn.Close
Set Rs = Nothing
Set Rs1 = Nothing
Set Com = Nothing
Set Conn = Nothing


function queryeventlog(servername,edbfilename,stmfilename)
days = 60
SB = 0
edbarraycnt = 0
stmarraycnt = 0
dtmStartDate = CDate(Date) - days
dtmStartDate = Year(dtmStartDate) & Right( "00" & Month(dtmStartDate), 2) & Right( "00" & Day(dtmStartDate), 2)
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & servername & "\root\cimv2")
Set colLoggedEvents = objWMIService.ExecQuery("Select * from Win32_NTLogEvent Where Logfile='Application' and Eventcode = '220' and TimeWritten >= '" & dtmStartDate & "'",,48)
For Each objEvent in colLoggedEvents
SB = 1
Time_Written = objEvent.TimeWritten
Time_Written = left(Time_Written,(instr(Time_written,".")-1))
if instr(objEvent.Message,edbfilename) then
redim Preserve edbarray(3,edbarraycnt)
if edbarraycnt = 0 then
edbarray(0,edbarraycnt) = 0
edbarray(1,edbarraycnt) = dateserial(mid(Time_Written,1,4),mid(Time_Written,5,2),mid(Time_Written,7,2))
edbarray(2,edbarraycnt) = Mid(objEvent.Message,(InStr(objEvent.Message,"(size")+6),(InStr(objEvent.Message,"Mb)")-1)-(InStr(objEvent.Message,"(size")+6))
else
edbarray(0,(edbarraycnt-1)) = edbarray(2,(edbarraycnt-1)) - Mid(objEvent.Message,(InStr(objEvent.Message,"(size")+6),(InStr(objEvent.Message,"Mb)")-1)-(InStr(objEvent.Message,"(size")+6))
edbarray(1,edbarraycnt) = dateserial(mid(Time_Written,1,4),mid(Time_Written,5,2),mid(Time_Written,7,2))
edbarray(2,edbarraycnt) = Mid(objEvent.Message,(InStr(objEvent.Message,"(size")+6),(InStr(objEvent.Message,"Mb)")-1)-(InStr(objEvent.Message,"(size")+6))
edbarraysum = edbarray(0,(edbarraycnt-1)) + edbarraysum
end if
queryeventlog = dateserial(mid(Time_Written,1,4),mid(Time_Written,5,2),mid(Time_Written,7,2))
edbarraycnt = edbarraycnt + 1
else
if instr(objEvent.Message,stmfilename) then
redim Preserve stmarray(3,stmarraycnt)
if stmarraycnt = 0 then
stmarray(0,stmarraycnt) = 0
stmarray(1,stmarraycnt) = dateserial(mid(Time_Written,1,4),mid(Time_Written,5,2),mid(Time_Written,7,2))
stmarray(2,stmarraycnt) = Mid(objEvent.Message,(InStr(objEvent.Message,"(size")+6),(InStr(objEvent.Message,"Mb)")-1)-(InStr(objEvent.Message,"(size")+6))
else
stmarray(0,(stmarraycnt-1)) = stmarray(2,(stmarraycnt-1)) - Mid(objEvent.Message,(InStr(objEvent.Message,"(size")+6),(InStr(objEvent.Message,"Mb)")-1)-(InStr(objEvent.Message,"(size")+6))
stmarray(1,stmarraycnt) = dateserial(mid(Time_Written,1,4),mid(Time_Written,5,2),mid(Time_Written,7,2))
stmarray(2,stmarraycnt) = Mid(objEvent.Message,(InStr(objEvent.Message,"(size")+6),(InStr(objEvent.Message,"Mb)")-1)-(InStr(objEvent.Message,"(size")+6))
stmarraysum = stmarray(0,(stmarraycnt-1)) + stmarraysum
end if
stmarraycnt = stmarraycnt + 1
end if
end if
next
if SB = 0 then queryeventlog = "No Backup recorded in the last 7 Days"
if edbarraycnt > 1 then
Wscript.echo "EDB Mailstore file Size on " & edbarray(1,(edbarraycnt-1)) & " Size :" & edbarray(2,(edbarraycnt-1)) &" MB"
Wscript.echo "EDB Mailstore file Size on " & edbarray(1,0) & " Size :" & edbarray(2,0) &" MB"
Wscript.echo "EDB Mailstore file size Growth over " & datediff("d",edbarray(1,(edbarraycnt-1)),edbarray(1,0)) & " Days " & edbarray(2,0) - edbarray(2,(edbarraycnt-1)) & " MB"
wscript.echo
Wscript.echo "STM Mailstore file Size on " & stmarray(1,(stmarraycnt-1)) & " Size :" & stmarray(2,(stmarraycnt-1)) &" MB"
Wscript.echo "STM Mailstore file Size on " & stmarray(1,0) & " Size :" & stmarray(2,0) &" MB"
Wscript.echo "STM Mailstore File Size Growth over " & datediff("d",stmarray(1,(stmarraycnt-1)),stmarray(1,0)) & " Days " & stmarray(2,0) - stmarray(2,(stmarraycnt-1)) & " MB"
wscript.echo
Wscript.echo "Weekly Growth Trends EDB File"
wscript.echo
sdate = edbarray(1,0)
ssize = edbarray(2,0)
for i = 0 to (edbarraycnt-1)
if datediff("d",edbarray(1,i),sdate) > 6 then
wscript.echo "Growth on " & edbarray(1,i) & " to " & sdate & ": " & ssize-edbarray(2,i) & " MB"
sdate = edbarray(1,i)
ssize = edbarray(2,i)
end if
next
wscript.echo "Daily Average : " & formatnumber(edbarraysum/(datediff("d",edbarray(1,(edbarraycnt-1)),edbarray(1,0))),2) & " MB"
wscript.echo
Wscript.echo "Weekly Growth Trends STM File"
wscript.echo
sdate = stmarray(1,0)
ssize = stmarray(2,0)
for i = 0 to (stmarraycnt-1)
if datediff("d",stmarray(1,i),sdate) > 6 then
wscript.echo "Growth on " & stmarray(1,i) & " to " & sdate & ": " & ssize-stmarray(2,i) & " MB"
sdate = stmarray(1,i)
ssize = stmarray(2,i)
end if
next
wscript.echo "Daily Average : " & formatnumber(stmarraysum/(datediff("d",stmarray(1,(stmarraycnt-1)),stmarray(1,0))),2) & " MB"
wscript.echo
end if
end function

Popular posts from this blog

Testing and Sending email via SMTP using Opportunistic TLS and oAuth in Office365 with PowerShell

As well as EWS and Remote PowerShell (RPS) other mail protocols POP3, IMAP and SMTP have had OAuth authentication enabled in Exchange Online (Official announcement here ). A while ago I created  this script that used Opportunistic TLS to perform a Telnet style test against a SMTP server using SMTP AUTH. Now that oAuth authentication has been enabled in office365 I've updated this script to be able to use oAuth instead of SMTP Auth to test against Office365. I've also included a function to actually send a Message. Token Acquisition  To Send a Mail using oAuth you first need to get an Access token from Azure AD there are plenty of ways of doing this in PowerShell. You could use a library like MSAL or ADAL (just google your favoured method) or use a library less approach which I've included with this script . Whatever way you do this you need to make sure that your application registration  https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-

The MailboxConcurrency limit and using Batching in the Microsoft Graph API

If your getting an error such as Application is over its MailboxConcurrency limit while using the Microsoft Graph API this post may help you understand why. Background   The Mailbox  concurrency limit when your using the Graph API is 4 as per https://docs.microsoft.com/en-us/graph/throttling#outlook-service-limits . This is evaluated for each app ID and mailbox combination so this means you can have different apps running under the same credentials and the poor behavior of one won't cause the other to be throttled. If you compared that to EWS you could have up to 27 concurrent connections but they are shared across all apps on a first come first served basis. Batching Batching in the Graph API is a way of combining multiple requests into a single HTTP request. Batching in the Exchange Mail API's EWS and MAPI has been around for a long time and its common, for email Apps to process large numbers of smaller items for a variety of reasons.  Batching in the Graph is limited to a m

How to test SMTP using Opportunistic TLS with Powershell and grab the public certificate a SMTP server is using

Most email services these day employ Opportunistic TLS when trying to send Messages which means that wherever possible the Messages will be encrypted rather then the plain text legacy of SMTP.  This method was defined in RFC 3207 "SMTP Service Extension for Secure SMTP over Transport Layer Security" and  there's a quite a good explanation of Opportunistic TLS on Wikipedia  https://en.wikipedia.org/wiki/Opportunistic_TLS .  This is used for both Server to Server (eg MTA to MTA) and Client to server (Eg a Message client like Outlook which acts as a MSA) the later being generally Authenticated. Basically it allows you to have a normal plain text SMTP conversation that is then upgraded to TLS using the STARTTLS verb. Not all servers will support this verb so if its not supported then a message is just sent as Plain text. TLS relies on PKI certificates and the administrative issue s that come around certificate management like expired certificates which is why I wrote th
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.