0

This code returns the disk size and space in GB. The problem is, it's only using C and i have to hard-code it.

What i'm trying is, it should iterate over all of the disks and i shouldn't have to write the disk part myself. All of my experiments were failure, i couldn't solve.

for /f "tokens=1-3" %%n in ('"WMIC LOGICALDISK GET Name,Size,FreeSpace | find /i "C:""') do set free=%%n& set total=%%p
set free=%free:~0,-3%
set /a free=%free%/1049
set total=%total:~0,-3%
set /a total=%total%/1049

set /a free=%free%/1024
echo C: Space Free- %free% GB
set /a total=%total%/1024
echo C: Space total- %total% GB
  • One thing to consider: Not every drive needs to have a drive letter, you can mount them into directories – Marged Mar 04 '20 at 06:29

3 Answers3

2

Something like this? It is a little sloppy but I think it does what you are asking for using the batch you (mostly) wrote.

I am using a batch function to get the variables out of the for /f loop. You could have also used delayed expansion. I find the whole !syntax! annoying but it seems that most people prefer it to batch functions.

@echo off

for /f "tokens=1-3" %%n in ('"WMIC LOGICALDISK GET Name,Size,FreeSpace"') do call :calculate "%%n" "%%o" "%%p"
goto :EOF 

:calculate
set free=%~1
set drive=%~2
set total=%~3

if "%drive%"=="" goto :EOF
if not "%drive:~1%"==":" goto :EOF
echo ---- information for drive %drive% ----
set free=%free:~0,-3%
set /a free=%free%/1049
set total=%total:~0,-3%
set /a total=%total%/1049
set /a free=%free%/1024
echo Free- %free% GB
set /a total=%total%/1024
echo Total- %total% GB
goto :EOF
Señor CMasMas
  • 4,290
  • 2
  • 14
  • 21
  • 1
    Using `powershell -NoLogo -NoProfile -Command "Get-CimInstance -ClassName CIM_LogicalDisk"` will produce what you seek. That can be worked in to a .bat file script with some added decorations. – lit Mar 03 '20 at 17:16
1

Below is part of a script i've previously written to grab drive information that is echoed to screen, written to a text file and also into a CSV.

@echo off
set "pathBackup=C:\backup"
set "infoFileName=%computername%_DriveSize.txt"
set "csvFile=All_DriveSizes.csv"

::Fix for CSV format output error on some systems
if exist "%WINDIR%\System32\wbem\en-us\csv.xsl" (
    set csvformat="%WINDIR%\System32\wbem\en-us\csv"
) else (
    set csvformat=csv
)

:: Get Drive Partition information
echo.             - Looking for Drive sizes
setlocal EnableDelayedExpansion
for /f "skip=2 tokens=2-5 delims=," %%a in ('wmic logicaldisk where (DriveType^="3"^) get DeviceID^,FreeSpace^,Size^,VolumeName /format:%csvformat%') do (
    set "diskID=%%a"
    set "diskSpace=%%b"
    set "diskSize=%%c"
    set "diskName=%%d"
    set /a diskSize1=!diskSize:~0,-4! / 107374
    if "0"=="!diskSize1!" (
        set /a diskSize1=!diskSize! / 1048576
        set diskSize1=0.!diskSize1:~0,-2!
    )
    set /a diskSpace1=!diskSpace:~0,-4! / 107374
    if "0"=="!diskSpace1!" (
        set /a diskSpace1=!diskSpace! / 1048576
        set diskSpace1=0.!diskSpace1:~0,-2!
    )
    set driveSizes=!driveSizes!"[%%a] %%d (!diskSize1!:!diskSpace1!)",
)

endlocal&if "_%~2"=="_" (set driveSizes=%driveSizes:~0,-1%)
:: Create non CSV variable for use in CSV file creation
set driveSizescsv=%driveSizes:"=%
set driveSizescsv="%driveSizescsv%"

The bit that echos to screen and writes to text file...

echo PC Drives : [Drive] Label (Size GB:Free GB)>>"%pathBackup%\%infoFileName%"
echo PC Drives : [Drive] Label (Size GB:Free GB)
:: Write individual drives one at a time
setlocal EnableDelayedExpansion
for %%i in (%driveSizes:,= %) do (
    set driveSizes1=%%i
    echo.            !driveSizes1:"=!
    set driveSizes2=!driveSizes1:"=!
    echo.            !driveSizes2!>>"%pathBackup%\%infoFileName%"
)
endlocal

The bit that writes to a csv

echo %computername%,%driveSizescsv% >>"%pathBackup%\%csvfile%"

Output example..

PC Drives : [Drive] Label (Size GB:Free GB)
            [C:] Windows (79:42)
            [D:] Database Volume (599:90)
            [E:] Log File (39:31)
Durry42
  • 401
  • 3
  • 10
0

As the command can take a while, and arithmetic can be particularly tricky in pure batch, here are a couple of additional options for you, which leverage other built-in scripting languages:

This complete uses :

@"%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoP^
 "[System.IO.DriveInfo]::GetDrives()|?{$_.IsReady -Eq $True}|"^
 "Select @{N='Drive';E={$_.Name.TrimEnd('\')}},"^
 "@{N='Size (GiB)';E={[Double]('{0:N2}' -F ($_.TotalSize/1GB))}},"^
 "@{N='Free (GiB)';E={[Double]('{0:N2}' -F ($_.AvailableFreeSpace/1GB))}}|FL
@"%__AppDir__%timeout.exe" /T 5 /NoBreak>NUL

And this even quicker uses the engine of :

<!-- :
@"%__AppDir__%cscript.exe" //NoLogo "%~f0?.wsf"
@"%__AppDir__%timeout.exe" /T 5 /NoBreak>NUL
@Exit /B
-->
<Job><Script Language="VBScript">
Set o=CreateObject("Scripting.FileSystemObject")
For Each Drv In o.Drives:If Drv.IsReady=True Then
  WScript.Echo "Drive="&Drv.DriveLetter&":"&VBCrLf&_
  "Size="&Round(Drv.TotalSize/1073741824,2)&" GiB"&VBCrLf&_
  "Free="&Round(Drv.FreeSpace/1073741824,2)&" GiB"
End If:Next
</Script></Job>
Compo
  • 36,585
  • 5
  • 27
  • 39