RunningLow - PowerShell script to check for disk space and send e-mail A free PowerShell script that will check for low disk space on local and/or network drives and servers and send e-mail to System Administrators

Event Viewer: come inviare notifiche e-mail dal Registro Eventi con uno script Powershell

Today I would like to share with our readers RunningLow, a simple yet effective PowerShell script I coded a while ago to get to know when one of my servers is running low of disk space.

Whoever works with physical and/or virtualized Windows Servers is well aware of the importance of keeping this constantly under control: as soon as a server runs out of disk space it will be unable to fullfill a number of tasks, such as: create temporary files, store data on a database, performing system maintenance / backup / updates, create or update web sessions - assuming they are handled through I/O - and so on. Things can be even worse for those servers who host DBMS services such as MySQL and MS-SQL, as the sudden I/O unavailability could cause non-trivial damages to indexes, filesystem-based tables and data integrity.

The main purpose of RunningLow is to prevent all that: it will check one or more local and/or network drives to see if their available free space went under a certain quota, and send a customizable alert to one or more e-mail addresses if that's the case. I know, there are A LOT of admin suites and maintenance software that could be easily configured to the same thing: even Piriform's CCleaner PRO does that! However, if you don't have the money, the time or the amount of system resources required to install these apps, you might find out that this lightweight alternative could be worth a shot.

UPDATE: RunningLow 1.1 (and later) added support for network drives and a whole set of CLI configuration parameters: be sure to check it out!

Source Code

Anyway, here's the script source code:

Copy/paste it into a text file, save it to RunningLow.ps1 (or any other name) and you should be set. Alternatively, you can also download the latest version from the project's official GitHub repo.

Configuration

The first ten or so lines host the configuration settings, which you should change accordingly to your needs and depending to your specific scenario. The most important thing to understand is the first line: as we can see, we can either specify an array of drives - including network drives, as long as they're permanently mapped to a local drive letter - or set a null value: if we go for the latter, the script will check all local drives.

The comments should be enough to guide you through this required part: however, if you need further assistance, you can use the comment section of this post to submit your query and I'll do my best to help you with that.

Testing

As soon as you're done with the configuration, you can test the script from the standard Windows Command Prompt with the following command:

... Or by typing

.\RunningLow.ps1

from a PowerShell prompt.

As soon as you hit ENTER, you should see something like this:

RunningLow - PowerShell script to check for disk space and send e-mail

... Meaning that everything went ok.

Sending E-Mail Alerts

Needless to say, you should then edit the script, raise the $minSize value to a ridiculously high amount (such as 5TB) and run another test to ensure that the e-mail alerts will actually be sent:

RunningLow - PowerShell script to check for disk space and send e-mail

... That's it.

Installing

It goes without saying that the script should not be launched manually: the best thing we can do to ensure that it will be executed on regular basis is to create an appropriate entry in the Windows Task Scheduler. In the example below, RunningLow will be executed once a day at noon:

RunningLow - PowerShell script to check for disk space and send e-mail

In the New Action window you can either insert the full execution statement (including parameters) in the Program/script textbox, or use the Add arguments (optional) textbox: the script will work either way. Similarly, you can specify the full path of the  RunningLow.ps1 file within the -File parameter or put it into the Start in (optional) textbox, just like we did in the above screenshot.

IMPORTANT: In the scheduled task General tab, be sure to activate the options Run whether the user is logged on or not and Run with highest priviledges, otherwise the script would run only if there's a logged-in user during the execution time.

Be sure to test it again - by setting an insanely high $minSize - on the server as well, to be sure that there are no firewalls or other restrictions that would block the e-mail alerts.

Well, that's it for now: I sincerely hope that you will enjoy having RunningLow on your servers just like I do!

Useful Links

Fork me on GitHub

 

About Ryan

IT Project Manager, Web Interface Architect and Lead Developer for many high-traffic web sites & services hosted in Italy and Europe. Since 2010 it's also a lead designer for many App and games for Android, iOS and Windows Phone mobile devices for a number of italian companies. Microsoft MVP for Development Technologies since 2018.

