Setting Specific Thresholds on Specific Drives

by w00tm3 at 2013-02-12 13:04:38

Hello. I found a PowerShell script online that does a really nice report for drive drives from an input file. In the future I will make it query all servers using Get-QADComputer -sizelimit 0 -OSName 'server' -LdapFilter '(!(userAccountControl] but for now it uses an input txt file. What I don’t have a clue about how to do though is set specific thresholds or exclusions on specific drives. For example, we have some servers that we know have a drive at 99% utilization but its okay because the data is static. Another drive might be a SQL drive in which the DB is expanded or whatever and we want to exclude that specific drive on that specific server from monitoring.

I would like to have the script read from a text file to get these exclusions. For example maybe the file could have something like the following:
Server1,D,0 (which would mean don’t monitor drive D at all)
Server2,E,3 (which would mean only alert at 3% and not the standard set in the script)
Server3 (Don’t get drive utilization for any drives on Server3)

Would anyone know how to do this? Thanks!


#
Continue even if there are errors
$ErrorActionPreference = "Continue";

#########################################################################################
#
# EMAIL PROPERTIES
# - the $users that this report will be sent to.
# - near the end of the script the smtpserver, From and Subject.

# REPORT PROPERTIES
# - you can edit the report path and report name of the html file that is the report.
#########################################################################################

# Set your warning and critical thresholds
$percentWarning = 15;
$percentCritcal = 10;

# EMAIL PROPERTIES
# Set the recipients of the report.
$users = "testy@company.com"
#$users = "You@company.com" # I use this for testing by using my email address.
#$users = "you@company.com", "manager@company.com", "etc@company.com"; # can be sent to individuals.


# REPORT PROPERTIES
# Path to the report
$reportPath = "C:\TempDriveSpace";

# Report name
$reportName = "DiskSpaceRpt_$(get-date -format ddMMyyyy).html";

# Path and Report name together
$diskReport = $reportPath + $reportName

#Set colors for table cell backgrounds
$redColor = "#FF0000"
$orangeColor = "#FBB917"
$whiteColor = "#FFFFFF"

# Count if any computers have low disk space. Do not send report if less than 1.
$i = 0;

# Get computer list to check disk space
$computers = Get-Content "servers_c.txt";
$datetime = Get-Date -Format "MM-dd-yyyy_HHmmss";

# Remove the report if it has already been run today so it does not append to the existing report
If (Test-Path $diskReport)
{
Remove-Item $diskReport
}

# Cleanup old files…
$Daysback = "-7"
$CurrentDate = Get-Date;
$DateToDelete = $CurrentDate.AddDays($Daysback);
Get-ChildItem $reportPath | Where-Object { $.LastWriteTime -lt $DatetoDelete } | Remove-Item;

