How Can I Determine the Percentage of Free Space on a Drive?

How Can I Determine the Percentage of Free Space on a Drive?

  • Comments 1
  • Likes

Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I determine the percentage of free space available on the drive where a script is running?

-- GS

SpacerHey, Scripting Guy! AnswerScript Center

Hey, GS. And hey, welcome to another edition of Scripting Guys Trivia, the Internet game show in which the Scripting Guys get to ask the questions! Let’s get right to the first such question: What number consists of a 1 followed by 100 zeroes? No, sorry; the correct answer is goog – oh, wait. Um, never mind. That wasn’t a very good question.

Let’s try another. What famous comic strip was created in 1919 by Bill De Beck? That is correct: Bill de Beck created the immortal comic strip Barney G – uh, well, we seem to have forgotten the rest of the name. Barney Something-or-other. Doesn’t matter; it probably wasn’t all that good of a comic strip anyway.

You know, this isn’t going quite as well as we had hoped.

Let’s try one more. In the year 2005 Dr. Brian L. Fisher discovered a new species of Madagascan ant. What name did he give this new species?

Sorry, time is up. Dr. Fisher christened his new species Proceratium goo – well, Proceratium is close enough. Give yourself a point if you said Proceratium.

Please accept our apologies for today’s quiz; we’re just having the darndest time coming up with answers. Because of that, maybe we should simply skip the quiz and, instead, see if we can figure out how to write a script that dynamically determines the amount of free space available on the drive where the script is running. As for the answers to today’s edition of Scripting Guys Trivia, well, maybe you could just look those up yourself using your favorite Internet search engine.

Note. So is Windows Live Search the Scripting Guys’ favorite Internet search engine? You bet it is. Why? Are you saying that there are other Internet search engines? That’s news to us.

At any rate, here’s a script that the Scripting Guys wrote themselves.

Note. What, no cute remarks about having stolen the script off the Internet? No, sorry; no cute remarks. The Scripting Guys do not condone stealing in any way, shape, or form. And no, not even in baseball. In fact, especially not in baseball.

Here’s the script:

strPath = Wscript.ScriptFullName
strDrive = Left(strPath, 2)

strComputer = "."

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set colDisks = objWMIService.ExecQuery _
    ("Select * From Win32_LogicalDisk Where DeviceID = '" & strDrive & "'")

For Each objDisk in colDisks
    intFreeSpace = objDisk.FreeSpace
    intTotalSpace = objDisk.Size
    pctFreeSpace = intFreeSpace / intTotalSpace
    Wscript.Echo FormatPercent(pctFreeSpace)
Next

This script starts out by assigning the value of the ScriptFullName property to a variable named strPath. In case you’re wondering, ScriptFullName is a property of the Wscript object. Notice that we don’t have to explicitly create an instance of the Wscript object; that’s because this object is automatically created for us any time we run a script that uses Windows Script Host.

And here you thought Microsoft never did anything for you without expecting to get paid for it!

ScriptFullName is going to return the full path to the script itself; that path will be something along the lines of D:\Scripts\My Scripts\Active Directory\Test.vbs. That’s very nice, except for this: all we want out of the path is the drive letter. How are we supposed to tease out everything except that drive letter?

To tell you the truth, there are probably several fancy-pants ways of doing that. The Scripting Guys being the Scripting Guys, however, we decided to take the easy way out. The first two characters in a path will always be the drive letter and a colon (e.g., D:). That means we can extract the drive letter by doing nothing fancier than simply using the Left function to grab the first two characters in the string:

strDrive = Left(strPath, 2)

And yes, we could have combined the first two lines into a single line, like so:

strDrive = Left(Wscript.ScriptFullName, 2)

We used two lines (rather than one) simply because we thought it would be a little easier for everyone to understand what we were doing.

After all, it’s hard enough to understand what the Scripting Guys are doing without us making it any harder on everyone.

Once we have the drive letter (and the colon), we’re ready to calculate the amount of free space remaining on the drive. To do so, we bind to the WMI service on the local computer, then call the ExecQuery method to return a collection of all the disk drives that have a DeviceID (drive letter) equal to the value of the variable strDrive :

Set colDisks = objWMIService.ExecQuery _
    ("Select * From Win32_LogicalDisk Where DeviceID = '" & strDrive & "'")

Notice what we’ve done here. In a typical WQL query you might hardcode in a drive letter, like so:

"Select * From Win32_LogicalDisk Where DeviceID = 'C:'"

Instead of hardcoding in a drive letter, however, we opted to do the following:

After the first single quote in our WQL query, we inserted a double quote mark. That indicates that we want the string to stop at that point:

"Select * From Win32_LogicalDisk Where DeviceID = '"

