Checking System Drive Free Space with WMI and PowerShell

Today’s article is another “ripped from the forums” inspired item. The question at hand is how to query the free space on the system drive for several remote computers. The system drive is normally C: as you can see with the %SystemDrive% environmental variable. But it doesn’t have to be, and in the original problem that was exactly the situation. Some servers might be C: but others might be D: or even E:, I suppose. So what’s the best way to use PowerShell to figure all of this out?


First off, let’s see what we need to get the free space information. We can use Get-Wmiobject and query the Win32_LogicalDisk class. We can also limit the query to the system drive. Since I already know in advance what that is I can run a command like this:

Getting disk information for the system drive (Image Credit: Jeff Hicks)
Getting disk information for the system drive (Image Credit: Jeff Hicks)
Of course, we can control what information to get.
Selecting key properties (Image Credit: Jeff Hicks)
Selecting key properties (Image Credit: Jeff Hicks)
The values are in bytes but they are easily converted using a custom hash table.
Formatted results (Image Credit: Jeff Hicks)
Formatted results (Image Credit: Jeff Hicks)
I'm telling PowerShell to treat the size value as an integer and to round the free space value to two decimal points. Now that we know what we want to end up with, let's take a step back and figure out how to determine what device ID to filter. It turns out the Win32_OperatingSystem class has the information we need.
Finding the system drive from WMI (Image Credit: Jeff Hicks)
Finding the system drive from WMI (Image Credit: Jeff Hicks)
This means that if I didn't know the system drive ahead of time, I could run my Win32_Logicaldisk query like this:
Dynamically getting system drive size and freespace (Image Credit: Jeff Hicks)
Dynamically getting system drive size and freespace (Image Credit: Jeff Hicks)
And of course PowerShell easily scales.
Sorted and formatted results (Image Credit: Jeff Hicks)
Sorted and formatted results (Image Credit: Jeff Hicks)
In this example I had to run a separate WMI command to get the SystemDrive from Win32_OperatingSystem. I have to query each computer separately so that I can correlate the system drive for each one. But if I wanted to be clever, I could use a nested command.
​
This will give me the same result. This is definitely a bit more convoluted and requires the use of sub-expressions and nested commands. Although one benefit of processing computers individually is that it makes it easier to handle errors. I made it easy by using computers that I knew were running in my $computers variable. But most likely that isn't always going to be true.
Added error handling with Try/Catch (Image Credit: Jeff Hicks)
Added error handling with Try/Catch (Image Credit: Jeff Hicks)
I've given you a lot of PowerShell code to digest, so I think we'll wrap it up for today. But we'll be back to this topic and scenario because it offers a good platform for learning more about PowerShell.