Exchange 2010 health check

A long time ago I found some really useful powershell to report on the health of my Exchange 2010 environment.

Whilst this is pretty much a straight cut-n-paste job I have made some changes and kept the more relevant (at least to me) data whilst removing columns I thought we not adding "value".  

I added a feature to look up a file called: C:\Scripts\HealthCheck\MailboxServers.csv which is a key/value pair of Mailbox name and mailbox Server name.  This will show you if a mailbox has failed over from the designated mailbox server.  

For example, if database1 and database2 are running on my_mbx_server1 and database3 is running on my_mbx_server2 then: 

my_mbx_server1, database1
my_mbx_server1, database2
my_mbx_server2, database3

The code will read this file in and check that all mailboxes are running on the designated mailbox servers, if not, the cell is highlighted in red with some text detailing where the mailbox has moved from.

Probably the best way is to schedule this to run from a management server - we have EMC installed on the box to get the powershell add ins.

Here's how I run it from the task scheduler:

Action: Start a program
Program/Script: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Add arguments (optional): -command ". 'C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1'; Connect-ExchangeServer -auto; c:\Scripts\HealthCheck\Backup_report.ps1"

Anyways here is the powershell:

##################################################################################### 
# Exchange 2010 Mailbox Database HTML Email Report 
# Author: Thiyagu14 
# Date Jan 28th 2010 
# Script gathers below information 
# 1. Server currently hosting the Database. 
# 2. Database Size 
# 3. Database file path 
# 4. Number of users in the Database. 
# 5. Amount of Whitespace 
# 6. Top Mailbox in the Database and the size of it. 
# 7. Last Backup time and days since last backup. 
# ################################################################################### 
# It then generates HTML Files for this. 
# You can setup Threshold in the script,below are the items which can have threshold 
# 1. Number of Mailboxes 
# 2. Database Size 
# 3. How old a Backup can be 
# 4. Top Mailbox Size 
# If any one of the above threshold is reached the configured threshold. 
# It will be marked as red in the HTML. 
##################################################################################### 
Clear-Host
Remove-Item DBReport.htm 
New-Item -ItemType file -Name dbreport.htm 
$mailboxCountThreshold = 250 
$dbSizeThreshold = 480GB
$backupThreshold = 3 
$mbxSizeThreshold = 2048MB
$fileName = "DBReport.htm"

