Thursday, March 4, 2010

PowerShell - Disk Space HTML Email Report


Hi Guys and fellow powershell scripters :),
Well, i have been busy for the past few days and now time to write my next blog.
As you already know from the title, yes am going to write a powershell script which generate a html report of the disk spaces details on a given list of servers and then email that report to the administrator or any email address.

What is needed?
A file named sl.txt on the directory where you have this script copied, this file will have the list of computers, one per line.

Before i start to go into details, you can simply get the diskspace info for any computer by the following powershell cmd-let

Get-WmiObject win32_logicaldisk  | format-table DeviceID, VolumeName,status,Size,FreeSpace | Out-File FreeSpace.txt

Well many in the world dont like some black&white text report, they just dont like it, well lets create a HTML report of this diskspace info and then email it.

So, lets jump in and get his badboy started.
My Powershell script contains 5 important functions, which do their own job.
Below are the details of those 5 functions:
1.writeHtmlHeader: This function write the HTML tags to create the html file and then kick start the process.
   This function also write some CSS styling info, so dont worry about any of this, i have already taken the load of going through them and creating it, so this is just for your info.
Below is the code for this function:
2.writeHtmlFooter - This function simply updates the file in the end to add the closing html tags , the same old </body> and the </html> tags.
3. sendEmail - This function sends email to the given address, it takes in from,to,subject,smtphost,htmlfile as the input and then composes the message and then emails the file.

4.writeTableHeader - This function simply writes the html tags for a table, my idea was for each and every computer to have a seperate table header, for eg., drive letter C:\ and the the lable of the drive "OS", and then total space ,free space etc., these info will be the table header for each computer. 


5. writeDiskInfo -  This is the actual function which write the disk details to the html file, it also calculates the free space percentage etc.,
On top of the script, i have setup some variable like the sl.txt file which will contain the server names, you can change it to whatever name of the file you want or you take in parameter from the user and then process it, it is left to you.

I have two more variables named lke $warning and $critical, i have set them to 85 and 70, these values will be compared against the free disk space percentage and then if a particular drive is above the critical or warning threshold, that particular drive will marked in RED and Yellow respectively.
You will get an idea of what i am talking about when you see the screen shot below:
Here is the complete Script:


# First lets create a text file, where we will later save the freedisk space info
$freeSpaceFileName = "FreeSpace.htm"
$serverlist = "sl.txt"
$warning = 90
$critical = 75
New-Item -ItemType file $freeSpaceFileName -Force
# Getting the freespace info using WMI
#Get-WmiObject win32_logicaldisk  | format-table DeviceID, VolumeName,status,Size,FreeSpace | Out-File FreeSpace.txt
# Function to write the HTML Header to the file
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>EVOLUTION.COM DiskSpace 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>EVOLUTION.COM DiskSpace 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 "<tr bgcolor=#CCCCCC>"
Add-Content $fileName "<td width='10%' align='center'>Drive</td>"
Add-Content $fileName "<td width='50%' align='center'>Drive Label</td>"
Add-Content $fileName "<td width='10%' align='center'>Total Capacity(GB)</td>"
Add-Content $fileName "<td width='10%' align='center'>Used Capacity(GB)</td>"
Add-Content $fileName "<td width='10%' align='center'>Free Space(GB)</td>"
Add-Content $fileName "<td width='10%' align='center'>Freespace %</td>"
Add-Content $fileName "</tr>"
}

Function writeHtmlFooter
{
param($fileName)

Add-Content $fileName "</body>"
Add-Content $fileName "</html>"
}

