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.
- Part 1: Checking System Drive Spaces with WMI and PowerShell
- Part 2: Getting System Drive Alternatives
- Part 3: Compound Filtering with WMI and PowerShell
- Part 4: Scaling WMI with PowerShell and Remoting
- Part 5: Using PowerShell’s Storage Cmdlets to Query the System Drive
On your client desktop, you can import the Storage module.
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.
Say Goodbye to Traditional PC Lifecycle Management
Traditional IT tools, including Microsoft SCCM, Ghost Solution Suite, and KACE, often require considerable custom configurations by T3 technicians (an expensive and often elusive IT resource) to enable management of a hybrid onsite + remote workforce. In many cases, even with the best resources, organizations are finding that these on-premise tools simply cannot support remote endpoints consistently and reliably due to infrastructure limitations.
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. I already know that C is the system drive, so let's see if there is property that can identify it as such.
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.
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.
Excellent! I can see the size and size remaining or free space. With this information, I can easily query all of the servers.
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. 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.