How to get available hard drive space [SOLVED]

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
Dos_Probie
Posts: 233
Joined: 21 Nov 2010 08:07
Location: At My Computer

How to get available hard drive space [SOLVED]

#1 Post by Dos_Probie » 28 Apr 2014 07:05

The below code will give me my CORRECT Local Drive Free space (as show in My Computer) when increasing 1024 to 1036. Is this just a issue with batch files doing the math or what?

Code: Select all

@echo off
for /f "skip=1 usebackq delims==" %%i in (`wmic logicaldisk where "mediatype='12'" get caption`) do (
call :doit %%i )
:doit
set driveletter=%1
if {%driveletter%}=={} goto :EOF
for /f "usebackq delims== tokens=2" %%x in (`wmic logicaldisk where "DeviceID='%driveletter%'" get FreeSpace /format:value`) do set FreeSpace=%%x
for /f "usebackq delims== tokens=2" %%x in (`wmic logicaldisk where "DeviceID='%driveletter%'" get Size /format:value`) do set Size=%%x
set LocalDrv=%cd:~0,2%
set FreeMB=%FreeSpace:~0,-10%
set SizeMB=%Size:~0,-10%
set /a HDPercent=100 * FreeMB / SizeMB
set /a KB=%FreeSpace:~0,-4%
set /a MB = KB/1036
set /a GB = MB/1036
Echo %LocalDrv% Drive: %GB% GB Of Free Space = %HDPercent%%% Available..
Pause>nul
Last edited by Dos_Probie on 29 Apr 2014 12:14, edited 2 times in total.

penpen
Expert
Posts: 1991
Joined: 23 Jun 2013 06:15
Location: Germany

Re: Question on Avialable hard drive output from batch?

#2 Post by penpen » 28 Apr 2014 10:16

It is because you use "set /A KB=%FreeSpace:~0,-4%".
So KB doesn't store the real amount of free disk space in KB: only FreeSpace/1000 (/ == div == integer division without rest).
The correct value should be: FreeSpace/1024 (default math division).

When you are seeing it from the MB size, the correct value were (default math division; the "a^b" should denote "a to the power of b"):
FreeSpace/(1024^3) == FreeSpace/(1024*1024^2)
== FreeSpace/(1000 * 1.024 *1048576)
== FreeSpace/(1000 * 1073741,824)
== FreeSpace/(1000 * 1036,2151436839745395093974366397^2)
== (FreeSpace/1000) / (1036,2151436839745395093974366397^2)

penpen

Edit: Corrected 2 flaws.
Last edited by penpen on 28 Apr 2014 10:20, edited 2 times in total.

Compo
Posts: 599
Joined: 21 Mar 2014 08:50

Re: Question on Avialable hard drive output from batch?

#3 Post by Compo » 28 Apr 2014 10:19

Why not use one of the fancy hybrid methods!

Code: Select all

<!-- : Begin batch script
@Echo off
CScript //NoLogo "%~f0?.wsf"
Pause
Exit /b

----- Begin wsf script --->
<job><script language="VBScript">
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & "." & "\root\cimv2")
Set colDisks = objWMIService.ExecQuery _
    ("Select * from Win32_LogicalDisk Where DriveType = 3")
For Each objDisk in colDisks
    intFreeSpace = objDisk.FreeSpace / 1024 / 1024 / 1024
    intTotalSpace = objDisk.Size / 1024 / 1024 / 1024
    pctFreeSpace = intFreeSpace / intTotalSpace
    Wscript.Echo "Drive " & objDisk.DeviceID & " " & Round(intFreeSpace, 2) & _
     "GB Of Free Space = " & FormatPercent(pctFreeSpace) & " available"
Next
</script></job>

<EDIT>Tidied code</EDIT>

Dos_Probie
Posts: 233
Joined: 21 Nov 2010 08:07
Location: At My Computer

Re: Question on Avialable hard drive output from batch?

#4 Post by Dos_Probie » 28 Apr 2014 16:19

