Your one stop shop to various PowerShell resources: Downloads, Webcasts, Videos, Podcasts and more... click to get more information
Exchange White Space - Shay Levy

Shay Levy

If you repeat it, $CRIPT it!

Exchange White Space

A common posting on PowerShell newsgroups and forums from Exchange administrators is how to parse event id 1221 from the Exchange server application log file. A typical event message would look like:

Event Type:  Information
Event Source: MSExchangeIS Mailbox Store
Event Category: General 
Event ID: 1221
Date:  10/01/2009
Time: 13:27:31
User:  N/A
Computer: SERVER
Description: The database "First Storage Group\Mailbox Store (SERVER)" has
7.2 megabytes of free space after online defragmentation has terminated.

Usual solutions are based on regular expressions to process the message description and extract the name of the database(s) and the number of free megabytes. The bellow code gets the information and doesn’t require any knowledge of regular expression, though I strongly recommend any sys admin getting to know regex!

The message text is a fixed message with two placeholders for the database name and the free megabytes:

  The database "<name>" has “<number>” megabytes of free space after online defragmentation has terminated.

We can access the message placeholder values with the insertion strings array property of the Windows NT event object:

Get-WMIObject Win32_NTLogEvent -ComputerName SERVER -Filter "LogFile='Application' AND `
EventCode=1221 AND TimeWritten>='$Start' AND TimeWritten<='$End'" | `
Select-Object  ComputerName,InsertionStrings

ComputerName InsertionStrings
------------ ----------------
SERVER       {10351, First Storage Group\SG1 (SERVER)}
SERVER       {6043, Second Storage Group\SG2 (SERVER)}
SERVER       {881, Third Storage Group\SG3 (SERVER)}

As you can see, the free megs are positioned at index 0 and the database name at 1. With Get-ExchangeWhiteSpace we can pass a computer name and get white space information for the previous day. 

function Get-ExchangeWhiteSpace {

param(
  
$ComputerName = $(throw "ComputerName cannot be empty.")
)

# Convert Dates to WMI CIM dates
$tc = [System.Management.ManagementDateTimeconverter]
$Start =$tc::ToDmtfDateTime( (Get-Date).AddDays(-1).Date )
$End =$tc::ToDmtfDateTime( (Get-Date).Date)

# Create two claculated properties for InsertionStrings values
$DB = @{Name="DB";Expression={$_.InsertionStrings[1]}}
$FreeMB = @{Name="FreeMB";Expression={[int]$_.InsertionStrings[0]}}

Get-WMIObject Win32_NTLogEvent -ComputerName $ComputerName -Filter "LogFile='Application' AND EventCode=1221 AND TimeWritten>='$Start' AND TimeWritten<='$End'" | Select-Object ComputerName,$DB,$FreeMB | Sort-Object FreeMBUnique Descending

}

 

PS > Get-ExchangeWhiteSpace -ComputerName SERVER | Format-Table -AutoSize

ComputerName DB                                FreeMB
------------ --                                ------
SERVER       First Storage Group\SG1(SERVER)   10351
SERVER       Second Storage Group\SG2(SERVER)  6043
SERVER       Third Storage Group\SG3(SERVER)   881

Comments

Episode 80 – Klaus Graefensteiner « PowerScripting Podcast said:

Pingback from  Episode 80 &#8211; Klaus Graefensteiner &laquo;  PowerScripting Podcast

# August 17, 2009 4:36 AM

Tom said:

Hi Shay,

Saw your script during a search.

I could not run this on exchange shell script with an error output. Anything wrong with it?

# August 22, 2009 10:55 AM

ScriptFanatic said:

What's the error?

# August 22, 2009 5:02 PM

tom said:

Basically i Copied your script into a *.ps1 file and activated it but nothing comes out. Is there any instruction or compatibility on the powershell to run the script?

Maybe you can ignore the first post as I used one of the command to run on powershell as within the command has variable.

# August 22, 2009 5:41 PM

ScriptFanatic said:

Nothing will happen when you execute the ps1 file you've created, you need to call the function. Add this to the end of your ps1 file (after the function declaration) and run the script again:

Get-ExchangeWhiteSpace -ComputerName <YourExServerName>

# August 22, 2009 7:19 PM

tom said:

I put the "Get-ExchangeWhiteSpace -Computer <ExServerName> at the end of '}' function but nothing comes out too?.

# August 22, 2009 7:32 PM

ScriptFanatic said:

I guess you don't have any 1221 events in the log for the specified period of time. Try to change the $Start varibale to -10 days and see if it helps.

# August 22, 2009 8:04 PM

tom said:

-10 means 10 hours?

# August 22, 2009 8:21 PM

ScriptFanatic said:

$Start sets the starting date to -10 days from the current date.

# August 22, 2009 8:46 PM

tom said:

Thanks scriptFanatic. Edited it and it's working fine now. Just some clarification to make this event more accurate is that when I run this script, it provides alot of similar databases event ID 1221. Is there anyway just to grep the last database offline defragmentation ID 1221?

# August 22, 2009 8:56 PM

ScriptFanatic said:

1. Add a third calculated property (convert wmi dates)

  $TimeWritten = @{Name="TimeWritten";Expression={ $tc::ToDateTime($_.TimeWritten).ToShortDateString()}}

2. Change the select+sort command to:

  Select-Object ComputerName,$DB,$FreeMB,$TimeWritten | Sort-Object TimeWritten,FreeMB –Descending

3. Pipe the reults of the function to where-object and filter by a date  of your choice

  Get-ExchangeWhiteSpace serverName | where {$_.TimeWritten -eq '8/21/2009'}

# August 22, 2009 9:39 PM

Don V said:

Great script Shay, but how do I export the output to a csv file?

Thanks, Don

# September 30, 2009 10:12 PM

ScriptFanatic said:

Pipe the command to Export-Csv :)

Get-ExchangeWhiteSpace -ComputerName SERVER | Export-Csv -Path ExWhiteSpace.csv

# October 1, 2009 3:19 PM

Exchange 2007 Mailbox Database Reporting Script « Unlock-PowerShell said:

Pingback from  Exchange 2007 Mailbox Database Reporting Script &laquo; Unlock-PowerShell

# January 27, 2010 4:57 AM
Leave a Comment

(required) 

(required) 

(optional)

(required) 


Enter the numbers above: