A couple of weeks ago, I received an email message from someone who asked a rather thought-provoking question. He wanted to know if there is an easy way to calculate a total for a column of information displayed in PowerShell. More specifically, the person who wrote me the email wanted to be able to use PowerShell to determine the amount of resources that were being collectively used by a group of Hyper-V virtual machines.
While the above question seems simple enough, there is a lot to unpack. The question implies the need for creating a VM group, adding virtual machines to that group, performing some sort of resource query against the VMs in the group, and then totaling the query results. For this article, however, I am going to keep things a little bit simpler.
Rather than going through all of the steps that I described above, I am going to use the Get-VM cmdlet to acquire a list of all of the virtual machines that reside on a particular Hyper-V host, and then I am going to derive the total amount of memory that is in use by those virtual machines. Sure, there are easier ways to figure out how much memory is in use, but figuring out how much memory is in use isn’t the point. The technique that I am about to show you can be used to create a sum total for any column of information displayed in PowerShell. I am using memory as an example, but the technique could just as easily be applied to CPU resources, disk space, storage IO, or any other metric.
If you look at the screenshot below, you can see that I have run the Get-VM cmdlet on a Hyper-V server. Because I did not specify any additional command parameters, PowerShell shows me every VM on the host, as well as the state, CPU usage, memory usage, uptime, status, and version of each virtual machine. Since there are only six VMs present, it is easy to see that the five running VMs are consuming 1GB of memory each, for a collective total of 5GB.
In this case, it was easy to tell how much memory was being used just by looking, but in the real world, things aren’t always quite so easy. That being the case, let me show you how to make PowerShell come up with the total for you.
The first thing that we have to do is to figure out the name of the parameter that holds the virtual machine memory value. In the screenshot above, the column header is named MemoryAssigned(M). However, in PowerShell column headers do not always match parameter names. If I were to append the Select-Object M* cmdlet to the end of the Get-VM cmdlet, PowerShell shows me all of the VM parameters that start with the letter M. As you can see in the next figure, the parameter that reflects the amount of memory being used is MemoryAssigned.
Now that we know the column name, we can sum the column. Even though there are ways of getting a column sum directly, I prefer to use a variable. The reason for this is that depending on what kind of data you are totaling, PowerShell might not always present the data in the best possible format. I will show you what I mean in just a moment. For right now though, the command that is used to determine the total amount of memory used by the Hyper-V virtual machines is:
$Total = (Get-VM | Measure-Object ‘MemoryAssigned’ -sum).sum
As you can see, this command is relatively straightforward. I am creating a variable named $Total. This variable is assigned the output of the Get-VM cmdlet after it has been filtered by the Measure-Object cmdlet. In this case, the Measure-Object cmdlet is being directed toward the MemoryAssigned column, which is then being summed. The screenshot below shows the command being used in PowerShell, as well as the value that is ultimately assigned to the $Total variable.
Earlier, I said that I like to map the results to a variable because PowerShell does not always output the value in the best format. This is a perfect example of that statement. While it is true that PowerShell is telling us that the VMs are collectively consuming 5GB of memory, the 5GB value is being expressed as 5,368,709,120. In other words, PowerShell is reporting virtual machine memory usage in kilobytes. Even though there are certain use cases for this, it is usually going to be more convenient to see the value expressed in terms of gigabytes. Thankfully, this is really easy to do.
Since we mapped the value to a variable, all we have to do is to divide the variable by 1GB. We don’t even have to know the number of kilobytes in a gigabyte, because PowerShell is natively able to divide a value by gigabytes. Here is the command:
$Total / 1GB
As you can see in the next screenshot, this command gives a result of 5, indicating that the VMs are collectively consuming 5GB of memory. Incidentally, you can just as easily display the value in megabytes by dividing by 1MB rather than 1GB.
Virtual machine resources: Leverage PowerShell for more information
Even though I worked through the example of displaying the amount of memory that my virtual machines are collectively consuming, the technique that I showed you is not limited to tallying memory consumption. PowerShell can report on a wide variety of virtual machine attributes and you can use this technique to sum any numerical attribute. You can also filter the list of VMs and then create sums for attributes within the filtered list.
Featured image: Freepik / Science vector created by Slidesgo
More PowerShell Basics articles
- Which type of PowerShell loop should you be using?
- Working with CSV files in PowerShell
- Reading and extracting values from XML files with PowerShell
- Working with dates in PowerShell revisited
- PowerShell regular expressions: Making string evaluation easier