Using PowerShell’s Storage Cmdlets to Query the System Drive

I’m back one more time to wrap up my article series on getting disk information for the system drive, even if you don’t know what that drive letter will be on a remote computer. More specifically, I want to search a list of computers that have 5 GB or less of free space.
In this series, I’ve been showing you how to use WMI as well as PowerShell remoting. If you have no idea what I’m talking about, take some time to get caught up on the previous articles. Those approaches work especially well if you have a number of legacy servers. In this article, I want to demonstrate how you can use the storage cmdlets to achieve the same results.


On your client desktop, you can import the Storage module.

Importing the Storage module (Image Credit: Jeff Hicks)
Importing the Storage module (Image Credit: Jeff Hicks)

This is what I have on Windows 8.1 with PowerShell 4.0. Of course, you can also run any command in the module, and PowerShell will automatically import the module. You can use Get-Command to view all of the available commands in the module.

Viewing Storage commands (Image Credit: Jeff Hicks)
Viewing Storage commands (Image Credit: Jeff Hicks)
The target servers for these commands must be running Windows Server 2012 at least. This means that I'm going to have to skip a few my of legacy servers in my environment for the sake of demonstration. The first step is to identity the system partition. The Storage module has a cmdlet called Get-Partition, so let's try that.
Querying partitions with Get-Partition (Image Credit: Jeff Hicks)
Querying partitions with Get-Partition (Image Credit: Jeff Hicks)
I already know that C is the system drive, so let's see if there is property that can identify it as such.
Getting partition details (Image Credit: Jeff Hicks)
Getting partition details (Image Credit: Jeff Hicks)
Although there's a IsSystem property, I believe IsBoot is the correct one to check. I can verify this logic by testing my list of computers. Because this is a new article, let me rebuild that list:
​
But remember, I can only query computers running Windows Server 2012 or later, so I need to refine this list one more time.
​
I used a wildcard query with WMI to only keep servers with 2012 in the operating system name. With this list, I can now get all of the bootable partitions.
Getting bootable partitions (Image Credit: Jeff Hicks)
Getting bootable partitions (Image Credit: Jeff Hicks)
The partition object doesn't provide any freespace information. But I can get that from the associated volume. The easiest way is to pipe the partition to the Get-Volume cmdlet. Here's a test for a single server to see all of the properties.
Viewing volume properties (Image Credit: Jeff Hicks)
Viewing volume properties (Image Credit: Jeff Hicks)
Excellent! I can see the size and size remaining or free space. With this information, I can easily query all of the servers.
Getting volume size for multiple servers (Image Credit: Jeff Hicks)
Getting volume size for multiple servers (Image Credit: Jeff Hicks)
The size values are in bytes, but that's simple enough to reformat. Also I want to limit my results to servers with low free space. For the sake of demonstration, I'm going to use threshold of 10 GB.
​
The storage cmdlets don't have a lot of filtering options, so I'll have to use Where-Object.
Querying for volumes with low free space (Image Credit: Jeff Hicks)
Querying for volumes with low free space (Image Credit: Jeff Hicks)
The Select-Object expression is using the same type of custom properties that I used in previous articles. And by the way, this command took 3.3 seconds to query eight computers. As with remoting, keep in mind that these commands need to setup and tear down temporary CIMSessions. You might be able to tweak performance by reusing existing CIMSessions.
​
This took under a second. I'll use these sessions instead of computer names.
​
I got the same results, but this time in 1.2 seconds. I didn't have to specify the CIMSessions with Get-Volume because it reused the session information from Get-Partition.
Finally, although I'm running this as one pipelined expression, sometimes you get better performance by breaking it down into several steps. Here is a multi-step variation.
​
Again, I get the same results, but this time it only took 351 milliseconds!

And there you have it. Over the series of articles, we explored a variety of PowerShell techniques for discovering information about the system drive, without having to know the system drive letter. As I've said throughout the series, the end result, while useful, isn't really the goal. My ongoing project is to educate you about PowerShell and hopefully take away some of the fears you may have in using it. Comments, questions and suggestions are always welcome.