# Create and write HTML Header of report
$titleDate = get-date -uformat "%m-%d-%Y - %A"
$header = "
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>
<title>DiskSpace Report</title>
<STYLE TYPE='text/css'>
<!–
td {
font-family: Tahoma;
font-size: 11px;
border-top: 1px solid #999999;
border-right: 1px solid #999999;
border-bottom: 1px solid #999999;
border-left: 1px solid #999999;
padding-top: 0px;
padding-right: 0px;
padding-bottom: 0px;
padding-left: 0px;
}
body {
margin-left: 5px;
margin-top: 5px;
margin-right: 0px;
margin-bottom: 10px;
table {
border: thin solid #000000;
}
–>
</style>
</head>
<body>
<table width='100%'>
<tr bgcolor='#CCCCCC'>
<td colspan='7' height='25' align='center'>
<font face='tahoma' color='#003399' size='4'><strong>DiskSpace Report for $titledate</strong></font>
</td>
</tr>
</table>
"
Add-Content $diskReport $header

# Create and write Table header for report
$tableHeader = "
<table width='100%'><tbody>
<tr bgcolor=#CCCCCC>
<td width='10%' align='center'>Server</td>
<td width='5%' align='center'>Drive</td>
<td width='15%' align='center'>Drive Label</td>
<td width='10%' align='center'>Total Capacity(GB)</td>
<td width='10%' align='center'>Used Capacity(GB)</td>
<td width='10%' align='center'>Free Space(GB)</td>
<td width='5%' align='center'>Freespace %</td>
</tr>
"
Add-Content $diskReport $tableHeader

# Start processing disk space reports against a list of servers
foreach($computer in $computers)
{
$disks = Get-WmiObject -ComputerName $computer -Class Win32_LogicalDisk -Filter "DriveType = 3"
$computer = $computer.toupper()
foreach($disk in $disks)
{
$deviceID = $disk.DeviceID;
$volName = $disk.VolumeName;
[float]$size = $disk.Size;
[float]$freespace = $disk.FreeSpace;
$percentFree = [Math]::Round(($freespace / $size) * 100, 2);
$sizeGB = [Math]::Round($size / 1073741824, 2);
$freeSpaceGB = [Math]::Round($freespace / 1073741824, 2);
$usedSpaceGB = $sizeGB - $freeSpaceGB;
$color = $whiteColor;

# Set background color to Orange if just a warning
if($percentFree -lt $percentWarning)
{
$color = $orangeColor

# Set background color to Orange if space is Critical
if($percentFree -lt $percentCritcal)
{
$color = $redColor
}

# Create table data rows
$dataRow = "
<tr>
<td width='10%'>$computer</td>
<td width='5%' align='center'>$deviceID</td>
<td width='15%' >$volName</td>
<td width='10%' align='center'>$sizeGB</td>
<td width='10%' align='center'>$usedSpaceGB</td>
<td width='10%' align='center'>$freeSpaceGB</td>
<td width='5%' bgcolor=&#39;$color' align='center'>$percentFree</td>
</tr>
"
Add-Content $diskReport $dataRow;
Write-Host -ForegroundColor DarkYellow "$computer $deviceID percentage free space = $percentFree";
$i++
}
}
}

# Create table at end of report showing legend of colors for the critical and warning
$tableDescription = "
</table><br><table width='20%'>
<tr bgcolor='White'>
<td width='10%' align='center' bgcolor='#FBB917'>Warning less than 15% free space</td>
<td width='10%' align='center' bgcolor='#FF0000'>Critical less than 10% free space</td>
</tr>
"
Add-Content $diskReport $tableDescription
Add-Content $diskReport "</body></html>"

# Send Notification if alert $i is greater then 0
if ($i -gt 0)
{
foreach ($user in $users)
{
Write-Host "Sending Email notification to $user"

$smtpServer = "mail.company.com"
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$msg = New-Object Net.Mail.MailMessage
$msg.To.Add($user)
$msg.From = "notification@hbk.com"
$msg.Subject = "DiskSpace Report for $titledate"
$msg.IsBodyHTML = $true
$msg.Body = get-content $diskReport
$smtp.Send($msg)
$body = ""
}
}
by AlexBrassington at 2013-02-13 04:44:49
So what you want to do is to read in a csv file and then test to see if the disk has any special handling rules, then modify the behaviour as required.

Try this. Note that i haven’t tested it, I need to grab lunch.
#To import the CSV
#Path to the Special Handling rules csv file
$csvPath = ""
#get array of disks and special handling rules
$specialHandlingRules = Import-Csv $csvPath


#To be inserted in the for-each disk loop
#Check for special handling instructions for this server and disk
$specialRules = $specialHandlingRules | where {$
.Server -eq $computer -and $_.Disk -eq $disk.DeviceID}
#set a flag for wether the disk should be ignored for warnings or not.
$ignoreWarnings = $false
#if there are any special rules for this, adjust prameters for it
if ($specialRules.Count -gt 0)
{
# just in case you want multiple rules to be applicable to each disk.
foreach ($rule in $specialRules)
{
switch ($rule.Type)
{
0 {
#Set the $percentwarning to 0, supressing the warning.
$percentWarning = 0
}
2 {
#Set flag to ignore all errors
$ignoreWarnings = $false
}
}
}
}

#to replace your current $i++ line
if (!$ignoreWarnings)
{
$i++
}


It’s not the most efficient way to process things but it should work.

You could make life a lot easier by using the ConvertTo-HTML commandlet, possibly mixing it in with Don’s creating HTML reports using powershell tricks. Also think about seperating the code out into functions. Long scripts like this are a lot easier to develop but a pain to maintain and a royal pain to debug. Putting in functions early makes testing and, over time, development a lot easier.