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

Hey, Scripting Guy! I know how to determine the amount of free space on a drive, but how can I determine the percentage of free disk space on a drive?

-- MS

Hey, JP. You’re right: determining the amount of free disk space on a drive is pretty easy. For example, this simple little script tells you the amount of free space (in bytes) for drive C on a computer:

```strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colDisks = objWMIService.ExecQuery _
("Select * from Win32_LogicalDisk Where DeviceID = 'C:'")
For Each objDisk in colDisks
Wscript.Echo objDisk.FreeSpace
Next
```

And we have good news for you: determining the percentage of free disk space is almost as easy. That’s because the percentage of free disk space requires just a simple calculation: you take the available disk space and divide it by the total size of the drive. Suppose we had a really small drive, a 10-byte drive with 2 bytes of free disk space. To determine the percentage of free disk space, we’d divide 2 by 10 (free space by total size) and get a value of .20. In other words, 20% free space on our teeny-tiny drive.

It’s a simple equation, and we already have half of it: the FreeSpace property of the Win32_LogicalDisk class tells us the amount of free space. And although you might not have realized it, we also have the second half of the equation: the Size property of that same class tells us the size of the drive. All we need to do in our script is divide the FreeSpace by the Size, and we have our percentage:

```strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colDisks = objWMIService.ExecQuery _
("Select * from Win32_LogicalDisk Where DeviceID = 'C:'")
For Each objDisk in colDisks
intFreeSpace = objDisk.FreeSpace
intTotalSpace = objDisk.Size
pctFreeSpace = intFreeSpace / intTotalSpace
Wscript.Echo pctFreeSpace
Next
```

Nifty, huh? The only problem with this script is that it reports back a decimal number like 0.22457268101427. Technically accurate, yes, but an answer that doesn’t really look much like a percentage. So let’s use VBScript’s FormatPercent function to get back a value like 22.45%:

```strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colDisks = objWMIService.ExecQuery _
("Select * from Win32_LogicalDisk Where DeviceID = 'C:'")
For Each objDisk in colDisks
intFreeSpace = objDisk.FreeSpace
intTotalSpace = objDisk.Size
pctFreeSpace = intFreeSpace / intTotalSpace
Wscript.Echo FormatPercent(pctFreeSpace)
Next
```

That’s much better.

Just for the heck of it, here’s another variation. By default, the Win32_LogicalDisk class looks at all disk drives on your computer, including floppy drives, removable Zip drives, etc. If you’d like to get back free space information on just your hard drives, modify your WQL Query so that it selects all drives with a DriveType of 3 (which, in the world of WMI, represents a hard drive). In other words:

```strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colDisks = objWMIService.ExecQuery _
("Select * from Win32_LogicalDisk Where DriveType = 3")
For Each objDisk in colDisks
intFreeSpace = objDisk.FreeSpace
intTotalSpace = objDisk.Size
pctFreeSpace = intFreeSpace / intTotalSpace
Wscript.Echo objDisk.DeviceID, FormatPercent(pctFreeSpace)
Next
```

1. jrv says:

John –

sysdrive = shell.Environment("PROCESS")("SYSTEMDRIVE")

2. Muhammed says:

Thanks this is great!

3. BG says:

Hi, Thats a nice script, can the output be converted to a HTML format and used for some mailing?

4. Daniel B says:

Hi, this is great! Is there a way to deposit this info on a file or on a list of sharepoint?

5. John says:

Awesome…love the simplicity.  Can you set your query to only include the system partition (which of course isn't always C:)??

6. sqlscripter says:

This will dump mount pointn info into a sql table if already present in a perfmon db created ahead of time.

Create db named perfmon – Table code:
create TABLE [dbo].[MountPoint_info] (
[MountSize] [int] NULL ,
[Caption] [varchar](25) NULL ,
[DriveLetter] [varchar](25) NULL ,
[Mount_Label] [varchar](25) NULL ,
[FreeSpace] [int] NULL,
[Mount_Name] [varchar](55)NULL,
[Time_Occurred] [smalldatetime]
) ON [PRIMARY]
GO
CONSTRAINT [DF_MountPoint_info_Occurred] DEFAULT (LEFT(GETDATE(),20)) FOR [Time_Occurred]

GO

–Code to insert mount point information from WMI using VB Script and ASP.
On Error Resume Next
objRS.CursorLocation = 3
objRS.Open "SELECT * FROM MountPoint_info" , objConn, 3, 3
strComputer = "."
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\" & strComputer & "rootcimv2")
Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_Volume WHERE Capacity>0?",,48)
For Each objItem in colItems
objRS ("MountSize") = objItem.Capacity
objRS ("Caption") = objItem.Caption
objRS ("DriveLetter") = objItem.DriveLetter
objRS ("FreeSpace") = objItem.FreeSpace
objRS ("Mount_Label") = objItem.Label
objRS ("Mount_Name") = objItem.Name
Next
objRS.Close
objConn.Close

7. Ram Karthik says:

I have a very strange problem on a production server SQL2005 server.

I have a SQL Agent job that has a single step that is some activex code for disk space monitoring. There is more code to it but I have narrowed the issue down to a piece of code I can run for debugging the issue.

The following code stalls out on the BOLD line of code and progresses no further. At this point, I have to stop the job as it will never finish. This same code works on other SQL2005 servers as well as SQL2008/SQL2012 instances.

Set oShell = CreateObject("WScript.Shell")
Set WshNetwork = CreateObject("WScript.Network")
strComputer = WshNetwork.ComputerName

Set objWMIService = GetObject( "winmgmts" & chr(58) & "//" & strComputer & "/root/cimv2" )
Set colItems = objWMIService.ExecQuery("Select * from Win32_LogicalDisk where DriveType=3",,48)

Set WshNetwork = nothing
Set objWMIService = nothing
Set colItems = nothing
Set oShell = nothing
Some trouble shooting I have done so far:
I can create a VBscript .vbs file and execute it via XP_CMDSHELL without issue.
I can run it manually on the server logged in under the same domain account that both SQLAgent and SQLServer instances are running as without issue.
I can also run it manually on the server using my own domain login without issue.
This is a stand alone server so no clustering or anything fancy that might get in the way.
A reboot of the server also did not help.
There is no console/echo code to hang up the script either.
I have some DB connection code (not shown here) that writes to a table so I know the strComputer is being calculated correctly.
Windows Admins as a last effort did a WMI rebuild which also did not help.

For reference:
select @@version
Microsoft SQL Server 2005 – 9.00.4035.00 (X64)

Note: I do not have admin access to this box as that team is separated from the DBA team due to security regulations and requirements, however, they have been as helpful as possible.

Any advise would be greatly appreciated.

8. Steve says:

Hi! Thanks for this great script! Could I make this into an alert i.e. if Disk space is above 90 % send email?
Thanks in Advance for the help!