We then removed the hardcoded drive letter (C:) and replaced it with an ampersand, the variable strDrive, and a second ampersand:

"Select * From Win32_LogicalDisk Where DeviceID = '" & strDrive &

As you can see, we’re simply concatenating a couple of strings here; we have the string Select * From Win32_LogicalDisk Where DeviceID = ' plus the string variable strDrive. As for the ampersands, well, ampersands, as you undoubtedly know, are used to concatenate strings.

Finally, we need to put in the second single quote mark; after all, because the value in strDrive is a string that means the value needs to be enclosed within single quote marks. To take care of that, we tack on another double quote mark (to indicate that we’re starting a new string), then add the second single quote and a closing set of double quotes:

"Select * From Win32_LogicalDisk Where DeviceID = '" & strDrive & "'"

In other words, all we really did in order to replace a hardcoded string value with a variable is replace that hardcoded value with the construction " & strDrive & ":

"Select * From Win32_LogicalDisk Where DeviceID = 'C:'
"Select * From Win32_LogicalDisk Where DeviceID = '" & strDrive & "'"

See? Replacing a hardcoded string value with a variable is nowhere near as hard as you thought it was.

After we issue the query we get back a collection of all the hard drives on the computer that have a drive letter equal to D:; because drive letters must be unique on a computer that means there will be only one item in our collection. That also means that we can calculate the percentage of free space on the drive by first setting up a For Each loop to loop through all the items in our one-item collection, then executing the following block of code:

intFreeSpace = objDisk.FreeSpace
intTotalSpace = objDisk.Size
pctFreeSpace = intFreeSpace / intTotalSpace
Wscript.Echo FormatPercent(pctFreeSpace)

What are we doing here? Well, to begin with, we’re taking the value of the FreeSpace property and storing it in a variable named intFreeSpace; as the name implies, the FreeSpace property tells us the number of available bytes on the drive. We then take the value of the Size property and store that value in a variable named intTotalSpace; the Size property returns the total size of the drive in bytes. To determine the percent free space all we have to do is divide the available bytes by the total size of the disk:

pctFreeSpace = intFreeSpace / intTotalSpace

That’s going to return a value similar to this one:

0.138232508084972

Hmmm …. That’s the correct answer, but it doesn’t look much like a percentage, does it? Say, maybe that’s why we didn’t immediately echo the value of the equation intFreeSpace / intTotalSpace but, instead, stored that value in a variable named pctFreeSpace. In turn, that would explain why we used the FormatPercent function to convert the value to a percentage. Let’s see what the FormatPercent function returns:

13.82%

Now that’s more like it.

But what if you don’t like to spend all day typing? Hey, no problem; if you prefer, you can compact those four lines of code into a single line, like so:

Wscript.Echo FormatPercent(objDisk.FreeSpace / objDisk.Size)

Again, we used four lines because it makes it easier for people to visualize what’s happening. If you’d rather use one line or two lines or even 10,000 lines, however, well, who are we to tell you different?

We hope that answers your question, GS. And you know what? Seeing as how we still have a little bit of time left, what do you say we give the trivia quiz one last shot? Let’s see what we have here …. OK, here we go: What was the name of the monster in the 1913 children’s book by Vincent Cartwright Vickers? Oh, wait; we can’t use that one.

How about this: the name of the hit song released in 1964 by The Nashville Teens? Nope, sorry; that one’s no good, either.

Last try: name the author of the Russian novel Dead Souls?

You know what? Now we are out of time. See you all tomorrow.

Editor’s Note: Hey, the Scripting Editor knows the answer to that last one. Dead Souls was written by Nikolai Gogol. We finally got one – Yippee! Hooray! Yahoo!

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Hello, it's too late to write answer, but there's a direct solution:

    If objWMIService Then

    Set colDiskDrives = objWMIService.ExecQuery _

    ("Select * from Win32_PerfFormattedData_PerfDisk_LogicalDisk Where " _

    & "Name <> '_Total'")

    For Each objDiskDrive In colDiskDrives

    ' oFile.WriteLine "Drive " & objDiskDrive.Name & " on " & strComputer & " has " & objDiskDrive.FreeMegabytes & " MB (" & objDiskDrive.PercentFreeSpace & "%) Free"

    oFile.WriteLine "Drive;" & objDiskDrive.Name & ";" & objDiskDrive.FreeMegabytes/1024 & ";MB;" & objDiskDrive.PercentFreeSpace & "%"

    Next

    Else

    oFile.WriteLine "Could not connect to " & strComputer

    oFile.WriteLine "objWMIService; #" & objWMIService & "#"

    End If

    I expect that this code can solve a lot of problems

    Thansks!