PowerShell – Script to Monitor Disk Space of a Group of servers – HTML Formatted Email Output

This post explains how to monitor DiskSpace of a group of listed servers in a text file.

The function Get-DiskSpaceReport comprises of various cmdLets and function to monitor Disk Drives.

  • Get-Win32LogicalDisks
  • HTML Ouptut
  • Email Address validation

You can customize it as per your requirement.The Function Get-DiskSpaceReport has six input parameters:-

  1. ComputerList – List of Servers – Path of a input file where servers are listed
  2. Warning – Warning Threshold – Default = 25%
  3. Critical – Critical Threshold – Default =15%
  4. SMTPMail – SMTP mail address
  5. FromID – Valid Email ID
  6. ToID – Valid Email ID

Example 1:- Execute with default threshold values. By default, the threshold are set to 25(Warning) and 15(Critical)

PS:\>Get-DiskSpaceReport -ComputerList c:\computer.txt  -To pjayaram@Appvion.com -From pjayaram@appvion.com -SMTPMail qqma01.ppp.com

Image

Example 2:- Customize the default threshold values.

PS:\>Get-DiskSpaceReport -ComputerList c:\computer.txt -warning 15 -critical 10 -To pjayaram@Appvion.com -From pjayaram@appvion.com -SMTPMail qqma01.ppp.com

Image

First create a function Get-DiskSpaceReport using the below code and do a function call. which is shown above

****************************************************************************

Function Get-DiskSpaceReport
{
param(
[String]$ComputerList,[int]$warning,[int]$critical,[String]$To,[String]$From,[string]$SMTPMail
)

$script:list = $ComputerList
$freeSpaceFileName = “C:\FreeSpace.htm”
if ($Warning -eq “$NULL”)
{
$Warning=25
}

if ($critical -eq “$NULL”)
{
$critical=15
}

$critical = $critical
$warning = $warning
New-Item -ItemType file $freeSpaceFileName -Force

# Getting the freespace info using WMI
#Get-WmiObject win32_logicaldisk | Where-Object {$_.drivetype -eq 3 -OR $_.drivetype -eq 2 } | 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>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>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>”
}
}
writeHtmlHeader $freeSpaceFileName

foreach ($server in Get-Content $script:list)
{
if(Test-Connection -ComputerName $server -Count 1 -ea 0) {
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 -ComputerName $server | Where-Object {$_.drivetype -eq 3 }
foreach ($item in $dp)
{
Write-Host $item.DeviceID $item.VolumeName $item.FreeSpace $item.Size
writeDiskInfo $freeSpaceFileName $item.DeviceID $item.VolumeName $item.FreeSpace $item.Size

}
}
Add-Content $freeSpaceFileName “</table>”
}

writeHtmlFooter $freeSpaceFileName
Function sendEmail
{
param($from,$to,$subject,$smtphost,$htmlFileName)
[string]$receipients=”$to”
$body = Get-Content $htmlFileName
$body = New-Object System.Net.Mail.MailMessage $from, $receipients, $subject, $body
$body.isBodyhtml = $true
$smtpServer = $MailServer
$smtp = new-object Net.Mail.SmtpClient($smtphost)
$validfrom= Validate-IsEmail $from
if($validfrom -eq $TRUE)
{
$validTo= Validate-IsEmail $to
if($validTo -eq $TRUE)
{
$smtp.Send($body)
write-output “Email Sent!!”

}
}
else
{
write-output “Invalid entries, Try again!!”
}
}

# Email our report out

function Validate-IsEmail ([string]$Email)

{

return $Email -match “^(?(“”)(“”.+?””@)|(([0-9a-zA-Z]((\.(?!\.))|[-!#\$%&'\*\+/=\?\^`\{\}\|~\w])*)(?<=[0-9a-zA-Z])@))(?(\[)(\[(\d{1,3}\.){3}\d{1,3}\])|(([0-9a-zA-Z][-\w]*[0-9a-zA-Z]\.)+[a-zA-Z]{2,6}))$”
}

$date = ( get-date ).ToString(‘yyyy/MM/dd’)

sendEmail -from $From -to $to -subject “Disk Space Report – $Date” -smtphost $SMTPMail -htmlfilename $freeSpaceFileName

}

***************************************************************

Output :-

Image

Download the code here Disk

Thanks for reading my space….

Happy Learning!!!

About these ads

About Prashanth Jayaram

I’m a Database technologist having 8+ years of rich, hands-on experience on Database technologies. I am Microsoft Certified Professional and backed with a Degree in Master of Computer Application. My expertise lies in T-SQL programming, Replication and PowerShell. hobbies are playing sports and drawing.
This entry was posted in PowerShell and tagged , , . Bookmark the permalink.

40 Responses to PowerShell – Script to Monitor Disk Space of a Group of servers – HTML Formatted Email Output

  1. manideep says:

    hi,
    i ran the powershell script sucessfully then when i am making a call to the function getting the below error.

    Get-DiskSpaceReport : The term ‘Get-DiskSpaceReport’ is not recognized as the name of a cmdlet, function, script file,
    or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and
    try again.
    At line:1 char:1

    • Hi,Can you once check the arguments that you are passing and make sure that it properly separated by space

      Example-

      Ps:\>get-disk -com abc -war 10….

      If possible, post me a function call

      -Prashanth

      • patyk says:

        I just have some basic questions for you. I am new to Power shell I have downloaded the disk file, but which directory on the server it should it go? What name it should have?
        Sorry for asking such basics…..

  2. Michael says:

    Hello Prashanth. Excellent script! I have one question – how can I edit to send email to multiple users? I have tried wrapping address with quotes, using comma and semicolon, no luck so far.

    • Modify the mail sending function of the code like below
      Function sendEmail
      {
      param($from,$to,$subject,$smtphost,$htmlFileName)
      [string]$receipients=”$to”
      $body = Get-Content $htmlFileName
      $body = New-Object System.Net.Mail.MailMessage $from, $receipients, $subject, $body
      $body.isBodyhtml = $true
      $smtpServer = $MailServer
      $smtp = new-object Net.Mail.SmtpClient($smtphost)
      $smtp.Send($body)
      }

      Do a function call

      $emlst=”pjayaram@app.com,rghi@app.com”
      Get-DiskSpaceReport -ComputerList c:\computer.txt -To $emlst -From pjayaram@app.com -SMTPMail mail01.app.com

      Let me know if you need full code to be pasted here – Prashanth

  3. sree says:

    Cool/Very useful Script….What If my environment has few Server(s) with Mount Points? Will Get-Win32LogicalDisks pull Mount points info as well?

    • Thanks Sree. Yes, DriveType =2 includes mount points.
      Get-WmiObject win32_logicaldisk | Where-Object {$_.drivetype -eq 3 -OR $_.drivetype -eq 2 } | format-table DeviceID, VolumeName,status,Size,FreeSpace..Try this.

  4. Howard says:

    Very nice! I have so many servers. I would only like to see the drives that are warning or critical.

    • Hello Howard,

      Just replace the writeDiskInfo function by a given code.

      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 -lt $warning -and $freePercent -gt $critical)
      {
      Add-Content $fileName “”
      Add-Content $fileName “$devid”
      Add-Content $fileName “$volName”
      Add-Content $fileName “$totSpace”
      Add-Content $fileName “$usedSpace”
      Add-Content $fileName “$frSpace”
      Add-Content $fileName “$freePercent”
      Add-Content $fileName “”
      }
      elseif ($freePercent -le $critical)
      {
      Add-Content $fileName “”
      Add-Content $fileName “$devid”
      Add-Content $fileName “$volName”
      Add-Content $fileName “$totSpace”
      Add-Content $fileName “$usedSpace”
      Add-Content $fileName “$frSpace”
      Add-Content $fileName “$freePercent”
      #
      Add-Content $fileName “”
      }
      <#else
      {
      Add-Content $fileName "”
      Add-Content $fileName “$devid”
      Add-Content $fileName “$volName”
      Add-Content $fileName “$totSpace”
      Add-Content $fileName “$usedSpace”
      Add-Content $fileName “$frSpace”
      Add-Content $fileName “$freePercent”
      Add-Content $fileName “”
      }#>
      }

  5. Bruce Carey says:

    Prashanth, most excellent script. I am getting access denied to Domain servers so rather than logging out and logging in with Admin account, how do I use the -Credential just once in script to give me access to the domain computers? I would supply my domain admin account of course. Thanks, Bruce

  6. Bruce Carey says:

    Prashanth, I cannot seem to get the critical freespace to come up in red even though they are less than 15% available. I am not entering anything on the PS command parameters, just taking the default values in the script. Any suggestions?

    • Hello Bruce,

      I just executed the script, It came as expected. Lets change input parameter value – Warning -> 50 and critical ->25. Let me know the output..

      I hope you are download the script and executing it.

      • Bruce Carey says:

        Thanks Prashanth, had a type-o, all fixed on this one. Did you see my other post though regarding:
        I am getting access denied to Domain servers so rather than logging out and logging in with Admin account, how do I use the -Credential just once in script to give me access to the domain computers? I would supply my domain admin account of course. Thanks, Bruce

      • Hello Bruce,

        I’m working on it…I’ll update you soon.

  7. Thank you, so much for your script!

  8. Jake says:

    Hi, this is a great report, but I can’t get it to run no matter what I try. I’ve only edited the following:
    $freeSpaceFileName = e:\scripts\diskreport\freespace.html

    I’ve tried leaving your default and no luck. I’m not sure if it’s even reading the list of servers I put in, and I’ve tried moving that to different folders. It just runs very quickly, but i get no email or anything else.

    Please Help!

  9. Jake says:

    Yes, I’m not sure if I didn’t create the function correctly, but I copied your code, saved it as get-diskspacereport.ps1 and then put int he parameters as you detailed.

  10. Jake says:

    also, thank you VERY MUCH for replying!! I read alot of blogs/forums, and I’ve been reading yours for a while. But it’s very hard to get anyone to reply when you have a question, so I really appreciate the help!

  11. Jake says:

    I’m not sure where I’m going wrong. I copied the code again, pasted into the powershell ise, no errors. I run exactly what you detailed and it goes by so quickly I have to think it’s not pulling in the list of servers. I only update the location of the temp file, but I did try to use it leaving that as the default c:\
    I thought if it’s a function you can just do exactly as I did, although you can also add this function to your posh profile standard functions? Is that correct?

  12. Jake says:

    It’s working great, thank you!

  13. Marie says:

    I am trying to change the “background color” and “font color” of the values put into the script for the drive, drive label, Total Capacity, Free Capacity, but then I wouldn’t change the %FreeSpace so that it shows up with the RED/Yellow highlight.
    I can’t figure out how to do this, can someone help me out?

    Thank you,
    Marie

    • Hello Marie,

      You need to modify writeDiskInfo code like below

      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 “”
      Add-Content $fileName “$devid”
      Add-Content $fileName “$volName”

      Add-Content $fileName “$totSpace”
      Add-Content $fileName “$usedSpace”
      Add-Content $fileName “$frSpace”
      Add-Content $fileName “$freePercent”
      Add-Content $fileName “”
      }

      –Prashanth

  14. Vinay Marihal says:

    Hi Prashant,

    Excellent piece of work and thank you so much for the script. I would like to know how I can schedule this script to run everyday and send the alert mails?

    Thanks in advance
    Vinay

    • Hi Vinay,

      1. Download the script and add the function call with required parameters in the same script file
      2. Create a batch file and call this script file
      Power.bat

      C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -file C:\DiskSpace.ps1

      3. Call the batch file using task scheduler

      -Prashanth

  15. Heinrich Kruger says:

    Hi there,
    Is there any way that you can get the output of the actual mountpoint information as well?

    • Hello Kruger,

      You can use the below function to get mount point
      related data

      function Get-MountPoint {
      param (
      [string]$computername = “localhost”
      )
      Get-WmiObject -Class Win32_MountPoint -ComputerName $computername |
      where {$_.Directory -like ‘Win32_Directory.Name=”*”‘} |
      foreach {
      $vol = $_.Volume
      Get-WmiObject -Class Win32_Volume -ComputerName $computername | where {$_.__RELPATH -eq $vol} |
      Select @{Name=”Folder”; Expression={$_.Caption}},
      @{Name=”Size (GB)”; Expression={“{0:F3}” -f $($_.Capacity / 1GB)}},
      @{Name=”Free (GB)”; Expression={“{0:F3}” -f $($_.FreeSpace / 1GB)}},
      @{Name=”%Free”; Expression={“{0:F2}” -f $(($_.FreeSpace/$_.Capacity)*100)}}|ft -AutoSize
      }
      }

      Get-MountPoint -Computername

      -Prashanth

  16. Max says:

    Hi Prashanth

    Great script, it’s working very well for my servers. but for some reason, it can’t not retrieve disk information from any Windows 7 systems.

    Thanks

  17. Srinivas says:

    Hi Prasanth,

    Its a cool Script Not sure whether people noticed this wheni executed the script, it runs fine bt the issue is with some table alignment when i access the email thorugh outlook client.

  18. rasheed says:

    Hi am trying to run this the batch script but i am not getting the htm file generated or any mails.
    C:\WINDOWS\system32\WindowsPowerShell\v1.0\PowerShell.exe -Command “”

    Is there a way to just generate the report as htm file

  19. Howdy! We possjbly could have sworn I’ve gone to your blog before but after lookiung at some of the articles I
    realized it’s fresh to me. Anyhow, I’m definitely pleased
    I found it and I’ll be book-marking iit
    and checking back frequently!

  20. Hi Prashanth
    the script works great! Now I have an SMTP server that requires authentication, could you help me enabling authentication in the script?

    Thanks in advance!

  21. Preethi says:

    Hi,
    Script is really good . But all content looks cornered , Need to align them to center .

    New to PS scripting . Please help .

    • Hi Preethi,

      Replace the WriteDiskInfo function with the below code

      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 “”
      Add-Content $fileName “$devid”
      Add-Content $fileName “$volName”

      Add-Content $fileName “$totSpace”
      Add-Content $fileName “$usedSpace”
      Add-Content $fileName “$frSpace”
      Add-Content $fileName “$freePercent”
      Add-Content $fileName “”
      }
      elseif ($freePercent -le $critical)
      {
      Add-Content $fileName “”
      Add-Content $fileName “$devid”
      Add-Content $fileName “$volName”
      Add-Content $fileName “$totSpace”
      Add-Content $fileName “$usedSpace”
      Add-Content $fileName “$frSpace”
      Add-Content $fileName “$freePercent”
      #
      Add-Content $fileName “”
      }
      else
      {
      Add-Content $fileName “”
      Add-Content $fileName “$devid”
      Add-Content $fileName “$volName”
      Add-Content $fileName “$totSpace”
      Add-Content $fileName “$usedSpace”
      Add-Content $fileName “$frSpace”
      Add-Content $fileName “$freePercent”
      # #FBB917
      Add-Content $fileName “”
      }
      }

      –Prashanth

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s