Thanks, guys
@penpen , Yours when changing as you suggested outputs a INCORRECT amount of free space.
@compo, Yours works CORRECTLY but reads ALL drives not just the local drive.
DP :roll:

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Question on Avialable hard drive output from batch?

#5 Post by foxidrive » 28 Apr 2014 17:42

Dos_Probie wrote:Thanks, guys
@penpen , Yours when changing as you suggested outputs a INCORRECT amount of free space.


Is the figure being calculated larger than 2 GB? plain batch maths tops out there in the freespace/1024 method that penpen mentioned.

Dos_Probie
Posts: 233
Joined: 21 Nov 2010 08:07
Location: At My Computer

Re: How to get available hard drive space figure in power of

#6 Post by Dos_Probie » 28 Apr 2014 18:56

Yes, it's much larger that 2 GB , actually 105 GB..DP

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: How to get available hard drive space

#7 Post by foxidrive » 28 Apr 2014 19:45

A little tweak of compo's code gives c: drive. The change is in line 3.

Code: Select all

<!-- : Begin batch script
@Echo off
CScript //NoLogo "%~f0?.wsf" |find /i "c:"
Pause
Exit /b

----- Begin wsf script --->
<job><script language="VBScript">
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & "." & "\root\cimv2")
Set colDisks = objWMIService.ExecQuery _
    ("Select * from Win32_LogicalDisk Where DriveType = 3")
For Each objDisk in colDisks
    intFreeSpace = objDisk.FreeSpace / 1024 / 1024 / 1024
    intTotalSpace = objDisk.Size / 1024 / 1024 / 1024
    pctFreeSpace = intFreeSpace / intTotalSpace
    Wscript.Echo "Drive " & objDisk.DeviceID & " " & Round(intFreeSpace, 2) & _
     "GB Of Free Space = " & FormatPercent(pctFreeSpace) & " available"
Next
</script></job>

penpen
Expert
Posts: 1991
Joined: 23 Jun 2013 06:15
Location: Germany

Re: How to get available hard drive space

#8 Post by penpen » 29 Apr 2014 04:14

Dos_Probie wrote:@penpen , Yours when changing as you suggested outputs a INCORRECT amount of free space.
You misunderstood me:
It is no suggestion but an explanation, why your code seems to output the correct value. Marking the important parts with red:
penpen wrote:So KB doesn't store the real amount of free disk space in KB: only FreeSpace/1000 (/ == div == integer division without rest).
The correct value should be: FreeSpace/1024 (default math division).
Side notes:
Batch is using div and no default math.

The error your first code does (in the above notation, using default math) is
e == 1 - (1024^3/(1000*1036^2)) == 0.0004153784231004308224385444463 ~= 0.0415%

So if your FreeSpace value does not exceed 1/e == 2407,4432960091874820556991099627 GB then your code will return the correct value without rounding.
If you want the correct result with rounding, then your code returns the correct value, if your FreeSpace value must be smaller than 0.5/e == 1203.7216480045937410278495557535 GB

penpen

einstein1969
Expert
Posts: 941
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: How to get available hard drive space

#9 Post by einstein1969 » 29 Apr 2014 08:35

Dos_Probie wrote:The below code will give me my CORRECT Local Drive Free space (as show in My Computer) when increasing 1024 to 1036. Is this just a issue with batch files doing the math or what?

Code: Select all

@echo off
for /f "skip=1 usebackq delims==" %%i in (`wmic logicaldisk where "mediatype='12'" get caption`) do (
call :doit %%i )
:doit
set driveletter=%1
if {%driveletter%}=={} goto :EOF
for /f "usebackq delims== tokens=2" %%x in (`wmic logicaldisk where "DeviceID='%driveletter%'" get FreeSpace /format:value`) do set FreeSpace=%%x
for /f "usebackq delims== tokens=2" %%x in (`wmic logicaldisk where "DeviceID='%driveletter%'" get Size /format:value`) do set Size=%%x
set LocalDrv=%cd:~0,2%
set FreeMB=%FreeSpace:~0,-10%
set SizeMB=%Size:~0,-10%
set /a HDPercent=100 * FreeMB / SizeMB
set /a KB=%FreeSpace:~0,-4%
set /a MB = KB/1036
set /a GB = MB/1036
Echo %LocalDrv% Drive: %GB% GB Of Free Space = %HDPercent%%% Available..
Pause>nul


