PowerShell for Storage and File System Management (Part 11)

If you would like to read the other parts in this article series please go to:

We are just about finished with our storage health script. All we really have left to do is to add an E-mail notification mechanism and schedule the script to run automatically. In the previous article, I showed you how to generate an E-mail message from a PowerShell script. In this article, I want to show you how to integrate mail notification into the script that we have already created. So let’s get started.

So as you may recall, here is what our script looks like right now:

Function Get-Smart

#Function to get disk SMART information

{

$Smart = Get-WmiObject -namespace root\wmi –class MSStorageDriver_FailurePredictStatus -ComputerName $Input

If ($Smart.PredictFailure -EQ $True) {$Smart | Select-Object PSComputerName, InstanceName, PredictFailure, Reason | FL}

}

 

Function Get-Health

#Function to get disk health information

{

$Pdisk= Get-PhysicalDisk

ForEach ( $LDisk in $PDisk )

                {

                $CurrentDisk = $LDisk | Get-StorageReliabilityCounter

                If ($CurrentDisk.Temperature -GT 35 -OR $CurrentDisk.ReadErrorsTotal -GT 0 -OR $_.CurrentDisk -GT 0){

                                $LDisk.FriendlyName

                                $LDisk.HealthStatus

                                $LDisk | Get-StorageReliabilityCounter | Select-Object Temperature, ReadErrorsTotal, WriteErrorsTotal | FL

                                Write-Host ================== }

                }

}

 

#Script Body

$Servers = @(“Hyper-V-1”, “Hyper-V-2”, “Hyper-V-3”, “Hyper-V-4”, “Prod1”, “Prod2”)

                ForEach ($Server in $Servers) {

                $Server

                $Server | Get-Smart

                Enter-PSSession -ComputerName $Server

                Get-Health

                Exit-PSSession

                }

The easiest way of adding mail notification capabilities to the script would be to create an E-mail function. This function can contain everything except for the message body. We can send the message body to the function in the form of a variable. That way, the E-mail message can tell the recipient a little bit about the problem.

Since our function will require a name, I am going to call it Send-Notice. If we were to take the code from the previous article and dump it into the Send-Notice function as-is, then the function might look like this:

Function Send-Notice{

#Function to send E-mail notification of a problem

 

$EmailTo = “[email protected]

$EmailFrom = “[email protected]

$Subject = “Test”

$Body = “Test Body”

$SMTPServer = “E2K13.poseydemo.com”

 

$Username = “poseydemo\Administrator”

$Password = Get-Content c:\scripts\cred.txt | ConvertTo-SecureString

$Cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $password

 

Send-MailMessage -To $EmailTo -From $EmailFrom -Subject $Subject -Body $Body -Credential $Cred -SMTPServer $smtpserver

}

By adding this function to the script, it becomes possible to send test messages to [email protected] just by calling the function. Of course we want to do more than just send test messages. We want to send meaningful notifications of problems.

If you look at the function above, you will notice that it contains a variable named $Body. This variable forms the body of the E-mail message that is to be sent. Therefore, the key to sending meaningful messages will be to remove the $Body line from the Send-Notice function, and pass the message body to the function instead. By doing so, we will be able to send mail on an as needed basis in response to conditions detected by the script, and provide the recipient with information about the problem.

Designing the Send-Notice function to accept the message body is as simple as changing the function name to accept a variable, like this:

Function Send-Notice($Body)

Of course we also have to remove the $Body= line from the function.

The next trick is to modify the other functions to form a message body and then pass that message body to the Send-Notice function. Even this process is relatively straightforward.

The Get-Smart function currently contains the following line of code:

If ($Smart.PredictFailure -EQ $True) {$Smart | Select-Object PSComputerName, InstanceName, PredictFailure, Reason | FL}

This line of code causes the computer name, instance name, failure prediction, and reason code to be displayed whenever SMART predicts a storage failure. We can easily adapt this line of code to construct an E-mail message body and send it to the Send-Notice function. The resulting code looks like this:

