Project Objective:
Monitor available volume space with single script that can be deployed in a multiple scenarios.

Problem to be solved:
Running out of disk space on a server is not fun and users noticing before you do is even less fun, but Nagios and or NRPE isn’t always deployed in every environment. This script is an effort to bridge the gap between central and local monitoring.

Future Versions:
I’d like to add the SMTP auth ability as well as Event Log entries.

Notes:
v1.5 contains suggested edits from Stephen Mills and bug fix.

#
# Test-Volume-Space.ps1
#
# Written by Aaron Wurthmann (aaron (AT) wurthmann (DOT) com)
#
# If you edit please keep my name as an original author and
# keep me apprised of the changes, see email address above.
# This code may not be used for commercial purposes.
# You the executor, runner, user accept all liability.
# This code comes with ABSOLUTELY NO WARRANTY.
# You may redistribute copies of the code under the terms of the GPL v2.
# -----------------------------------------------------------------------
# 2011.05.12 ver 1.5
#
# Summary:
# Checks for disk percent usage on all Windows partitions/logical disks.
# Can be configured to send an email in non-Nagios environments. 
# -----------------------------------------------------------------------
# General Usage:
#    This script can be edited and or parameters can be passed to enable
#    email alerts, to whom, from whom, using what server, etc.
#     Examples:    
#        .\Test-Volume-Space.ps1 -WarningLevel 70
#        .\Test-Volume-Space.ps1 -email True -From foobar@null.local -To administrator@null.local -Server smtp.null.local
#
# Scheduled Task Usage
#    To run this script as a scheduled task create a .bat .cmd file
#    As indicated above you can either pass the needed parameters or
#    edit Test-Volume-Space.ps1 itself. 
#    Example of .bat or .cmd file:
#        powershell -command "& '.\Test-Volume-Space.ps1' -email True -From foobar@null.local -To administrator@null.local -Server smtp.null.local"
#
# Nagios Usage:
#    For Nagios NRPE/NSClient++ usage add the following line to the 
#    NSC.ini file after placing this script in Scripts subdirectory.
#    check_services=cmd /c echo scripts\Test-Volume-Space.ps1; exit($lastexitcode) | powershell.exe -command -
#    NOTE: The trailing - is required.
# -----------------------------------------------------------------------
# Notes:
#    At the moment there is no error detection built in for the email send.
#    There is also no smpt auth. I'll put that in at a later time.
#
#     Lines with ### are from previous version of script where "Win32_LogicalDisk"
#    was used instead of "Win32_Volume". The latter captures disks
#    mounted as folders. Thank you "Stephen Mills" for your insight.
#    
#    In addition to Stephen Mills' suggestions this version properly
#    handles the event where one drive is hitting the warning level and 
#    another is hitting the critical level. I knew there was a reason 
#    I wanted to leave that logic in from my vbscript.
# -----------------------------------------------------------------------

# Parameters and Editable Settings
Param(
    [int]$WarningLevel = 80,
    [int]$CriticalLevel = 90,
    [string]$From = 'noreply@domain.ext',
    [string]$To = 'someone@domain.ext',
    [string]$Server = 'smtp.domain.ext',
    $email=$false
)

# Volume Names to Ignore
$Ignore=@(
    'Backups',
    'Recovery',
    'Reserved';
)

# Static Parameters
[int]$ResultWarning = 0
[int]$ResultError = 0
[string]$CriticalResults = ''
[string]$WarningResults = ''
[string]$Results = ''
[string]$computername=$env:computername 


# Get local disks that are not in the ignore list
$Volumes=Get-WMIObject Win32_Volume -filter "DriveType=3"  | where {$Ignore -notcontains $_.Label}
###$Volumes=Get-WMIObject Win32_LogicalDisk -filter "DriveType=3" | where {$Ignore -notcontains $_.VolumeName}

if ($Volumes) {
    ForEach ($Volume in $Volumes) {
        ###[string]$DeviceID=$Volume.DeviceID
        [string]$Name=$Volume.Name
        [int]$FreeGBs=$Volume.FreeSpace/1073741824
        ###[int]$SizeGBs=$Volume.Size/1073741824
        [int]$SizeGBs=$Volume.Capacity/1073741824
        [int]$UsedGBs=$SizeGBs-$FreeGBs
        [int]$PerUsed=$UsedGBs/$SizeGBs*100
        ###[string]$VolumeInfo = $DeviceID + " Used " + $PerUsed + " GB of " + $SizeGBs + " GB"
        [string]$VolumeInfo = $Name + " Used " + $PerUsed + " GB of " + $SizeGBs + " GB"
        
        if ($PerUsed -gt $CriticalLevel) {
            $ResultError=2
            if ($CriticalResults) {
                $CriticalResults=$VolumeInfo + " and " + $CriticalResults
            }
            ELSE {
                $CriticalResults = $VolumeInfo + " exceeding the Critical Level of " + $CriticalLevel +"% used on " + $computername
            }
        }
        ELSE {
            if ($PerUsed -gt $WarningLevel) {
                $ResultWarning=1
                if ($WarningResults) {
                    $WarningResults=$VolumeInfo + " and " + $WarningResults
                }
                ELSE {
                    $WarningResults = $VolumeInfo + " exceeding the Warning Level of " + $WarningLevel +"% used on " + $computername
                }
            }
        }
        if ($AllVolumeInfo) {
            $AllVolumeInfo=$VolumeInfo + ", " + $AllVolumeInfo
        }
        ELSE {
            [string]$AllVolumeInfo=$VolumeInfo
        }
    }
}

if ($email) {
    $msg = new-object Net.Mail.MailMessage
    $smtp = new-object Net.Mail.SmtpClient($Server)
    $msg.From = $From
    $msg.To.Add($To)
}


[int]$ResultTotal=$ResultWarning + $ResultError
$Results=$CriticalResults + " " + $WarningResults

Switch ($ResultTotal) {
    default {
        write-host 'All drive usage is healthy. Drive(s) checked:' $AllVolumeInfo
        exit 0
    }

    1 {
        write-host $Results
        if ($email) {
            $msg.Subject = 'WARNING: Hard Drive Usage Has Reached Warning Level on ' + $computername
            $msg.Body = $Results
            $smtp.Send($msg)
        }
        exit 1
    }

    2 {
        write-host $Results
        if ($email) {
            $msg.Subject = 'CRITICAL: Hard Drive Usage Has Reached Critical Level on ' + $computername
            $msg.Body = $Results
            $smtp.Send($msg)
        }
        exit 2
    } 

    3 {
        write-host $Results
        if ($email) {
            $msg.Subject = 'CRITICAL: Multiple Hard Drives Have Reached Critical or Warning Levels'
            $msg.Body = $Results
            $smtp.Send($msg)
        }
        exit 2
    } 
}