Function writeHtmlHeader{ 
param($fileName) 
$date = ( Get-Date ).ToString('yyyy/MM/dd') 
Add-Content $fileName "<html>" 
Add-Content $fileName "<head>" 
Add-Content $fileName "<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>" 
Add-Content $fileName '<title>Exchange 2010 Report</title>' 
Add-Content $fileName '<STYLE TYPE="text/css">' 
Add-Content $fileName  "<!--" 
Add-Content $fileName  "td {" 
Add-Content $fileName  "font-family: Tahoma;" 
Add-Content $fileName  "font-size: 11px;" 
Add-Content $fileName  "border-top: 1px solid #999999;" 
Add-Content $fileName  "border-right: 1px solid #999999;" 
Add-Content $fileName  "border-bottom: 1px solid #999999;" 
Add-Content $fileName  "border-left: 1px solid #999999;" 
Add-Content $fileName  "padding-top: 0px;" 
Add-Content $fileName  "padding-right: 0px;" 
Add-Content $fileName  "padding-bottom: 0px;" 
Add-Content $fileName  "padding-left: 0px;" 
Add-Content $fileName  "}" 
Add-Content $fileName  "body {" 
Add-Content $fileName  "margin-left: 5px;" 
Add-Content $fileName  "margin-top: 5px;" 
Add-Content $fileName  "margin-right: 0px;" 
Add-Content $fileName  "margin-bottom: 10px;" 
Add-Content $fileName  "" 
Add-Content $fileName  "table {" 
Add-Content $fileName  "border: thin solid #000000;" 
Add-Content $fileName  "}" 
Add-Content $fileName  "-->" 
Add-Content $fileName  "</style>" 
Add-Content $fileName "</head>" 
Add-Content $fileName "<body>" 
Add-Content $fileName  "<table width='100%'>" 
Add-Content $fileName  "<tr bgcolor='#CCCCCC'>" 
Add-Content $fileName  "<td colspan='7' height='25' align='center'>" 
Add-Content $fileName  "<font face='tahoma' color='#003399' size='4'><strong>Exchange 2010 Database Report - $date</strong></font>" 
Add-Content $fileName  "</td>" 
Add-Content $fileName  "</tr>" 
Add-Content $fileName  "</table>" 
# Function to write the HTML Header to the file 
Function writeTableHeader{ 
param($fileName) 
Add-Content $fileName "<table width='100%'><tbody>"  
Add-Content $fileName "<tr bgcolor=#CCCCCC>" 
Add-Content $fileName "<td width='10%' align='center'>Database Name</td>" 
Add-Content $fileName "<td width='10%' align='center'>Server</td>" 
    Add-Content $fileName "<td width='10%' align='center'>Free Space (GB)</td>"
Add-Content $fileName "<td width='15%' align='center'>Database File</td>"
Add-Content $fileName "<td width='10%' align='center'>Database Size (MB)</td>"  
Add-Content $fileName "<td width='7%' align='center'># of Mailboxes</td>" 
Add-Content $fileName "<td width='10%' align='center'>WhiteSpace (GB)</td>"
#Add-Content $fileName "<td width='10%' align='center'>Top Mailbox Size</td>" 

Add-Content $fileName "<td width='10%' align='center'>Last Full Backup</td>" 
Add-Content $fileName "<td width='15%' align='center'>Days of log files</td>" 
Add-Content $fileName "</tr>" 
Function writeHtmlFooter{ 
param($fileName) 
Add-Content $fileName "</table>" 
Add-Content $fileName "</body>" 
Add-Content $fileName "</html>" 
Function get-DBInfo{ 
$dbs = Get-MailboxDatabase -Status | Sort Name
foreach($db in $dbs){ 
    $name = $db.name 
$svr = $db.servername     
$edb = $db.edbfilepath
     
$edbSize = $db.DatabaseSize

$whiteSpace = $db.AvailableNewMailboxSpace.ToMB()

$mbxCount = (Get-Mailbox -Database $db).count
    
$lastBackup =  $db.LastFullBackup
        $lastDiff = $db.LastIncrementalBackup

$currentDate = Get-Date

if ($lastBackup -eq $null){     
$howOldBkp =  $null      
elseif($lastDiff -ne $null){
            $howOldBkp = $currentDate - $lastDiff     
$howOldBkp = $howOldBkp.days     
# Convert Date to UK format
$lastbackup = $lastbackup.ToString("dd-MM-yyyy")
$currentDate = Get-Date -format "dd-MM-yyyy"     
}
        else{ 
$howOldBkp = $currentDate - $lastBackup     
$howOldBkp = $howOldBkp.days     
# Convert Date to UK format
$lastbackup = $lastbackup.ToString("dd-MM-yyyy")
$currentDate = Get-Date -format "dd-MM-yyyy"
}
        $diskData = get-DiskSpace $svr ($edb.ToString()).SubString(0,2)

   writedata $name $svr $edb $edbSize $whiteSpace $mbxCount $topMailbox $topMailboxSize $lastBackup $howOldBkp $diskData
}
Function get-DiskSpace{
    param($name, $edb)
    # Get the space of the disks
    
    $diskData = Get-WmiObject win32_LogicalDisk -ComputerName $name | ?{$_.DeviceID -eq $edb} | Select FreeSpace

    $diskData = $diskData.FreeSpace/1024/1024/1024
    "{0:N0}" -f $diskData
}
Function WriteData{ 
param($name,$svr,$edb,$edbSize,$whiteSpace,$mbxCount,$topMailbox,$topMailboxSize,$lastBackup,$howOldBkp, $diskData) 
# Allen Kong
# Grab a CSV containing DB names and servers they should be running on
$hashtable=((get-content "C:\Scripts\HealthCheck\MailboxServers.csv") -replace ",","=") -join "`n" | ConvertFrom-StringData

$tableEntry = "<tr><td align=center>$name</td>"
# Alert if a mailbox is not running on the defined server
    $htmlline = "<td bgcolor='#aaaaff' align=center>No Record</td>"

    $hostsrv = $hashtable.Get_Item($name)

    if($hashtable.ContainsKey($name)){
        
        $htmlline = "<td bgcolor='#FF0000' align=center>Failed over to : $svr</br>From : $hostsrv</td>"

   if($hostsrv -eq $svr){
   $htmlline = "<td align=center>Running OK</td>"
   }
    }
    $tableEntry += $htmlline

    $tableEntry += "<td  align=center>$diskData</td>" 

$tableEntry += "<td  align=center>$edb</td>" 
#Checking if EDB size is greater than the set  Threshold 
#If it is greater than the table cell will be marked red, else green. 
if ($edbSize -gt $dbSizeThreshold){  
$tableEntry += "<td bgcolor='#FF0000' align=center>$edbSize</td>" 
else{ 
$tableEntry += "<td bgcolor='#387C44' align=center>$edbSize</td>" 

#Checking if mailbox count is greater than configured threshold 
if($mbxCount -gt $mailboxCountThreshold){ 
$tableEntry += "<td bgcolor='#FF0000' align=center>$mbxCount</td>" 
}
else{ 
$tableEntry += "<td bgcolor='#387C44' align=center>$mbxCount</td>" 
}
$whiteSpace = "{0:N2}" -f ($whiteSpace/1024)
$tableEntry +=  "<td align=center>$whiteSpace</td>" 
#Checking how old is the backup 
if ($howOldBkp -eq $null){ 
  $tableEntry += "<td bgcolor='#FF0000' align=center> null </td>" 
$tableEntry += "<td bgcolor='#FF0000' align=center>Never Backed Up</td>" 

elseif ($howOldBkp -le $backupThreshold){ 
$tableEntry += "<td bgcolor='#387C44' align=center>$lastbackup</td>" 
$tableEntry += "<td bgcolor='#387C44' align=center>$howOldBkp</td>" 
}

else{ 
$tableEntry += "<td bgcolor='#FF0000' align=center>$lastbackup</td>" 
$tableEntry += "<td bgcolor='#FF0000' align=center>$howOldBkp</td>" 
Add-Content $fileName $tableEntry 
Write-Host $tableEntry 
Function sendEmail{
param($from,$to,$subject,$smtphost,$htmlFileName) 
$body = Get-Content $htmlFileName 
$smtp= New-Object System.Net.Mail.SmtpClient $smtphost 
$msg = New-Object System.Net.Mail.MailMessage $from, $to, $subject, $body 
$msg.isBodyhtml = $true 
$smtp.send($msg) 
writehtmlheader $fileName 
writetableheader $fileName 
get-DBInfo 
writehtmlfooter $fileName 
sendEmail from@contoso.com to@contoso.com "Database Report" my_cas_server $fileName

Comments

Popular posts from this blog

PXE booting, MDT and 802.1x

Intune installation requires a wire...or does it?

Security Policy 1001