In Part 1 of this two-part series, I covered the ‘Microsoft Troubleshooting Packs’ and ACL permission checks using PowerShell scripting. This article will focus on two more scripts, one to check if a host is alive and, if it is not, send a notification email, and another to check disk space, delete data from a given folder if a certain threshold is met and then notify a user by email.
Ping and Notify
Of primary importance to any network admin is server availability. Being able to regularly monitor if a group of hosts are alive and then give you a ‘heads up’ when they aren’t is a useful tool to have. The idea behind this script is to use the ping command to verify the availability of a destination host(s) at specified intervals and take action based on the response that is received; if the response is positive then do nothing, if the response is negative, send a notification email.
To construct this script, we need the following main elements:
1) The SMTP details for sending the email
2) An Array to store the hosts to ping
3) The Get-WmiObject cmdlet that uses the Win32_PingStatus class
4) A ForEach loop to perform an operation on each element in the Array
5) An If statement to perform a conditional action based on the result.
The first part of the script sets the email properties and stores each of them in a variable; $smtpServer holds the SMTP Server Name/IP Address, $smtpFrom stores the FROM address and $smtpTo stores the TO address.
An Array called $PingHosts is used to store the destination hosts to ping. The ForEach-Object cmdlet is used to execute the Get-WmiObject Win32_PingStatus command stored in $WmiPingStatus against the hosts stored in $PingHosts to the left of the pipe. The Select-Object cmdlet is used to obtain the Address and StatusCode property of each ping result.
A ForEach loop and If statement is then used to circle through each ping result and check if the status code is equal to 0. If it is equal to 0, no action is taken. If it is not equal to 0 then the email subject and body are set using the details of the non-responsive host and a message is sent using the Net.Mail.SmtpClient class. The image below shows a sample of the notification email that will be sent out to the address stored in $smtpTo.
Script:
# Set e-mail properties
$smtpServer = “192.168.0.5”;
$smtpFrom = “pinger@yourdomain.com”;
$smtpTo = “admin@domain.local”;
# Create an Array to store the destination hosts to ping
[Array] $PingHosts = “192.168.0.105”, “mailsrv01”, “www.google.com”
# Run Get-WmiObject using the Win32_PingStatus class against every host in the Array
$WmiPingStatus = {Get-WmiObject -Class Win32_PingStatus -Filter (“Address='” + $_ + “‘”) -ComputerName .}
$PingHosts | ForEach-Object -Process $WmiPingStatus | Select-Object -Property Address,StatusCode |
foreach {
# If StatusCode is equal to 0 then do nothing (since 0 = success)
If ($_.StatusCode -eq 0)
{
# Write-Host “Do nothing for:” $_.Address
}
# Else, if StatusCode is NOT equal to 0 then do something
Else
{
# Set e-mail subject and body using details of non-responsive host
$subject = “Attention: ” + $_.Address + ” is down!”;
$body = $_.Address + ” is not responding to a ping request. Please take action.`n”
# Set e-mail objects and send e-mail
$smtpClient = New-Object Net.Mail.SmtpClient($smtpServer);
$emailFrom = New-Object Net.Mail.MailAddress $smtpFrom, $smtpFrom;
$emailTo = New-Object Net.Mail.MailAddress $smtpTo, $smtpTo;
$mailMsg = New-Object Net.Mail.MailMessage($emailFrom, $emailTo, $subject, $body);
$smtpClient.Send($mailMsg)
}
}
Disk Space Checker
Hand in hand with my previous script to check whether a host is alive or not, it is important to keep an eye on disk space as low storage could result in performance issues or, at its worst, the system grinding to a halt. The idea behind this script is to use a WMI object to check, at specified intervals, if storage space for each drive on a given machine is less than xGB (5GB in this example) and take action based on this condition; if free space is less than the threshold then perform an action (e.g. delete all files in a given folder – an application log folder for example) and send a notification email, if free space is greater than the threshold then do nothing.
To construct this script, we need the following main elements:
1) The SMTP details for sending the email
2) An Array to store machines to check
3) The Get-WmiObject cmdlet that uses the Win32_LogicalDisk class
4) A ForEach loop to perform an operation on each element in the Array
5) An If statement to perform a conditional action based on the result.
The first part of the script sets the email properties and stores them in a variable; $smtpServer holds the SMTP Server Name/IP Address, $smtpFrom stores the FROM address and $smtpTo stores the TO address.
An Array called $machines is used to store the machines we want to check disk space on. The Win32_LogicalDisk class in the Get-WmiObject cmdlet is used to obtain the drive information for each machine in the $machines variable. The ‘-Authentication PacketPrivacy’ property is used to specify the authentication method, which encrypts all the data that is transferred between the client and the script that is authenticating. The ‘-Impersonation Impersonate’ property is used to specify the impersonation level to use, which allows the objects to use the credentials of the caller. The Where-Object cmdlet is used to retrieve local disk drives only (i.e. DriveType -eq 3), and Select-Object specifies to pull back the SystemName, VolumeName, FreeSpace, and Size information related to each drive.
A ForEach loop and If statement is used to circle through the FreeSpace information of each drive and check if it is greater than 5GB. If it is greater than 5GB then no action is taken. If it is less than 5GB then the Remove-Item cmdlet handles deleting all data in the folder specified within the $cleanDir variable and the email subject and body are set using the details of each machine and drive being checked. Finally, an email message is sent using the Net.Mail.SmtpClient class. The image below shows a sample of the notification email that will be sent out to the address stored in $smtpTo.
Note: The Remove-Item cmdlet can be removed from the script altogether, if you wish for no action to be taken and only an email notification sent out. Alternatively, edit the folder location to be a directory from where you wish files to be removed (e.g. a log files folder).
Script:
# Set e-mail properties
$smtpServer = “192.168.0.5”;
$smtpFrom = “notify@yourdomain.com”;
$smtpTo = “admin@domain.local”;
# Create an Array to store the destination hosts to ping
[Array] $machines = “192.168.0.5”, “localhost”
# Execute the Get-WmiObject win32_logicaldisk class against the array of machines
Get-WmiObject Win32_LogicalDisk -computername $machines -Authentication PacketPrivacy -Impersonation Impersonate | Where-Object { $_.DriveType -eq 3 } | Select-Object SystemName,VolumeName,FreeSpace,Size | foreach {
# If FreeSpace is greater than 5GB then do nothing
If ($_.FreeSpace -gt 5GB)
{
#do nothing
}
# Else, if FreeSpace is less than 5GB then do something
Else
{
# Delete all items from the C:\Temp folder
$cleanDir = “C:\Temp\*”
Remove-Item $cleanDir -Recurse -ea SilentlyContinue
# Set e-mail subject and body using disk volume and machine name info
$subject = “Attention: Disk space is running low on ” + $_.SystemName + “”;
$body = $_.VolumeName + ” drive has less than 5GB. Files from the ” + $cleanDir + ” folder have been deleted.`n”
# Send e-mail
$smtpClient = New-Object Net.Mail.SmtpClient($smtpServer);
$emailFrom = New-Object Net.Mail.MailAddress $smtpFrom, $smtpFrom;
$emailTo = New-Object Net.Mail.MailAddress $smtpTo, $smtpTo;
$mailMsg = New-Object Net.Mail.MailMessage($emailFrom, $emailTo, $subject, $body);
$smtpClient.Send($mailMsg)
}
}
When discussing both scripts, I mentioned automating them by having them run at scheduled intervals. To do this, you need to make use of the Windows Task Scheduler. Open the Task Scheduler from Start > All Programs > Accessories > System Tools (or type taskschd.msc in the Run box). Right click on Task Scheduler (Local) and choose “Create Basic Task…”. Follow the wizard and at the ‘Action’ page, choose “Start a Program” and type “PowerShell” as the Program/Script and specify the full path to the .ps1 script as an argument (see screenshot below). Press Next and Finish to close the wizard.
Now, from the Task Scheduler Library, choose the task you just created and right click > Properties to bring up the properties window. Go to the “Triggers” tab, select the Daily trigger and click Edit. In Advanced Settings, select “Repeat task every:” and choose the number of minutes you wish to have the task run. Click OK and OK again to close the task window. The Ping & Notify or Disk Space Checker PowerShell script should now automatically run every X minutes.
Both these articles have covered some of the most popular Network Admin responsibilities; storage, network availability, permissions and troubleshooting. As I alluded to earlier, the beauty of PowerShell scripts is their intuitive and customizable nature. I’m sure you will find a use for the scripts covered in these two articles – you can also tweak them even further and incorporate them into your own scripting toolkit.
Like our posts? Subscribe to our RSS feed or email feed (on the right hand side) now, and be the first to get them!