I agree with penpen.

This code use KB, MB, GB and is about ok. But Windows use KiB, MiB, GiB and so on. ( Ki stand for Kibi etc.)

You need adjust or change the script to work in binary mode and not decimal mode

This table is for adjust or conversion decimal<-->binary Gibi-#Inconsistent_use_of_units

Code: Select all

Prefix    Bin ÷ Dec    Dec ÷ Bin    Percentage difference
kilo      1.024       0.9766    +2.4% or −2.3%
mega      1.049       0.9537    +4.9% or −4.6%
giga      1.074       0.9313    +7.4% or −6.9%
tera      1.100       0.9095    +10.0% or −9.1%
peta      1.126       0.8882    +12.6% or −11.2%
exa       1.153       0.8674    +15.3% or −13.3%
zetta     1.181       0.8470    +18.1% or −15.3%
yotta     1.209       0.8272    +20.9% or −17.3%


and use MiB=MB/0.9537 or MiB=MB/1.049 (I don't have checked this)

Edit: Correct the link.

einstein1969
Last edited by einstein1969 on 29 Apr 2014 08:55, edited 3 times in total.

Compo
Posts: 599
Joined: 21 Mar 2014 08:50

Re: Question on Avialable hard drive output from batch?

#10 Post by Compo » 29 Apr 2014 08:49

Dos_Probie wrote:@compo, Yours works CORRECTLY but reads ALL drives not just the local drive.
DP :roll:
It was difficult to tell from your code what you were looking for, the following 'fix' uses the current directory since you appeared to use %CD% in your original example.

Code: Select all

<!-- : Begin batch script
@Echo off
CScript //NoLogo "%~f0?.wsf"
Pause
Exit /b

----- Begin wsf script --->
<job><script language="VBScript">
Set objShell = CreateObject("Wscript.Shell")
strPath = objShell.CurrentDirectory
strDrive = Left(strPath, 2)
Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & "." & "\root\cimv2")
Set colDisks = objWMIService.ExecQuery _
    ("Select * From Win32_LogicalDisk Where DeviceID = '" & strDrive & "'")
For Each objDisk in colDisks
    intFreeSpace = objDisk.FreeSpace / 1024 / 1024 / 1024
    intTotalSpace = objDisk.Size / 1024 / 1024 / 1024
    pctFreeSpace = intFreeSpace / intTotalSpace
    Wscript.Echo "Drive " & strDrive & " " & Round(intFreeSpace, 2) & _
     "GB Of Free Space = " & FormatPercent(pctFreeSpace) & " available"
Next
</script></job>
(the current directory if not set in the batch script prior to the wsf instruction will be that of the script itself).

<EDIT>
If I understand what you were trying to do in your original offering, the below, although inaccurate, should have been all you required.

Code: Select all

@Echo off
SetLocal
For /f "UseBackQ Tokens=1-2 Delims==" %%A In (`WMIc LogicalDisk Where^
 "DeviceID = '%CD:~,2%'" Get FreeSpace^, Size /Value`) Do (If "%%B" NEq "" (
   Call Set _%%A=%%B))