Function writeDiskInfo
{
param($fileName,$devId,$volName,$frSpace,$totSpace)
$totSpace=[math]::Round(($totSpace/1073741824),2)
$frSpace=[Math]::Round(($frSpace/1073741824),2)
$usedSpace = $totSpace - $frspace
$usedSpace=[Math]::Round($usedSpace,2)
$freePercent = ($frspace/$totSpace)*100
$freePercent = [Math]::Round($freePercent,0)
        if ($freePercent -gt $warning)
        {
                Add-Content $fileName "<tr>"
                Add-Content $fileName "<td>$devid</td>"
                Add-Content $fileName "<td>$volName</td>"
               
                Add-Content $fileName "<td>$totSpace</td>"
                Add-Content $fileName "<td>$usedSpace</td>"
                Add-Content $fileName "<td>$frSpace</td>"
                Add-Content $fileName "<td>$freePercent</td>"
                Add-Content $fileName "</tr>"
        }
        elseif ($freePercent -le $critical)
        {
                Add-Content $fileName "<tr>"
                Add-Content $fileName "<td>$devid</td>"
                Add-Content $fileName "<td>$volName</td>"               
                Add-Content $fileName "<td>$totSpace</td>"
                Add-Content $fileName "<td>$usedSpace</td>"
                Add-Content $fileName "<td>$frSpace</td>"
                Add-Content $fileName "<td bgcolor='#FF0000' align=center>$freePercent</td>"
                #<td bgcolor='#FF0000' align=center>
                Add-Content $fileName "</tr>"
        }
        else
        {
                Add-Content $fileName "<tr>"
                Add-Content $fileName "<td>$devid</td>"
                Add-Content $fileName "<td>$volName</td>"               
                Add-Content $fileName "<td>$totSpace</td>"
                Add-Content $fileName "<td>$usedSpace</td>"
                Add-Content $fileName "<td>$frSpace</td>"
                Add-Content $fileName "<td bgcolor='#FBB917' align=center>$freePercent</td>"
                # #FBB917
                Add-Content $fileName "</tr>"
        }
}
Function sendEmail
{ param($from,$to,$subject,$smtphost,$htmlFileName)
$body = Get-Content $htmlFileName
$smtp= New-Object net.Mail.smtpclient($smtphost)
$msg = New-Object net.Mail.MailMessage($From,$To,$subject,$body)
$msg.isBodyhtml = $true
$smtp.send($msg)   
}


writeHtmlHeader $freeSpaceFileName

foreach ($server in Get-Content $serverlist)
{
    Add-Content $freeSpaceFileName "<table width='100%'><tbody>"
    Add-Content $freeSpaceFileName "<tr bgcolor='#CCCCCC'>"
    Add-Content $freeSpaceFileName "<td width='100%' align='center' colSpan=6><font face='tahoma' color='#003399' size='2'><strong> $server </strong></font></td>"
    Add-Content $freeSpaceFileName "</tr>"
   
    writeTableHeader $freeSpaceFileName

        $dp = Get-WmiObject win32_logicaldisk
            foreach ($item in $dp)
            {
                Write-Host  $item.DeviceID  $item.VolumeName $item.FreeSpace $item.Size
                writeDiskInfo $freeSpaceFileName $item.DeviceID $item.VolumeName $item.FreeSpace $item.Size
                   
            }
}
writeHtmlFooter $freeSpaceFileName
$date = ( get-date ).ToString('yyyy/MM/dd')
sendEmail rdawkins@evolution.com rdawkins@evolution.com "Disk Space Report - $Date" localhost $freeSpaceFileName

Below are couple of screenshots, 1st one shows the email which got delivered when running this script, the second one shows the actual email.

1st Screenshot: (You can see i have sent so many emails :).

2nd ScreenShot: Actual email when double-clicked, to show that it is a body of the email is the html generated by the script.


You guys can setup a scheduled job and make the script to send a report on a daily basis to analyse your diskspace info of the network.
thanks for reading this blog, any comments or questions , please post.
Until my next blog, adios.

~fox

கற்க கசடறக் கற்பவை கற்றபின் 
நிற்க அதற்குத் தக 

குறள் எண்: 391

1 comment:

  1. It does not take the second server name in SL.txt

    ReplyDelete