Function Get-Smart

#Function to get disk SMART information

{

$Smart = Get-WmiObject -namespace root\wmi –class MSStorageDriver_FailurePredictStatus -ComputerName $Input

If ($Smart.PredictFailure -EQ $True) {

               

#             $Smart | Select-Object PSComputerName, InstanceName, PredictFailure, Reason

                $Body=’SMART has predicted a failure. ‘

                $Body2 = $Smart.PSComputerName

                $Body3 = $Smart.InstanceName

                $Body4 = $Smart.PredictFailure

                $Body5 = $Smart.Reason

                $Body = $Body + $Body2 + $Body3 + $Body4 + $Body5

Send-Notice($Body)

 

}

}

The code above checks for a predicted storage failure and then creates a variable named $Body. The $Body variable consists of text that says “SMART has predicted a failure”, followed by the computer name, instance name, failure prediction, and reason code. All of this is combined into a single variable named $Body, which is sent to the Send-Notice function.

You might also have noticed that I commented out the $Smart command. The only reason why I did this was to keep the output from being displayed on the screen.

So with that said, here is what the script looks like as a whole:

Function Send-Notice($Body)

#Function to send E-mail notification of a problem

{

$EmailTo = “[email protected]

$EmailFrom = “[email protected]

$Subject = “Test”

$SMTPServer = “E2K13.poseydemo.com”

 

$Username = “poseydemo\Administrator”

$Password = Get-Content c:\scripts\cred.txt | ConvertTo-SecureString

$Cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $password

 

Send-MailMessage -To $EmailTo -From $EmailFrom -Subject $Subject -Body $Body -Credential $Cred -SMTPServer $smtpserver

}

 

 

Function Get-Smart

#Function to get disk SMART information

{

$Smart = Get-WmiObject -namespace root\wmi –class MSStorageDriver_FailurePredictStatus -ComputerName $Input

If ($Smart.PredictFailure -EQ $True) {

               

#             $Smart | Select-Object PSComputerName, InstanceName, PredictFailure, Reason

                $Body=’SMART has predicted a failure. ‘

                $Body2 = $Smart.PSComputerName

                $Body3 = $Smart.InstanceName

                $Body4 = $Smart.PredictFailure

                $Body5 = $Smart.Reason

                $Body = $Body + $Body2 + $Body3 + $Body4 + $Body5

Send-Notice($Body)

 

}

}

 

 

Function Get-Health

#Function to get disk health information

{

$Pdisk= Get-PhysicalDisk

ForEach ( $LDisk in $PDisk )

                {

                $CurrentDisk = $LDisk | Get-StorageReliabilityCounter

                If ($CurrentDisk.Temperature -GT 35 -OR $CurrentDisk.ReadErrorsTotal -GT 0 -OR $_.CurrentDisk -GT 0){

                                $LDisk.FriendlyName

                                $LDisk.HealthStatus

                                $LDisk | Get-StorageReliabilityCounter | Select-Object Temperature, ReadErrorsTotal, WriteErrorsTotal | FL

                                Write-Host ================== }

                }

 

Although the script currently only sends E-mail notifications of SMART failures, the exact same technique could easily be applied to the Get-Health function. Remember, all we have to do is to form a variable named $Body, and then pass that variable to the Send-Notice function. We might for instance do something like this:

$Body1 = ‘A disk health problem has been detected on disk ‘

$Body2 = $LDisk.FriendlyName

$Body3 = ‘. The health status is: ‘

$Body4 = $LDisk.HealthStatus

$Body = $Body1 + $Body2 + $Body3 + $Body4

$Send-Notice($Body)

Of course this code segment is just an example. You can be as creative as you like when forming E-mail notifications.

Conclusion

In this article, I have shown you how to integrate E-mail notifications into a disk health script. In the next article in this series, I plan to conclude the series by showing you how to automate the script so that it runs at scheduled times.

If you would like to read the other parts in this article series please go to:

Leave a Comment

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

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Scroll to Top