PowerShell for Storage and File System Management (Part 4)

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

In my previous article, I covered a lot of ground with regard to exploring techniques for evaluating disk health through PowerShell. Now it’s time to begin taking all of these techniques and turning them into some sort of useful script.

Even though the techniques that were covered in the previous article were at least somewhat straightforward, the script that we will be creating is going to be a little bit different from the way that you might be used to doing things – at least structurally. Here is the problem.

Obviously it is useful to be able to retrieve a server’s disk health information. However, our script would probably be a lot more useful if we could examine disk health for all of our servers. Normally if I were to write this sort of script in PowerShell, I would probably create a variable containing a list of my servers and then run the various diagnostic commands against each server. Although doing so is a viable option, the Get-PhysicalDisk cmdlet does not have a way to output the server name, at least not on its own. Imagine if we found a disk to have problems… We could report the problem, but it would be tough to tell which server the disk existed on. So with that being the case, I am going to build the script in a way that lets me work with each server individually.

So here is the plan. I am going to start out by creating a basic script that looks at disk health information and displays the relevant output. That’s step 1. Once I get that working then the next step will be to filter the output so that only the items requiring attention are displayed. After all, we don’t want to have to sort through a list of hundreds of disks to see if there is a problem. The report should tell us where the problem is without showing us a lot of clutter in the process. That’s Step 2. We will eventually get to Step 2, but because of the complexity of what I am doing, we need to get Step 1 working first.

In case you are wondering, there is a Step 3. Step 3 is setting up automation. The script should run automatically according to a schedule, and it should have a way of alerting the administrator if something were to go wrong.

So that’s the plan. By the time we are done, we should have a reliable mechanism for reporting on storage health for all of our servers.

So with that said, the first thing that I need to talk about is PowerShell functions. Remember when I said that we were going to have to deal with servers one at a time? To do so, we will build a couple of functions and then pass the name of each individual server to the functions, but I am getting ahead of myself.

For all practical purposes, you can think of a PowerShell function as a block of repeatable code. Let me explain.

At the risk of making myself sound really old. I first learned programming when I was a kid back in the 80s. Back then, the programming language of choice for home computers such as the CoCo and the Commodore 64 was BASIC, or line number basic as it is known today. For those of you who remember BASIC programming from classes in school or from playing around with your computer at home, you might recall a command called GOSUB. The GOSUB command would cause the program’s logic to take a detour to a specified line number. That line marked the beginning of a subroutine – a block of code that could be used multiple times. The subroutine ended with the RETURN command, which would cause the program’s execution to return to the point of the detour.

PowerShell functions are a lot like those old BASIC subroutines, but with a couple of important differences. The most obvious difference is that PowerShell doesn’t use line numbers. Therefore, a call to a PowerShell function doesn’t reference a line number, but rather a function name. Every PowerShell function has a name.

The other difference is that PowerShell allows you to pass parameters to a function (if necessary) and to optionally return parameters from a function. In line number basic there was no concept of sending values to or from a subroutine.

So let’s take a look at the structure of a PowerShell function. As previously mentioned, a function is really nothing more than a named block of repeatable code.

If you have ever taken a programming class then you are no doubt familiar with the old Hello World program. If you have never seen this before, it is an extremely simple program that displays the words Hello World on the screen. This is usually the first program that is taught in any beginner level programming class. 

In PowerShell, you could display Hello World simply by typing:

“Hello World”

But what if you wanted to do this using a function? Well, the first thing that we need is a name for the function. In recent years it has become commonplace to give functions names that resemble PowerShell cmdlets, so we will call our function Hello-World. The function itself might look something like this:

Function Hello-World


“Hello World”


So as you can see, we are using the word Function to designate the beginning of a function. The word Function is followed by the function name (Hello-World). The code that makes up the function is enclosed in braces {}. That’s it. That’s a simple PowerShell function. To call this function, we would just type Hello-World.

You can see an example of this in Figure A. The function shown in the figure doesn’t use any line breaks because I entered the function code at the command line rather than entering it into a script, but all of the previously mentioned components still exist.

Figure A: This is an extremely simple PowerShell function.

So what if we wanted to pass a parameter to a function? There are several ways of doing this, but maybe I want to pass my name to the function and have the function to say hello to me. I could do so with this code:

Function Hello-Name


“Hello $Input”


As you can see, I named the function Hello-Name and the function accepts a variable named $Input. If I wanted to pass my name to this variable, I could do so like this:

“Brien” | Hello-Name

You can see how this works in Figure B.

Figure B: I have passed my name to a function.

Like I said, there are many different ways of passing values to and from functions, but this is the simplest method that I could think of.


Now that you know the basic construct of a function, we can begin building our script. We will create two functions. One will check the disk’s SMART status, while the other checks basic health information. We can run these functions against remote computers by making use of the Invoke-Command cmdlet.

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