One of the new features introduced in ex 2003 sp2 is the ability to track public folder deletes. To turn this on you need to turn diagnostic logging on the public store general category to at least medium. For more details on this see the F1 help and look for the topic “Track Public Folder Deletions”. Once this option is turned on, when someone deletes a public folder Exchange then logs an event of type 9682 into the Application log on the server which tells you which folder was deleted and by whom it was deleted. Having this information in the event log is useful but for reporting purposes and proactive management (eg tracking folders that shouldn’t have been deleted) it’s a little impractical. So what I’ve come up with is a script that queries the eventlog on a server for a specified number of days retrieves any public folder delete entries parses all the values out and creates a CSV file with the result. It also outputs the result to the command line
The script itself is very simple it takes two commandline parameters which is the name of the server you want to query and the time period in days you want to query for. Then it does a semi-sync query of the Application log via WMI for any 9682 messages logged within the specified time period. It then parses the folder name, folder id, the mailbox that deleted the folder (displayed as the LegacyDN value) and also the username of the user that deleted the mailbox. The parser works by parsing the log message based on the static elements in the log format. The results are finally echoed to the console and then written to a csv file called pfdeletes.csv.
I’m working on a extended version of this script that uses the information retrieved from the event log to then query the folder dumpster of the parent folder that was deleted to get extra information about the folder such as how big it was, how many items where in the folder, who created it and maybe who the folder contacts are.
I’ve put a downloadable copy of the script here the script itself looks like the following to run the script requires two command-line parameters the servername and the number of days to query eg to query the log for the last 7 days it would look like
Cscript showpfdeletes.vbs servername 7
days = wscript.arguments(1)
servername = wscript.arguments(0)
SB = 0
Set fso = CreateObject("Scripting.FileSystemObject")
set wfile = fso.opentextfile("c:\PfDeletes.csv",2,true)
wfile.writeline("DateDeleted,FolderName,FolderID,DeletedBy-MailboxName,DeletedBy-UserName")
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 Timewritten,Message from Win32_NTLogEvent Where Logfile='Application' and Eventcode = '9682' and TimeWritten >= '" & dtmStartDate & "' ",,48)
wscript.echo "Date Deleted FolderName FolderID Deleter-Mbox Deleter-UserName"
For Each objEvent in colLoggedEvents
SB = 1
Time_Written = cdate(DateSerial(Left(objEvent.TimeWritten, 4), Mid(objEvent.TimeWritten, 5, 2), Mid(objEvent.TimeWritten, 7, 2)) & " " & timeserial(Mid(objEvent.TimeWritten, 9, 2),Mid(objEvent.TimeWritten, 11, 2),Mid(objEvent.TimeWritten,13, 2)))
FolderName = Mid(objEvent.Message,8,instr(objEvent.Message,"with folder")-9)
FolderID = Mid(objEvent.Message,instr(objEvent.Message,"with folder ID")+15,(instr(objEvent.Message,"was deleted by")-(instr(objEvent.Message,"with folder ID")+16)))
MailboxName = Mid(objEvent.Message,instr(objEvent.Message,"was deleted by")+15,instr(objEvent.Message,", user account")-(instr(objEvent.Message,"was deleted by")+15))
UserName = Mid(objEvent.Message,instr(objEvent.Message,", user account")+15,(instr(objEvent.Message,chr(13))-(instr(objEvent.Message,", user account")+16)))
wscript.echo Time_Written & " " & FolderName & " " & FolderID & " " & MailboxName & " " & UserName
wfile.writeline(Time_Written & "," & FolderName & "," & FolderID & "," & MailboxName & "," & UserName)
next
wfile.close
set wfile = nothing
if SB = 0 then wscript.echo "No Public Folder Deletes recorded in the last " & days & " Days"
The script itself is very simple it takes two commandline parameters which is the name of the server you want to query and the time period in days you want to query for. Then it does a semi-sync query of the Application log via WMI for any 9682 messages logged within the specified time period. It then parses the folder name, folder id, the mailbox that deleted the folder (displayed as the LegacyDN value) and also the username of the user that deleted the mailbox. The parser works by parsing the log message based on the static elements in the log format. The results are finally echoed to the console and then written to a csv file called pfdeletes.csv.
I’m working on a extended version of this script that uses the information retrieved from the event log to then query the folder dumpster of the parent folder that was deleted to get extra information about the folder such as how big it was, how many items where in the folder, who created it and maybe who the folder contacts are.
I’ve put a downloadable copy of the script here the script itself looks like the following to run the script requires two command-line parameters the servername and the number of days to query eg to query the log for the last 7 days it would look like
Cscript showpfdeletes.vbs servername 7
days = wscript.arguments(1)
servername = wscript.arguments(0)
SB = 0
Set fso = CreateObject("Scripting.FileSystemObject")
set wfile = fso.opentextfile("c:\PfDeletes.csv",2,true)
wfile.writeline("DateDeleted,FolderName,FolderID,DeletedBy-MailboxName,DeletedBy-UserName")
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 Timewritten,Message from Win32_NTLogEvent Where Logfile='Application' and Eventcode = '9682' and TimeWritten >= '" & dtmStartDate & "' ",,48)
wscript.echo "Date Deleted FolderName FolderID Deleter-Mbox Deleter-UserName"
For Each objEvent in colLoggedEvents
SB = 1
Time_Written = cdate(DateSerial(Left(objEvent.TimeWritten, 4), Mid(objEvent.TimeWritten, 5, 2), Mid(objEvent.TimeWritten, 7, 2)) & " " & timeserial(Mid(objEvent.TimeWritten, 9, 2),Mid(objEvent.TimeWritten, 11, 2),Mid(objEvent.TimeWritten,13, 2)))
FolderName = Mid(objEvent.Message,8,instr(objEvent.Message,"with folder")-9)
FolderID = Mid(objEvent.Message,instr(objEvent.Message,"with folder ID")+15,(instr(objEvent.Message,"was deleted by")-(instr(objEvent.Message,"with folder ID")+16)))
MailboxName = Mid(objEvent.Message,instr(objEvent.Message,"was deleted by")+15,instr(objEvent.Message,", user account")-(instr(objEvent.Message,"was deleted by")+15))
UserName = Mid(objEvent.Message,instr(objEvent.Message,", user account")+15,(instr(objEvent.Message,chr(13))-(instr(objEvent.Message,", user account")+16)))
wscript.echo Time_Written & " " & FolderName & " " & FolderID & " " & MailboxName & " " & UserName
wfile.writeline(Time_Written & "," & FolderName & "," & FolderID & "," & MailboxName & "," & UserName)
next
wfile.close
set wfile = nothing
if SB = 0 then wscript.echo "No Public Folder Deletes recorded in the last " & days & " Days"