View all posts by Ryan

37 Comments on “RunningLow - PowerShell script to check for disk space and send e-mail A free PowerShell script that will check for low disk space on local and/or network drives and servers and send e-mail to System Administrators

    1. use this to convert to MB:
      [math]::round($disk.Used/1MB,2)

      2 is number of decimal

      Replace MB with KB, GB, or TB if you’re trying to convert other units

    2. I would just do this:

      ($disk.Free/1MB).ToString(".00") + " GB"
      

      Anyway, the new version already does the conversion either in the CLI screen and in the alert e-mail.

  1. Hi Ryan,

    just wanted to give you a shout to say thanks. Very useful and concise. I personally did away with the email notification, and simply initiated a recursive delete of a folder I know has an ever growing set of files in it over time.

    Remove-Item -Recurse -Force $directory_path_to_delete
  2. Hello Guys,
    How can I do, that this script check to other servers too. For example reads a computer lost from txt file.
    Thank you very much your help!
    :)

    1. Hi there,
      we just published the new version on GitHub with some new features, including the LAN/network support through hostname or IP address (see the -hosts parameter): be sure to check it out!

  3. I Am getting this error-pls help on this
    Exception calling “Send” with “1” argument(s): “Failure sending mail.”
    At E:\writable\OneDrive\Desktop\Test\RunningLow-master\RunningLow.ps1:74 char:9
    + $smtp.send($message);
    + ~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SmtpException

    1. Hello there,
      check your powershell version by executing the following line from a command-line:

      > powershell $PSversionTable

      Tell me which version you’re running: you could have to upgrade it.

      Here’s the SmtpClient namespace docs: as you can see, the .Send() method can accept a single parameter.
      https://docs.microsoft.com/it-it/dotnet/api/system.net.mail.smtpclient?view=netframework-4.7.2

  4. -noNewLine : The term ‘-noNewLine’ 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 C:\Users\dparmar\Desktop\Test.ps1:104 char:48
    + Write-Host(“: sending e-mail…”); -noNewLine
    + ~~~~~~~~~~
    + CategoryInfo : ObjectNotFound: (-noNewLine:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

    we are getting this error

    1. Maybe you’re using PowerShell v4 or lower: either upgrade your PS to v5+ or just remove that attribute (or use the -join attribute).

  5. Brilliant script. Would it be possible to tweak this so that the e-mail is sent if the free space is lower than certain percentage rather than free disk space in GB?

    1. Sure, why not?

      Here’s how you calculate the $y% of $x:

      $x = 100
      $y = 25
      $result = $x * ($y / 100)
      

      Therefore, instead of doing this:

      ($disk.Size -lt $minSize)
      

      do this:

      ($disk.Size -lt ($y *($disk.FreeSpace/100))
      

      Where $y is the min free percentage you want to check.

  6. Hi I am getting below error.
    PS E:\New folder> powershell -executionpolicy bypass -File RunningLow.ps1

    Checking drive E …
    Drive E has less than 64424509440 bytes free (53689225216): sending e-mail…
    Exception calling “Send” with “1” argument(s): “Failure sending mail.”
    At E:\New folder\RunningLow.ps1:74 char:9
    + $smtp.send($message);
    + ~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SmtpException

    … E-Mail sent!

    Checking drive C …
    Drive C has less than 64424509440 bytes free (33066172416): sending e-mail…
    Exception calling “Send” with “1” argument(s): “Failure sending mail.”
    At E:\New folder\RunningLow.ps1:74 char:9
    + $smtp.send($message);
    + ~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SmtpException

    … E-Mail sent!

    1. Try to replace this:


      $smtp.send($message);
      $message.Dispose();
      Write-Host " E-Mail sent!" ;

      with this:

      try
      {
      $smtp.send($message);
      Write-Host " E-Mail sent!" ;
      }
      catch
      {
      Write-Host " Error sending E-Mail:" ;
      Write-Host $_.Exception.Message
      }
      $message.Dispose();

      So that you can see what the actual problem is.

      NOTE: GitHub version (1.1.1) already implements this, you can just get it there.

      1. Hi Ryan,
        I am getting this error:

        Checking drive C …
        Drive C has less than 214748364800 bytes free (155964452864): sending e-mail…
        Error sending E-Mail:
        Exception calling “Send” with “1” argument(s): “Failure sending mail.”

        Checking drive E …
        Drive E has more than 214748364800 bytes free: nothing to do.

        Checking drive G …
        Drive G has more than 214748364800 bytes free: nothing to do.

        Could you please help me on this ?
        Ps: I am using PowerShell version: 5.1.17763.1007
        Thanks!

    1. Sure, check this out:

      https://stackoverflow.com/questions/12698548/powershell-script-to-generate-alert-on-memory-and-cpu-usage

      However, if you want to receive many alerts for various different scenarios, you might want to consider to use a dedicated monitoring tool (for a single PC or the whole IT Infrastructure) such as Nagios and the likes.

  7. Hello,
    I am getting this error:

    PS C:\Users\Administrator> C:\Users\Administrator\Desktop\RunningLow.ps1

    Checking drive C …
    Drive C has less than 214748364800 bytes free (156002455552): sending e-mail…
    Error sending E-Mail:
    Exception calling “Send” with “1” argument(s): “Failure sending mail.”

    Checking drive E …
    Drive E has more than 214748364800 bytes free: nothing to do.

    Checking drive G …
    Drive G has more than 214748364800 bytes free: nothing to do.

    I am using poweshell version 5.1.
    Please help me check on this.

  8. Hi,
    I am getting this error:

    PS C:\Users\Administrator> C:\Users\Administrator\Desktop\RunningLow.ps1

    Checking drive C …
    Drive C has less than 214748364800 bytes free (155998789632): sending e-mail…
    Error sending E-Mail:
    Exception calling “Send” with “1” argument(s): “Failure sending mail.”

    Checking drive E …
    Drive E has more than 214748364800 bytes free: nothing to do.

    Checking drive G …
    Drive G has more than 214748364800 bytes free: nothing to do.

    I am using Powershell version 5.1
    Could you please help me check on this ?
    Thanks!

  9. Hi Ryan,
    I am not able to send the email through above script. below are configurations . do you think there is some issue with configuration.

    SMTP configuration: username, password & so on

    $email_username = “[email protected]”;
    $email_password = “Newuser15”;
    $email_smtp_host = “smtp.teoco.com”;
    $email_smtp_port = 25;
    $email_smtp_SSL = 0;
    $email_from_address = “[email protected]”;
    $email_to_addressArray = @(“[email protected]”, “[email protected]”, “[email protected]”);

    ——————-i am getting below error——————–

    Checking drive C …
    Drive C has less than 5497558138880 bytes free (36414402560): sending e-mail…
    Exception calling “Send” with “1” argument(s): “The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.57 SMTP;
    Client was not authenticated to send anonymous mail during MAIL FROM [MA1PR01CA0089.INDPRD01.PROD.OUTLOOK.COM]”
    At D:\RunningLow.ps1:74 char:9
    + $smtp.send($message);
    + ~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SmtpException

  10. Hi Ryan,

    i am getting error while sending email. i guess i am doing some mistake on configuration. Appreciate your help.

    Below is configuration–

    SMTP configuration: username, password & so on

    $email_username = “[email protected]”;
    $email_password = “XYZ”;
    $email_smtp_host = “smtp.outlook.com”;
    $email_smtp_port = 25;
    $email_smtp_SSL = 0;
    $email_from_address = “[email protected]”;
    $email_to_addressArray = @(“[email protected]”, “[email protected]”, “[email protected]”);

    —————Error————————-

    Checking drive C …
    Drive C has less than 5497558138880 bytes free (36164149248): sending e-mail…
    Exception calling “Send” with “1” argument(s): “The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.57 SMTP;
    Client was not authenticated to send anonymous mail during MAIL FROM [MA1PR0101CA0036.INDPRD01.PROD.OUTLOOK.COM]”
    At D:\RunningLow.ps1:74 char:9
    + $smtp.send($message);
    + ~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SmtpException

    … E-Mail sent!

  11. Good morning, the first thing is to thank you for this wonderful work. I’m going to deploy it to a couple of servers. Do you have any that are similar to check cpu load and ram memory consumption? It would be very good. And if everything was in a script, it’d be amazing.

    On the other hand, your script has a small flaw. When you check the network disk space to servers by wmi, the server reports the error well, but the report shows the name of the server where it runs and not where it has the problem. The same goes for ips.

    Thanks !!

  12. hi I am getting this error and i am using following smtp settings for gmail
    $email_smtp_host = “smtp.gmail.com”;
    $email_smtp_port = 587;
    $email_smtp_SSL = 1;

    Checking drive C …
    Drive C has less than 322122547200 bytes free (187064115200): sending e-mail…
    Exception calling “Send” with “1” argument(s): “The SMTP server requires a secure connection or the client was not
    authenticated. The server response was: 5.7.0 Authentication Required. Learn more at”
    At C:\Powershell\Test Email Sent.ps1:74 char:1
    + $smtp.send($message);
    + ~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SmtpException

    E-Mail sent!

    Checking drive D …
    Drive D has less than 322122547200 bytes free (313644326912): sending e-mail…
    Exception calling “Send” with “1” argument(s): “The SMTP server requires a secure connection or the client was not
    authenticated. The server response was: 5.7.0 Authentication Required. Learn more at”
    At C:\Powershell\Test Email Sent.ps1:74 char:1
    + $smtp.send($message);
    + ~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SmtpException

    E-Mail sent!

  13. please help me I am getting following error.I am trying to forward mail to gmail.it did work fine with outlook.I am using port 587 for smtp and set $email_smtp_SSL = 1;

    Exception calling “Send” with “1” argument(s): “The SMTP server requires a secure connection or the client
    was not authenticated. The server response was: 5.7.0 Authentication Required. Learn more at”
    At C:\Powershell\Test Email Sent.ps1:74 char:1
    + $smtp.send($message);
    + ~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SmtpException

  14. hello please Give me a script with percentage parameter for sending mail instead of using $minsize parameter.i have already saw above comment where $x = 100
    $y = 25
    $result = $x * ($y / 100)
    Is given .I had then made changes in my script still I am not able to send email when disk space is less than 10 % of disk space.I have change parameters of email for sending this comment.please check it below and suggest me a solution

    Drives to check: set to $null or empty to check all local (non-network) drives

    $drives = @(“C”,”D”);

    $drives = @(“C”,”D”);

    The minimum disk size to check for raising the warning

    SMTP configuration: username, password & so on

    $email_username = “demo email”;
    $email_password = “demo password “;
    $email_smtp_host = “smtp.gmail.com”;
    $email_smtp_port = 587;
    $email_smtp_SSL = 1;
    $email_from_address = “demo email”;
    $email_to_addressArray = @(“demo email”);

    if ($drives -eq $null -Or $drives -lt 1) {
    $localVolumes = Get-WMIObject win32_volume;
    $drives = @();
    foreach ($vol in $localVolumes) {
    if ($vol.DriveType -eq 3 -And $vol.DriveLetter -ne $null ) {
    $drives += $vol.DriveLetter[0];
    }
    }
    }
    foreach ($d in $drives) {
    Write-Host (“rn”);
    Write-Host (“Checking drive ” + $d + ” …”);
    $disk = Get-PSDrive $d;
    $x = 100;
    $y = 10;
    $result = $x * ($y / 100);
    if (($disk.Size -lt ($y *($disk.FreeSpace/100)))){
    Write-Host (“Drive ” + $d + ” has less than ” + $result `
    + ” bytes free (” + $disk.Free + ” bytes – ” + ($disk.Free/1MB).ToString(“.00″) + ” GB)”);

        $message = new-object Net.Mail.MailMessage;
        $message.From = $email_from_address;
        foreach ($to in $email_to_addressArray) {
            $message.To.Add($to);
        }
        $message.Subject =  ("[RunningLow] WARNING: " + $env:computername + " drive " + $d);
        $message.Subject += (" has less than " + $result + " bytes free ");
        $message.Subject += ("(" + $disk.Free + " bytes - "+ ($disk.Free/1GB).ToString(".00") +" GB)");
        $message.Body =     "Hello there, `r`n`r`n";
        $message.Body +=    "this is an automatic e-mail message ";
        $message.Body +=    "sent by RunningLow Powershell script ";
        $message.Body +=    ("to inform you that " + $env:computername + " drive " + $d + " ");
        $message.Body +=    "is running low on free space. `r`n`r`n";
        $message.Body +=    "--------------------------------------------------------------";
        $message.Body +=    "`r`n";
        $message.Body +=    ("Machine HostName: " + $env:computername + " `r`n");
        $message.Body +=    "Machine IP Address(es): ";
        $ipAddresses = Get-NetIPAddress -AddressFamily IPv4;
        foreach ($ip in $ipAddresses) {
            if ($ip.IPAddress -like "127.0.0.1") {
                continue;
            }
            $message.Body += ($ip.IPAddress + " ");
        }
        $message.Body +=    "`r`n";
        $message.Body +=    ("Used space on drive " + $d + ": " + $disk.Used + " bytes. `r`n");
        $message.Body +=    ("Free space on drive " + $d + ": " + $disk.Free + " bytes. `r`n");
        $message.Body +=    "--------------------------------------------------------------";
        $message.Body +=    "`r`n`r`n";
        $message.Body +=    "This warning will fire when the free space is lower ";
        $message.Body +=    ("than " + $result + " bytes `r`n`r`n");
        $message.Body +=    "Sincerely, `r`n`r`n";
        $message.Body +=    "-- `r`n";
        $message.Body +=    "RunningLow`r`n";
    
    
        $smtp = new-object Net.Mail.SmtpClient($email_smtp_host, $email_smtp_port);
        $smtp.EnableSSL = $email_smtp_SSL;
        $smtp.Credentials = New-Object System.Net.NetworkCredential($email_username, $email_password);
        $mycredentials = ($email_username, $email_password);
    

    $smtp.send($message);
    $message.Dispose();

    Write-Host ” E-Mail sent!” ;
    }
    else {
    Write-Host (“Drive ” + $d + ” has more than ” + $result + ” bytes free: nothing to do.”);
    }
    }

  15. Hi Ryan,
    The percentage is fine for a fixed size drive, the problem with my servers is that the drive sizes are different, so how can I check for a percentage like 15% on drives of different sizes.

    Thanks

    Richard

  16. I am getting the below error. Please help me on this.

    Exception calling “Send” with “1” argument(s): “Failure sending mail.”
    At D:\Users\sumukhrs\Desktop\19APR\RunningLow.ps1:76 char:9
    + $smtp.send($message);
    + ~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : SmtpException

  17. Hi,
    How can I change $minsize = 2 GB in to Gigabytes , while it shows in bytes in the result which you can find below. It sends mails as bytes, how can we change to GB. Please help me to change it.
    Checking drive C …
    Drive C has more than 21474836480 bytes free: nothing to do.

    Checking drive D …
    Drive D has more than 21474836480 bytes free: nothing to do.

    Thanks

  18. .\RunningLow.ps1: The parameter “email_username” is declared in parameter-set “__AllParameterSets” multiple times.

Leave a Reply

Your email address will not be published. Required fields are marked *


The reCAPTCHA verification period has expired. Please reload the page.

This site uses Akismet to reduce spam. Learn how your comment data is processed.