PowerShell for Storage and File System Management (Part 7)

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

In my previous article, I showed you how to create a script that would retrieve SMART information and disk health information for the computers on your network. The script was even capable of looking at multiple servers. There were just two problems with the script. First, it was somewhat complicated. Second, it has the potential to produce an overwhelming amount of data.

My goal in this article is to address those two issues. I can’t really do much to simplify the script without sacrificing functionality in the process, but I do want to step you through the script so that you can understand how it works. As for the script having the potential to produce way too much data, I am eventually going to show you how to add some filters that will keep that from happening. For right now though, let’s walk through the script’s logic. Here is what the script looks like in its current form:

Function Get-Smart

#Function to get disk SMART information

{

(Get-WmiObject -namespace root\wmi –class MSStorageDriver_FailurePredictStatus -ComputerName $Input | Select-Object PSComputerName, InstanceName, PredictFailure, Reason)

}

 

Function Get-Health

#Function to get disk health information

{

$Pdisk= Get-PhysicalDisk

ForEach ( $LDisk in $PDisk )

                {

                $LDisk.FriendlyName

                $LDisk.HealthStatus

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

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

                }

}

 

#Script Body

$Servers = @(“Hyper-V-1”, “Hyper-V-2”)

                ForEach ($Server in $Servers) {

                $Server | Get-Smart

                Enter-PSSession -ComputerName $Server

                Get-Health

                Exit-PSSession

                }

As you look at the script shown above, you will notice that it contains three main sections. There is a function named Get-Smart, another function named Get-Health, and then there is the script’s main body.

PowerShell functions do not execute until they are called. As such, when the script is run, PowerShell initially ignores the two functions and begins the actual code execution at the script body. For the sake of reference, here is the script body:

#Script Body

$Servers = @(“Hyper-V-1”, “Hyper-V-2”)

                ForEach ($Server in $Servers) {

                $Server | Get-Smart

                Enter-PSSession -ComputerName $Server

                Get-Health

                Exit-PSSession

                }

The first line of code in the code block above (#Script Body) is just a comment, and is therefore ignored by PowerShell.

The second line of code is where we define the names of the servers that we want to analyze. In this case, those servers are named Hyper-V-1 and Hyper-V-2. Obviously, you would replace these server names with the names of your own servers. In my script, I am only analyzing two servers because I wanted to keep things simple, but you could easily add more servers. Server names need to be enclosed in quotation marks and separated from one another by a comma. Incidentally, the server names are being stored in an array named $Servers.

The next line is where the real action starts. This line uses the ForEach command to create a loop. In this case, we are performing a set of tasks for each $server in $servers. You will notice that this command ends with a brace and that there is another brace at the end of the code block. The code between the two braces executes once for each server within the list of servers. What the ForEach line is really saying is essentially that we need to perform a set of steps for every server on the server list.

So what are these steps? Well, there are really only four instructions. The first is $Server | Get-Smart. This command tells PowerShell to send the server name to the Get-Smart function, which will in turn retrieve SMART information for the specified server. I will step through the function in a moment, but first I want to finish with the main body.

The next line of code is Enter-PSSession –ComputerName $Smart. This line of code tells PowerShell to establish a remote session with the specified server. That way, PowerShell commands can be remotely executed on that server.

The following line is Get-Health. As previously discussed, Get-Health is not a native PowerShell cmdlet, but rather the name of a function. This line is therefore calling the Get-Health function.

The last line of code before the closing brace is Exit-PSSession. So in other words, the script establishes a session with a remote server, runs the Get-Health function against the specified server, and then ends the session.

So now that I have walked you through the script’s main body, what about the individual functions? Well, there are two functions and the first is the Get-Smart function. Here is the function:

Function Get-Smart

#Function to get disk SMART information

{

(Get-WmiObject -namespace root\wmi –class MSStorageDriver_FailurePredictStatus -ComputerName $Input | Select-Object PSComputerName, InstanceName, PredictFailure, Reason)

}

When the main body of the script calls the Get-Smart function, it passes the server name to the function. The function only contains a single line of executable code, and most of this code was discussed in a previous article. The thing that is important to pay attention to is the –ComputerName parameter, which is followed by $Input. The $Input variable refers to the value that is being passed to the function. In this case, that value is a server name.

The script also contains a Get-Health function. Here is what this function looks like:

Function Get-Health

#Function to get disk health information

{

$Pdisk= Get-PhysicalDisk

ForEach ( $LDisk in $PDisk )

                {

                $LDisk.FriendlyName

                $LDisk.HealthStatus

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

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

                }

}

Remember, we don’t have to pass the server name to the function because the function is executing on a remote server thanks to the session that we are establishing.

Although the function appears a bit convoluted, it is relatively simple. We are starting out by creating a variable named $Pdisk which contains a list of all of the physical disks within the server. Next, we are using the ForEach command to create a loop. In this case, the loop allows us to examine each of the server’s disks individually. We are basically telling PowerShell to perform a set of steps for each disk in the list of physical steps.

Once again, the loop steps are enclosed in braces. I won’t bore you with a discussion of the individual loop steps because they were covered in a previous article. These steps simply display the disk’s friendly name and its health status. The code block goes on to retrieve and display the total number of read and write errors as well as the disk’s temperature from the reliability counter.

In case you are wondering about the Write-Host =========== line, this line simply tells PowerShell to display several equal signs on the screen. I am using this as a separator that makes it easier to differentiate between one disk and the next. Each disk’s statistics is displayed between rows of equal signs.

Conclusion

I sincerely hope that you found my explanation of this script’s commands to be helpful and that you are starting to get some ideas for how such a script might be useful in your own organization. In the next article in this series, I will begin addressing the potential for information overload.

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

About The Author

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