Essential skill you should know: Mapping PowerShell commands to variables

When I first started learning about PowerShell many years ago, one of the concepts that I had trouble wrapping my head around was that of mapping PowerShell commands to variables. In case you have never encountered this before, PowerShell makes it possible to link a variable to a command so that when you call the variable, the command is executed. While there is nothing overly difficult about mapping PowerShell commands to a variable, it can sometimes be tricky to get the variable to give you the output that you might expect. As such, I thought that I would share with you a few tricks that I have picked up over the years.

PowerShell allows you to map nearly any command to a variable, but for the sake of demonstration, I want to pick a single command and stick with it for all of the examples that I will be providing throughout this article. The cmdlet that I will be using is Get-PhysicalDisk.

When you enter the Get-PhysicalDisk cmdlet directly into PowerShell, you will receive an output that looks something like what you see in the image below.

Mapping PowerShell commands

You can assign a command to a variable in the same way that you would assign a constant value to a variable. Just enter the variable name, followed by an equal sign, and the command. As you can see in the figure below, this doesn’t generate any visible output, but calling the variable directly (by entering the variable name at the command line) causes the associated command to execute.

Mapping PowerShell commands

Of course, variables are often used for comparative purposes, so what happens if we need to examine one particular physical disk attribute for the sake of making a comparison? Well, as is so often the case with PowerShell, there are several ways of doing this. The easiest way to look at a particular attribute is to call the variable name, and then append a period, followed by the name of the attribute. For example, if you mapped the Get-PhysicalDisk command to a variable named $A and you wanted to check the disk’s health status, then you could enter this command:


$A.HealthStatus


As an alternative, you could append the Select-Object command to the variable name. The problem with using Select-Object is that doing so returns header information as well. If you needed to make a comparison, then the header information would get in the way. Let me show you what I mean. The lines of code assign the exact same piece of information to variables $A and $B, but $B uses the Select-Object method, which results in header information being included. If I compare the two variables, then I get a status of False, indicating that their values are different from one another, as shown in the image below.


$A = Get-PhysicalDisk
$A
$A.HealthStatus
$B = Get-PhysicalDisk | Select-Object HealthStatus
$B
$A.HealthStatus -eq $B


Mapping PowerShell commands

One thing that you might have noticed about the way that I have been using the $Get-PhysicalDisk cmdlet is that this particular computer only has one physical disk. What if we had two physical disks, and wanted to make some comparisons between them? I realize that you may never need to use PowerShell to compare the disks in your computer but remember that I am only using the Get-PhysicalDisk cmdlet as an example. The techniques that I am discussing work with a wide variety of PowerShell cmdlets.

To show you how this works, I am going to switch to a different computer. When I enter the Get-PhysicalDisk cmdlet on this system, it shows that this computer is equipped with two hard disks, an HDD, and an SSD. So what happens if we map a variable to the Get-PhysicalDisk cmdlet and then attempt to look at the HealthStatus parameter in exactly the same way that we did on a computer with only one physical disk? As you can see in the figure below, we see an indication that both disks are healthy.

Mapping PowerShell commands

Now suppose that I am only interested in the health of the SSD. There are a few different ways that I could filter the output, but here is one way of doing it:


$A=Get-PhysicalDisk | Where MediaType -eq ‘SSD’
$A.HealthStatus


 

In actuality, this block of code would show me the health status of every SSD in the system. In this case, though, I only have one. If I had multiple SSDs and needed to narrow down the list, I could filter by the disk’s friendly name or serial number.

Now that I have shown you how to look at a specific disk, let’s do a disk comparison. My HDD is obviously far larger than my SSD, but let’s use PowerShell to prove it, while also mapping each individual disk to a variable. Here are the commands that I will be using:


$SSD = Get-PhysicalDisk | Where MediaType -eq ‘SSD’
$HDD = Get-PhysicalDisk | Where MediaType -eq ‘HDD’
$SSD.Size -GT $HDD.Size


As you look at the commands above, you will notice that I have switched things up a bit with regard to the variable names. Rather than using variable names like $A or $B, I have used $SSD to represent the SSD drive, and $HDD to represent the HDD drive. As such, the first two lines of code are just variable assignments. The last line of code checks to see if the size of the SSD drive is bigger (-GT) than the size of the HDD drive. Because the SSD drive is smaller than the HDD drive, this command should return an output of false. If I reverse the command and check to see if the HDD is bigger than the SSD, then the output should flip to True. You can see an example of this in the image below.
Mapping PowerShell commands

Mapping PowerShell commands: An essential skill

Although mapping PowerShell commands to variables can take a bit of getting used to, it is an essential skill for those who plan to do any sort of advanced PowerShell scripting. By mapping commands to variables, a variable can come to represent an object such as a disk or a virtual machine, thereby making it easy for the script to reference that object.

Featured image: Pexels

About The Author

4 thoughts on “Essential skill you should know: Mapping PowerShell commands to variables”

  1. But…But….But… this is not mapping PS commands to a variable. It’s assigning the output results / object to a variable and then using the variable name captured property data to get the property contents / values.

    This is mapping a PS command to a variable, though I am not real sure why one would do it.

    # Store the command
    $MyVar = “Get-PhysicalDisk”

    # Using the command
    Invoke-Expression -Command $MyVar

    As for this statement…
    “In actuality, this block of code would show me the health status of every SSD in the system. In this case, though, I only have one. If I had multiple SSDs and needed to narrow down the list, I could filter by the disk’s friendly name or serial number.”

    These lists are just zero-based arrays. So one could just pick a drive by it’s position in the array.

    4 SSD / HHD would mean array list 0-3.

    ($SSD = Get-PhysicalDisk | Where MediaType -eq ‘SSD’)

    # Results
    FriendlyName SerialNumber MediaType CanPool OperationalStatus HealthStatus Usage Size
    ———— ———— ——— ——- —————– ———— —– —-
    Samsung SSD 850 EVO 2TB S2HCNWAG901905D SSD False OK Healthy Auto-Select 1.82 TB
    Samsung SSD 950 PRO 512GB 0025_3853_5B16_0295. SSD False OK Healthy Auto-Select 476.94 GB
    Samsung SSD 850 EVO 4TB S2RSNX0J300191B SSD False OK Healthy Auto-Select 3.64 TB
    Samsung SSD 950 PRO 512GB 0025_3853_5B16_000D. SSD False OK Healthy Auto-Select 476.94 GB

    So, 4 SSD’s in my system, all with the same default friendlyName, as most folks won’t rename them. So, rather than mess with friendlyName or serial number, if I wan the first drive, it’s just…

    $SSD[0]

    FriendlyName SerialNumber MediaType CanPool OperationalStatus HealthStatus Usage Size
    ———— ———— ——— ——- —————– ———— —– —-
    Samsung SSD 850 EVO 2TB S2HCNWAG901905D SSD False OK Healthy Auto-Select 1.82 TB

  2. Surprised to find this post in a tutorial section. Anyone taking this advice could have serious problems if they were expecting a ‘current’ enumeration on entering the variable name.

    Obviously, your intentions are good and props for the effort – but please be careful that your info is accurate.

  3. You make a good point Steve, about the variable containing a point in time value, as opposed to a current value. I am glad that you brought that up, because I really should have mentioned it in the article. Thanks again.

  4. And yet, you haven’t fixed the article. It’s confusing at best, but would seriously slow down/mislead someone just starting out with powershell.

    You’re not “mapping a command to a variable”, you’re assigning the results returned from a command(let) to a variable.

    Please update/fix this article.

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