This is probably not what you need at all, as it uses PowerShell, but the “external utilities” are a bit foggy and leave me room for maneuver. In addition, it is essentially single-line.
SETLOCAL FOR /F "usebackq tokens=1,2" %%f IN (`PowerShell -NoProfile -EncodedCommand "CgBnAHcAbQBpACAAVwBpAG4AMwAyAF8ATABvAGcAaQBjAGEAbABEAGkAcwBrACAALQBGAGkAbAB0AGUAcgAgACIAQwBhAHAAdABpAG8AbgA9ACcAQwA6ACcAIgB8ACUAewAkAGcAPQAxADAANwAzADcANAAxADgAMgA0ADsAWwBpAG4AdABdACQAZgA9ACgAJABfAC4ARgByAGUAZQBTAHAAYQBjAGUALwAkAGcAKQA7AFsAaQBuAHQAXQAkAHQAPQAoACQAXwAuAFMAaQB6AGUALwAkAGcAKQA7AFcAcgBpAHQAZQAtAEgAbwBzAHQAIAAoACQAdAAtACQAZgApACwAJABmAH0ACgA="`) DO ((SET U=%%f)&(SET F=%%g)) @ECHO Used: %U% @ECHO Free: %F% " %% f IN ( `PowerShell -NoProfile -EncodedCommand" CgBnAHcAbQBpACAAVwBpAG4AMwAyAF8ATABvAGcAaQBjAGEAbABEAGkAcwBrACAALQBGAGkAbAB0AGUAcgAgACIAQwBhAHAAdABpAG8AbgA9ACcAQwA6ACcAIgB8ACUAewAkAGcAPQAxADAANwAzADcANAAxADgAMgA0ADsAWwBpAG4AdABdACQAZgA9ACgAJABfAC4ARgByAGUAZQBTAHAAYQBjAGUALwAkAGcAKQA7AFsAaQBuAHQAXQAkAHQAPQAoACQAXwAuAFMAaQB6AGUALwAkAGcAKQA7AFcAcgBpAHQAZQAtAEgAbwBzAHQAIAAoACQAdAAtACQAZgApACwAJABmAH0ACgA = "`) DO ((SET U = %% f) & (SET F = %% g)) SETLOCAL FOR /F "usebackq tokens=1,2" %%f IN (`PowerShell -NoProfile -EncodedCommand "CgBnAHcAbQBpACAAVwBpAG4AMwAyAF8ATABvAGcAaQBjAGEAbABEAGkAcwBrACAALQBGAGkAbAB0AGUAcgAgACIAQwBhAHAAdABpAG8AbgA9ACcAQwA6ACcAIgB8ACUAewAkAGcAPQAxADAANwAzADcANAAxADgAMgA0ADsAWwBpAG4AdABdACQAZgA9ACgAJABfAC4ARgByAGUAZQBTAHAAYQBjAGUALwAkAGcAKQA7AFsAaQBuAHQAXQAkAHQAPQAoACQAXwAuAFMAaQB6AGUALwAkAGcAKQA7AFcAcgBpAHQAZQAtAEgAbwBzAHQAIAAoACQAdAAtACQAZgApACwAJABmAH0ACgA="`) DO ((SET U=%%f)&(SET F=%%g)) @ECHO Used: %U% @ECHO Free: %F%
Since the / CMD package is bad in almost everything, I decided to use PowerShell, which is designed for such material and has quick and easy access to WMI.
Here's the PowerShell code:
Get-WMIObject -Query "SELECT * FROM Win32_LogicalDisk WHERE Caption='C:'" ` | % { $f = [System.Math]::Round($_.FreeSpace/1024/1024/1024,1); $t = [System.Math]::Round($_.Size/1024/1024/1024,1); Write-Host ('' + ($t-$f) + ',' + $f); }
This highlights two values ​​separated by a comma. Now, if we could do this in a FOR loop!
PowerShell has a good ability to accept Base64 encoding (to eliminate the need for escaping and make the code difficult to read), so all we need to do is reduce this command as much as possible (reduce the size of the encoded string - strictly thin, not absolutely necessary). I also reduced the sizes to integers that rounded them. This is at least closer than dropping decimal digits.
The reduction of the encoded command and its encoding in PowerShell is as follows:
$code = { gwmi Win32_LogicalDisk -Filter "Caption='C:'"|%{$g=1073741824;[int]$f=($_.FreeSpace/$g);[int]$t=($_.Size/$g);Write-Host ($t-$f),$f} } $enc = [convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($code)) Write-Host $enc
(See PowerShell /? For details).
I expect this to work on any Win7 or Win8 machine. The PoSH code does not depend on any additional functions (with the possible exception of the EncodedCommand bit), so if PoSH is installed on an XP or Vista computer, there is a good chance of it working. I can’t talk about the history of MS pushing PoSH through Windows Update, but I think there is a good chance that this will work everywhere.