You can try something like this. As it, it will not handle cluster size, as to speed operations output of dir command is used to get the file size for each branch to avoid as much partial sums as possible. Then, size occupied by the folders itself is added to the size of the files.
To avoid the problem with batch arithmetic limit of 2^31 max value, a simple pen and paper sum is done. It should handle up to exabytes, but if more is needed, it is configurable.
@echo off
setlocal enableextensions disabledelayedexpansion
call :initAddSize
call :AddSize "%temp%" "*" /s
call :AddSize "%userprofile%\AppData\Local\Microsoft\Windows\Explorer" "thumbcache_*.db"
call :AddSize "c:\thisdoesnotexist" "*" /s
call :GetTotalSize finalSize
echo(
echo(Total space occupied on disk: [%finalSize% bytes]
echo(
endlocal
exit /b
:: AddSize
:: Recursive add file and folder sizes
:AddSize folder [fileMask] [recurse]
:: check if internal variables has been defined and prepare environment
if not defined _add.total call :initAddSize
setlocal enabledelayedexpansion
:: Retrieve and adjust parameters
set "folder=%~1"
if not defined folder set "folder=%cd%"
set "recurse="
if /i "%~3"=="/s" (
set "recurse=/s"
)
set "fileMask="
if /i "%~2"=="/s" (
set "recurse=/s"
) else (
set "fileMask=%~2"
)
if not defined fileMask set "fileMask=*"
:: If folder does not exist, nothing to do
if not exist "%folder%\" ( endlocal & goto :eof )
:: Size files on disk is retrieved from summary in dir command output
:: Lines starting with at least two spaces belong to the summary
if defined debug echo Searching files... [%folder%\%fileMask%]
set "tempSize=0"
for /f "tokens=3,5" %%y in (
'dir /-c /a /w %recurse% "%folder%\%fileMask%" 2^>nul ^| findstr /b /c:" "'
) do if "%%~z"=="" set "tempSize=%%~y"
:: If files has been found, add its size
if not "%tempSize%"=="0" call :doAddSize %tempSize%
:: Get the size on disk of the folders.
:: If recursive search is selected the sum is handled in a variable,
:: with periodic chekcs to avoid possible overflow in batch arithmetics.
:: If not recursive search is selected, size of the folder is only
:: added if all its content is selected (fileMask=*)
if defined debug echo Sizing folders... [%folder%]
set "_fsz=0"
if defined recurse (
for /d /r "%folder%" %%z in (.) do (
set /a "_fsz+=%%~zz"
if !_fsz! gtr 1073741824 (
call :doAddSize !_fsz!
set "_fsz=0"
)
)
if !_fsz! gtr 0 call :doAddSize %_fsz%
) else (
if "%fileMask%"=="*" for /d %%z in ("%folder%") do call :doAddSize %%~zz
)
:: Calc operations done for the current folder.
:: Cleanup and exit
endlocal & set "_add.total=%_add.total%"
goto :eof
:: GetTotalSize
:: Returns the content of the internal variable used to acumulate the
:: sucessive operations. To simplify cacls, it is stored in reverse
:: order, so, we need to reverse it to output
:GetTotalSize [variable]
setlocal enabledelayedexpansion
set "_output="
for /l %%z in (0 1 %_add.precision%) do set "_output=!_add.total:~%%z,1!!_output!"
endlocal & if not "%~1"=="" ( set "%~1=%_output%" ) else echo(%_output%
goto :eof
:: initAddSize
:: Initialize the internal variables used to handle output to console
:: and to acumulate the sucessive sizes.
:initAddSize
:: Initialize variables needed for calcs. By default "only" 20 digits will be handled
:: in operations (10 EB) . If more or less are needed, change variable
set "_add.total=0"
set "_add.precision=20"
goto :eof
:: doAddSize
:: Internal function to handle the adition of values without the problems
:: of arithmetic overflow in batch files.
:: This is nothing more than a pen and paper sum.
:doAddSize size
setlocal enabledelayedexpansion
set "_sz=%~1"
set "_t=%_add.total%"
set "_s=0"
set "_c=0"
set "_o="
for /l %%z in (0 1 %_add.precision%) do (
if defined _sz (
set /a "_s=!_t:~%%z,1!+!_sz:~-1!+!_c!+0"
set "_sz=!_sz:~0,-1!"
set /a "_c=!_s!/10"
set "_o=!_o!!_s:~-1!"
) else if !_c! gtr 0 (
set /a "_s=!_t:~%%z,1!+!_c!+0"
set /a "_c=!_s!/10"
set "_o=!_o!!_s:~-1!"
) else if not "!_t:~%%z,1!"=="" set "_o=!_o!!_t:~%%z,1!"
)
endlocal & set "_add.total=%_o%"
goto :eof