Wednesday, April 11, 2012

Checking Server Disk Space

PROBLEM: You have a large network of computers, you want to know when they are getting low on space since that can cause many issues such as websites running slowly or not at all, logs might not get written, defragging can't occur, windows updates can't be applied etc. So you want to monitor them constantly but don't want to waste time doing it.
SOLUTION: I'm sure there are products out there (free and paid for) to do this but my solution was to go the DIY path and use PowerShell and two Windows Scheduled Tasks (one daily that will email any warnings and one weekly that will email regardless). I have zero PowerShell experience but have borrowed liberally from a few fellows (attributions in the script). I'll give you the code and then raise a few points about it:


##############  Script starts Here ##########

# This script is designed to loop through a list of servers in an external file and check the
# space on each drive associated with each server, report on their free disk space percentage
# and output the results to the screen (if run in a console), and an email (which will only get
# sent if the parameter of WarningsOnly is passed when executing the script
# e.g. C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe -command "C:\ServerDiskSpaceChecker\ServerDiskSpaceChecker.ps1 WarningsOnly").
#
# Acknowledgements:
# DISK SPACE PORTION OF THE SCRIPT TAKEN AND MODIFIED FROM: http://www.youdidwhatwithtsql.com/check-disk-space-with-powershell-2/195
# EMAIL PORTION OF THE SCRIPT TAKEN AND MODIFIED FROM: http://www.techrepublic.com/blog/window-on-windows/send-an-email-with-an-attachment-using-powershell/4969
# EMAIL HTML FORMATTING PORTION OF THE SCRIPT TAKEN AND MODIFIED FROM: http://exchangeserverpro.com/powershell-send-html-email
# SCHEDULING PROCESS (no code required but good to know) TAKEN FROM: http://dmitrysotnikov.wordpress.com/2011/02/03/how-to-schedule-a-powershell-script/



# MODIFY THE BELOW VARIABLES AS REQUIRED

# Issue warning if % free disk space is less
$percentWarning = 15;

# Get server list (text file containing server names)
$servers = Get-Content "C:\ServerDiskSpaceChecker\computers.txt";

# IP address of email server
$smtpServer = "10.10.0.999"

# Email address to send notifications to
$emailTo = "ITTeam@yourcompanyhere.com.au"



# LET'S CHECK SOME DISKS!

$warningsExist = $false;
$scriptParameter = $args[0];
$msgSubject = "Server Disk Space Checker Results";
$datetime = Get-Date -Format "yyyyMMddHHmmss";

# variable for storing body of email (formatted in html so that we can use pretty colours)
$emailBody = "<p>The following are the results of an automated check of remaining server disk space (Refer to the <a href='http://yourwikiurlhere'>wiki</a> for more information). Entries will be marked in red if they fall below the current threshold - please investigate these ASAP.<p>";

# Add headers to log file
Add-Content "$Env:USERPROFILE\server disks $datetime.txt" "server,deviceID,size,freespace,percentFree";

foreach($server in $servers)
{
# Get fixed drive info
$disks = Get-WmiObject -ComputerName $server -Class Win32_LogicalDisk -Filter "DriveType = 3";

foreach($disk in $disks)
{
$deviceID = $disk.DeviceID;
[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);

$colour = "Green";
if($percentFree -lt $percentWarning)
{
$colour = "Red";
$warningsExist = $true;
}

# Get results
$results = "$server $deviceID percentage free space = $percentFree% (Total Size=$sizeGB GB, Total Free=$freeSpaceGB GB)"

# Write results to email
$emailBody = $emailBody + "<span style='color:$colour'>$results</span><br />"

# Write results to screen
Write-Host -ForegroundColor $colour $results;
}
}



# Send an email with the details

if(($warningsExist -eq $true) -or ($scriptParameter -ne "WarningsOnly"))
{
Add-PSSnapin Microsoft.Exchange.Management.Powershell.Admin -erroraction silentlyContinue;

$msg = new-object Net.Mail.MailMessage;
$smtp = new-object Net.Mail.SmtpClient($smtpServer);
$msg.From = "system@yourcompanynamehere.com.au";
$msg.To.Add($emailTo);
if($warningsExist -eq $true)
{
$msgSubject = "Warnings Exist - " + $msgSubject;
}
$msg.Subject = $msgSubject;
$msg.IsBodyHTML = $true;
$msg.Body = $emailBody;
$smtp.Send($msg);
}


############## End of Script ##########

To enable the PowerShell script to run permissions needed to be changed on the server to allow local scripts to run ok (but external scripts require signing) - run this command in PowerShell:

  • Set-ExecutionPolicy RemoteSigned
There are a number of variables within the script that can be modified:
  • $percentWarning (Issue warning if % free disk space is less)
  • $servers (text file containing server names))
  • $smtpServer (IP address of email server)
  • $emailTo (Email address to send notifications to)
To specify which servers to check, create a file (e.g. computers.txt) and simply have a list of server names, one on each row, no empty rows at the end, and ensure the $servers variable uses that file.

When executing the script, if you want it to only email you when there is a warning then pass the parameter "WarningsOnly" after the script name (provide any other value if you want to always be notified) e.g. C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe -command "C:\Server Disk Space Checker\ServerDiskSpaceChecker.ps1 WarningsOnly"

To troubleshoot run the script/scheduled task manually - if you include the -NoExit flag when running the script it will not close the PowerShell window when it's done so you can see any errors etc that may have occurred.
    Common problems include:
    • Incorrect server name in computers.txt
    • Blank lines in computers.txt
    • Incorrect script permissions (refer above)
    • NaN% in the email (this means the script has had a problem reading the disk space - NaN stands for Not a Number - add the -NoExit flag and see what's happening).
    This script is basically a Frankenstein compliation of a few different scripts (refer to the URL references within the script itself) - I'm definitely no PowerShell expert, but it seems to do a good job when combined with the schedule task and parameters. (apologies for the blog formatting - I'm really not a big fan of the Blogger formatting!).

    No comments:

    Post a Comment