Set/a _FreePercent=%_FreeSpace:~,-3% / %_Size:~,-5%
Set/a _FreeSpace=%_Freespace:~,-3% / 1036 /1036
Echo(Drive %CD:~,2% %_FreeSpace% GB Of Free Space = %_FreePercent%%% available
Pause>Nul
Depending upon your drive sizes and the possibility of reaching the 32-bit number limitations, you may need to replace the appropriate lines with:

Code: Select all

Set/a _FreePercent=%_FreeSpace:~,-6% / %_Size:~,-8%
Set/a _FreeSpace=%_Freespace:~,-6% / 1048
</EDIT>

einstein1969
Expert
Posts: 941
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: How to get available hard drive space

#11 Post by einstein1969 » 29 Apr 2014 10:45

There is a problem with output of wmic too...

This is accurate and work until 1PetaByte using above table for output in GiB.
This is an examples for freespace only. You may adapt for Tera byte output in future easily.

Code: Select all

@echo off
for /f "skip=1 usebackq delims==" %%i in (`wmic logicaldisk where "mediatype='12'" get caption`) do (
call :doit %%i )

goto :eof

:doit

set driveletter=%1
if {%driveletter%}=={} goto :EOF

rem add patch for wmic output
for /f "usebackq delims== tokens=2" %%x in (`wmic logicaldisk where "DeviceID='%driveletter%'" get FreeSpace /format:value`) do for %%y in (%%x) do set FreeSpace=%%y

rem 1PetaByte
rem set freespace=112589990684262

rem using MB for getting three digit after the comma. Precision of 3 digit.
set MB=%FreeSpace:~0,-6%

if Not defined MB set MB=0

rem workaround for batch precision
if %MB% lss 214748 (
       set /A GiB=MB*9313/10000
) else set /A GiB=MB/1074*1000

echo %1 FreeSpace: %freespace% Byte - %GiB:~0,-3%.%GiB:~-3% GiB

goto :eof


einstein1969

Compo
Posts: 599
Joined: 21 Mar 2014 08:50

Re: How to get available hard drive space

#12 Post by Compo » 29 Apr 2014 11:21

einstein1969 wrote:

Code: Select all

rem workaround for batch precision
if %MB% lss 214748 (
   set /A GiB=MB*9313/10000
) else set /A GiB=MB/1074*1000

Using your accuracy

Code: Select all

@Echo off
SetLocal
For /f "UseBackQ Tokens=1-2 Delims==" %%A In (`WMIc LogicalDisk Where^
 "DeviceID = '%CD:~,2%'" Get FreeSpace^, Size /Value`) Do If "%%B" NEq "" (
   Call Set _%%A=%%B)
Rem Set/a _FreePercent=%_FreeSpace:~,-3% / %_Size:~,-5%
Set/a _FreePercent=%_FreeSpace:~,-6% / %_Size:~,-8%
If %_FreeSpace:~,-6% lss 214748 (Set/a _FreeSpace=%_FreeSpace:~,-6%*9313/10000
   ) Else (Set/a _FreeSpace=%_FreeSpace:~,-6%/1074*1000)
Echo(Drive %CD:~,2% %_FreeSpace:~,-3% GiB Of Free Space = %_FreePercent%%%^
 available
Pause>Nul
TBH I see no real reason for accuracy when using integer math which rounds down

einstein1969
Expert
Posts: 941
Joined: 15 Jun 2012 13:16
Location: Italy, Rome

Re: How to get available hard drive space

#13 Post by einstein1969 » 29 Apr 2014 11:53

Compo wrote:
einstein1969 wrote:

Code: Select all

rem workaround for batch precision
if %MB% lss 214748 (
   set /A GiB=MB*9313/10000
) else set /A GiB=MB/1074*1000

Using your accuracy

Code: Select all

@Echo off
SetLocal
For /f "UseBackQ Tokens=1-2 Delims==" %%A In (`WMIc LogicalDisk Where^
 "DeviceID = '%CD:~,2%'" Get FreeSpace^, Size /Value`) Do If "%%B" NEq "" (
   Call Set _%%A=%%B)
Rem Set/a _FreePercent=%_FreeSpace:~,-3% / %_Size:~,-5%
Set/a _FreePercent=%_FreeSpace:~,-6% / %_Size:~,-8%
If %_FreeSpace:~,-6% lss 214748 (Set/a _FreeSpace=%_FreeSpace:~,-6%*9313/10000
   ) Else (Set/a _FreeSpace=%_FreeSpace:~,-6%/1074*1000)
Echo(Drive %CD:~,2% %_FreeSpace:~,-3% GiB Of Free Space = %_FreePercent%%%^
 available
Pause>Nul
TBH I see no real reason for accuracy when using integer math which rounds down


I have done 3 digit precision for compare with 2 digit precision windows freespace. The error of integer math is not visible until we get range extreme. But there is the REMAINDER if we can go over...

Code: Select all

C: FreeSpace: 1779224576 Byte - 1.656 GiB
D: FreeSpace: 3993055232 Byte - 3.718 GiB
E: FreeSpace: 10647683072 Byte - 9.915 GiB
F: FreeSpace: 6824042496 Byte - 6.355 GiB


Code: Select all

Drive E: 9 GiB Of Free Space = 18% available


The free space on my E: volume is 10647683072 Byte = 10647683072/1024/1024/1024 = 9,9164276123046875 (near 10GiB)

The difference about 9.916 and 9.915 is because the above Table report 9313 and this is truncate.
Real value is 1 / (1024*1024*1024) = 0.00 ... 931322574615478515625....

And for the truncate of %FreeSpace:~,-6%

einstein1969
Last edited by einstein1969 on 29 Apr 2014 12:34, edited 2 times in total.

Dos_Probie
Posts: 233
Joined: 21 Nov 2010 08:07
Location: At My Computer

Re: How to get available hard drive space

#14 Post by Dos_Probie » 29 Apr 2014 12:10

Thanks everyone on the script choices, I know PowerShell and Vbs would do a better job but just wanted to stick with pure batch, anyway will be using the Einstein revised script by Compo which gives me the results from a variable that I am looking for..
DP 8)

Liviu
Expert
Posts: 470
Joined: 13 Jan 2012 21:24

Re: How to get available hard drive space

#15 Post by Liviu » 29 Apr 2014 21:50

I can see that the issue has been resolved to everybody's satisfaction, but still have a side comment on this.
Compo wrote:TBH I see no real reason for accuracy when using integer math which rounds down
While it's true that the builtin integer division truncates (rounds down), it's also easy to use it to "round to nearest", instead.

Code: Select all

set/a truncated = a / b
set/a nearest = (a + b/2) / b

For low precision arithmetics, such as GBs and whole number percents, this is often enough to get integer results right. Below is a rewrite of the code in the original post...

Code: Select all

@echo off & setlocal
for /f "usebackq skip=1" %%X in (`
    wmic logicaldisk where "mediatype='12'" get caption
  `) do call :drive %%X
endlocal & goto :eof

:drive
if "%~1"=="" goto :eof
set "freeB=" & set "sizeB="
for /f "usebackq skip=1 tokens=1,2" %%X in (`
    wmic logicaldisk where "DeviceID='%1'" get freespace^,size
  `) do if not defined freeB (set "freeB=%%X" & set "sizeB=%%Y")
set/a freeMB = %freeB:~0,-6% & set/a sizeMB = %sizeB:~0,-6%
set/a freePCT = (100 * freeMB + sizeMB / 2) / sizeMB
call :mb2gib freeMB freeGiB & call :mb2gib sizeMB sizeGiB
echo Drive %1  %freeGiB% GB free / %sizeGiB% GB size = %freePCT%%% available  (= %freeB% / %sizeB%)
goto :eof

:mb2gib
@rem double 1000/1024 mb->mib correction
set/a %2 = (125 * ((125 * %1 + 64) / 128) + 64) / 128
@rem 1/1024 mib->gib conversion
set/a %2 = (%2 + 512) / 1024
...which gives accurate numbers in the majority of cases up to about 10 TB drives.

For 100% accuracy to the last digit and beyond, see http://www.dostips.com/forum/viewtopic.php?p=20173#p20173. Squashman's link in the second post to the long division.bat still works, despite Judago's site being officially "abandoned" for a while now.

Liviu

Post Reply