Free space in a CMD shell - windows

Is there a way to get the amount of free diskspace of a disk or a folder in a CMD
without having to install some thirdparty applications?
I have a CMD that copies a big file to a given directory and could of course use
the errorlevel return from the copy command, but then I have to wait for the time
it takes to copy the file (eg...to that then the disk is full and the copy operation fails).
I would like to know before I start the copy if it is any idea at all. Tried the DU.EXE utility from Sysinternals, but that show occupied space only.

If you run "dir c:\", the last line will give you the free disk space.
Edit:
Better solution: "fsutil volume diskfree c:"

A possible solution:
dir|find "bytes free"
a more "advanced solution", for Windows Xp and beyond:
wmic /node:"%COMPUTERNAME%" LogicalDisk Where DriveType="3" Get DeviceID,FreeSpace|find /I "c:"
The Windows Management Instrumentation Command-line (WMIC) tool (Wmic.exe)
can gather vast amounts of information about about a Windows Server 2003 as well as Windows XP or Vista. The tool accesses the underlying hardware by using Windows Management Instrumentation (WMI). Not for Windows 2000.
As noted by Alexander Stohr in the comments:
WMIC can see policy based restrictions as well. (even if 'dir' will still do the job),
'dir' is locale dependent.

Using this command you can find all partitions, size & free space: wmic logicaldisk get size, freespace, caption

You can avoid the commas by using /-C on the DIR command.
FOR /F "usebackq tokens=3" %%s IN (`DIR C:\ /-C /-O /W`) DO (
SET FREE_SPACE=%%s
)
ECHO FREE_SPACE is %FREE_SPACE%
If you want to compare the available space to the space needed, you could do something like the following. I specified the number with thousands separator, then removed them. It is difficult to grasp the number without commas. The SET /A is nice, but it stops working with large numbers.
SET EXITCODE=0
SET NEEDED=100,000,000
SET NEEDED=%NEEDED:,=%
IF %FREE_SPACE% LSS %NEEDED% (
ECHO Not enough.
SET EXITCODE=1
)
EXIT /B %EXITCODE%
UPDATE:
Much has changed since 2014. Here is a better answer. It uses PowerShell which is available on all currently supported Microsoft Windows systems.
The code below would be much clearer and easier to understand if the script were written in PowerShell without using cmd.exe as a wrapper. If you are using PowerShell Core, change powershell to pwsh.
SET "NEEDED=100,000,000"
SET "NEEDED=%NEEDED:,=%"
powershell -NoLogo -NoProfile -Command ^
$Free = (Get-PSDrive -Name 'C').Free; ^
if ($Free -lt [int64]%NEEDED%) { exit $true } else { exit $false }
IF ERRORLEVEL 1 (
ECHO "Not enough disk space available."
) else (
ECHO "Available disk space is adequate."
)

df.exe
Shows all your disks; total, used and free capacity. You can alter the output by various command-line options.
You can get it from http://www.paulsadowski.com/WSH/cmdprogs.htm, http://unxutils.sourceforge.net/ or somewhere else. It's a standard unix-util like du.
df -h will show all your drive's used and available disk space. For example:
M:\>df -h
Filesystem Size Used Avail Use% Mounted on
C:/cygwin/bin 932G 78G 855G 9% /usr/bin
C:/cygwin/lib 932G 78G 855G 9% /usr/lib
C:/cygwin 932G 78G 855G 9% /
C: 932G 78G 855G 9% /cygdrive/c
E: 1.9T 1.3T 621G 67% /cygdrive/e
F: 1.9T 201G 1.7T 11% /cygdrive/f
H: 1.5T 524G 938G 36% /cygdrive/h
M: 1.5T 524G 938G 36% /cygdrive/m
P: 98G 67G 31G 69% /cygdrive/p
R: 98G 14G 84G 15% /cygdrive/r
Cygwin is available for free from: https://www.cygwin.com/
It adds many powerful tools to the command prompt. To get just the available space on drive M (as mapped in windows to a shared drive), one could enter in:
M:\>df -h | grep M: | awk '{print $4}'

The following script will give you free bytes on the drive:
#setlocal enableextensions enabledelayedexpansion
#echo off
for /f "tokens=3" %%a in ('dir c:\') do (
set bytesfree=%%a
)
set bytesfree=%bytesfree:,=%
echo %bytesfree%
endlocal && set bytesfree=%bytesfree%
Note that this depends on the output of your dir command, which needs the last line containing the free space of the format 24 Dir(s) 34,071,691,264 bytes free. Specifically:
it must be the last line (or you can modify the for loop to detect the line explicitly rather than relying on setting bytesfree for every line).
the free space must be the third "word" (or you can change the tokens= bit to get a different word).
thousands separators are the , character (or you can change the substitution from comma to something else).
It doesn't pollute your environment namespace, setting only the bytesfree variable on exit. If your dir output is different (eg, different locale or language settings), you will need to adjust the script.

Using paxdiablo excellent solution I wrote a little bit more sophisticated batch script, which uses drive letter as the incoming argument and checks if drive exists on a tricky (but not beauty) way:
#echo off
setlocal enableextensions enabledelayedexpansion
set chkfile=drivechk.tmp
if "%1" == "" goto :usage
set drive=%1
set drive=%drive:\=%
set drive=%drive::=%
dir %drive%:>nul 2>%chkfile%
for %%? in (%chkfile%) do (
set chksize=%%~z?
)
if %chksize% neq 0 (
more %chkfile%
del %chkfile%
goto :eof
)
del %chkfile%
for /f "tokens=3" %%a in ('dir %drive%:\') do (
set bytesfree=%%a
)
set bytesfree=%bytesfree:,=%
echo %bytesfree% byte(s) free on volume %drive%:
endlocal
goto :eof
:usage
echo.
echo usage: freedisk ^<driveletter^> (eg.: freedisk c)
note1: you may type simple letter (eg. x) or may use x: or x:\ format as drive letter in the argument
note2: script will display stderr from %chkfile% only if the size bigger than 0
note3: I saved this script as freedisk.cmd (see usage)

I make a variation to generate this out from script:
volume C: - 49 GB total space / 29512314880 byte(s) free
I use diskpart to get this information.
#echo off
setlocal enableextensions enabledelayedexpansion
set chkfile=drivechk.tmp
if "%1" == "" goto :usage
set drive=%1
set drive=%drive:\=%
set drive=%drive::=%
dir %drive%:>nul 2>%chkfile%
for %%? in (%chkfile%) do (
set chksize=%%~z?
)
if %chksize% neq 0 (
more %chkfile%
del %chkfile%
goto :eof
)
del %chkfile%
echo list volume | diskpart | find /I " %drive% " >%chkfile%
for /f "tokens=6" %%a in ('type %chkfile%' ) do (
set dsksz=%%a
)
for /f "tokens=7" %%a in ('type %chkfile%' ) do (
set dskunit=%%a
)
del %chkfile%
for /f "tokens=3" %%a in ('dir %drive%:\') do (
set bytesfree=%%a
)
set bytesfree=%bytesfree:,=%
echo volume %drive%: - %dsksz% %dskunit% total space / %bytesfree% byte(s) free
endlocal
goto :eof
:usage
echo.
echo usage: freedisk ^<driveletter^> (eg.: freedisk c)

Is cscript a 3rd party app?
I suggest trying Microsoft Scripting, where you can use a programming language (JScript, VBS) to check on things like List Available Disk Space.
The scripting infrastructure is present on all current Windows versions (including 2008).

Related

How to use ECHO to set a variable in batch

I've been wracking my brain trying to figure out a way to use the ECHO command to set the value of a variable in batch.
I'm aware that you can abuse the FOR command to set command output as a variable.
For example:
for /F "delims=" %%A in ('ipconfig ^| findstr /i IPv4') do (set TestVar=%%A)
However, I cannot figure out a way in which to use the ECHO command as the source command which "set" would use as input for the variable.
Does anybody know if there is a way in which to accomplish this?
Here is more info to help clarify my goal.
The purpose of doing this would be so that I can filter the results of a command via findstr and other commands to strip out the characters which I cannot use in the script. I'd be then assigning this stripped output to a variable.
I am creating a batch script with which to sync the contents of any USB drive plugged into a specific system with a source folder on the system. I am trying to make it "smart" in that it will automatically filter out any network drives, etc. Network drives are assigned via GPO, so I don't want to rely on manually updating a drive list pulled from a text file, since forgetting to update such a file could cause a network drive to be overwritten.
I am already able to accomplish this goal by echoing to a "temp.txt" file and then having the script pull from this temp.txt file.
The other catch is that I'm logging the results of each "sync." I do not want it to create false success logs, so I've compiled the script in such a way that a failed sync (failed robocopy) does not proceed to the logging command which is an echo to a text file (assuming that the failure is of a type that robocopy doesn't run at all, it would still log if robocopy ran).
Here's my script if it helps clarify things, as well as a copy of the one config file that I allow to be present.
SCRIPT:
REM This script relies on the "SyncConfig.txt" file to be present in the same directory as this script in order to run successfully.
REM The "SyncConfig.txt" file specifies which drives are eligible to have their contents synced with the Rockwell VM drive.
echo off
cls
color c
echo THIS SCRIPT WILL EFFECTIVELY WIPE ANY DRIVE THAT IS PRESENT
echo WHICH IS NOT SPECIFICALLY EXCLUDED IN THE "SyncConfig.txt"
echo FILE! Press any key to continue or click the "X" to cancel.
pause
color a
set SourceDrive=F:\
setlocal ENABLEDELAYEDEXPANSION
for /F "skip=6 tokens=*" %%A in (SyncConfig.txt) do (
echo %%A| findstr /i /v "Not Included" > temp.txt
for /F %%B in (temp.txt) do (
robocopy /MIR !SourceDrive! %%B:\
echo %Date% > %%B:\LastSynced.txt
for /F %%C in (temp.txt) do (
dir %%C:| findstr /i "Volume" | findstr /i /v "Serial" >> temp.txt
)
for /F "skip=1 tokens=6,7,8,9,10 delims= " %%C in (temp.txt) do (
echo ------------------- >> SyncLog.log
echo %DATE% %TIME% >> SyncLog.log
echo sync performed for: %%C %%D %%E %%F %%G >> SyncLog.log
)
)
)
del temp.txt
endlocal
"CONFIG FILE" - SyncConfig.txt:
Lines which include the text "Not Included" anywhere in the line will be ignored. This is being used |Not Included
to prevent specific drives (such as mapped network shares) from being overwritten by the sync script. |Not Included
|Not Included
|Not Included
DRIVES: |Not Included
----------- |Not Included
A
B
C Not Included
D Not Included
E Not Included
F Not Included
G
H
I
J
K
L Not Included
M
N
O Not Included
P
Q
R
S Not Included
T Not Included
U Not Included
V
W
X
Y
Z

How to use a volume label in a Windows path?

I want to copy files off a removable drive using a batch file, regardless of the drive letter it gets.
So far, no go. There don't seem to be any readily available commands or 3rd-party command-line tools that would handle paths based on volume labels.
I tried FreeFileSync, but it works in big batches, and I need precise file operations here. Also, it doesn't do deletions, and I need to MOVE files off the pendrive.
What piques my interest, however, is that issuing a nonsense command like...
C:\> cd MYPENDRIVE:
... results in quite an interesting bit in the default error message:
The filename, directory name, or volume label syntax is incorrect.
^^^^^^^^^^^^^^^^^^^
If this message is to be trusted, then it means there IS some correct syntax for putting a volume label in there. Or isn't there?
Note: I can settle for writing a small "getdriveletterforvolume" tool, if I have to, but I'd rather not reinvent the wheel. Also, during longer batch file operations the drive may be removed and replaced with another, at which point I'll need the operations to cease, and not continue on another drive that gets the same drive letter.
Note2: Using \\?\Volume{12345678.....} is a last resort, though it can be tamed to some extent, to build a rudimentary batch file like...
SET PENDRIVE=\\?\Volume{949a764e-a2f0-11e3-b710-6cf04975450b}
SET BACKUPDRIVE=\\?\Volume{e79091c4-5c2a-11e3-86f9-806e6f6e6963}
if exist %PENDRIVE% {
if exist %BACKUPDRIVE% {
move %PENDRIVE%\*.* %BACKUPDRIVE%
}
}
... but it's ugly and doesn't let me do any magic like giving two pendrives the same label to have them behave identically. I know it's not a common case, but hey, why limit one's options where there might be a ready solution?
Edit: Progress. I modified the subroutine to return a value as VOLUMEID:
CALL :GetVolumeID PENDRIVE
SET "PENDRIVE=%VOLUMEID%"
IF EXIST "%PENDRIVE%\" ECHO PENDRIVE is connected at %PENDRIVE%!
GOTO :eof
:GetVolumeID
FOR /F "skip=1" %%A in ('"wmic volume where label='%~1' get deviceid 2>/null"') do (
SET "VOLUMEID=%%A"
GOTO :eof
)
GOTO :eof
... but now if the pendrive is missing, wmic returns some empty-like value (NOT an empty string; it fails an if %%A=="" check) - and so IF EXIST \ ends up true. How do I eliminate an empty result like that..? I tried SET VOLUMEID=$FOO$ before the FOR, but it overwrites that with an empty value anyway.
Finally! Here's a proof of concept, for whomever finds it useful.
#ECHO OFF
CALL :GetVolumeID BACKUPDRIVE
SET "BACKUPDRIVE=%VOLUMEID%"
CALL :GetVolumeID PENDRIVE
SET "PENDRIVE=%VOLUMEID%"
if exist %PENDRIVE%\ (
if exist %BACKUPDRIVE%\ (
echo Emptying the pendrive.
move %PENDRIVE%\*.* %BACKUPDRIVE%\pendrive\
)
)
GOTO :eof
:GetVolumeID
SET VOLUMEID=$$$
FOR /F "tokens=1,* delims==" %%A IN ('"wmic volume where label='%~1' get deviceid /value 2>nul"') DO IF NOT "%%~B"=="" SET "VOLUMEID=%%~B"
SET "VOLUMEID=%VOLUMEID:~0,-2%"
GOTO :eof
I added the $ bogus value to be returned to fail an EXIST check.
The final SET VOLUMEID=%VOLUMEID... line removes the trailing backslash (for some reason it counts as TWO characters) so that paths written as %MYDRIVE%\file*.* look sane.
here's a subroutine that will push you to a drive by its name.It takes one argument - the drive label:
#echo off
:pushToLabel label
setlocal
for /f "skip=1 delims=:" %%A in ('"wmic logicaldisk where VolumeName='%~1' get name"') do (
set "drive=%%A:"
goto :break
)
:break
echo %drive%
endlocal && (
pushd %drive%
)
Here's a final proof of concept, for whomever finds it useful. Calling GetVolumeID sets a DRIVELETTER variable as return, in the "F:" form.
#ECHO OFF
CALL :GetVolumeID BACKUPDRIVE
SET "BACKUPDRIVE=%DRIVELETTER%"
CALL :GetVolumeID PENDRIVE
SET "PENDRIVE=%DRIVELETTER%"
if exist %PENDRIVE%\ (
if exist %BACKUPDRIVE%\ (
echo Emptying the pendrive.
move %PENDRIVE%\*.* %BACKUPDRIVE%\pendrive\
)
)
GOTO :eof
:GetVolumeID
SET DRIVELETTER=$$$
FOR /F "tokens=1,* delims==" %%A IN ('"wmic volume where label='%~1' get deviceid /value 2>nul"') DO IF NOT "%%~B"=="" SET "DRIVELETTER=%%~B"
SET "DRIVELETTER=%DRIVELETTER:~0,-2%"
GOTO :eof

How to read net use generated text file and use the net use command to remap the network drive

How to read net use generated text file lets called it network_drive.txt that consist of the current machine mapped network drive as image below:
New connections will be remembered.
Status --- Local --- Remote ------------------ Network
-------------------------------------------------------------------------------
OK ---------- H: ---- \\server\users\john -----
Microsoft Windows Network
OK ---------- Y: ---- \\server\e$\ --------------
Microsoft Windows Network
The command completed successfully.
How to read the file above to map the network drive again with the same Letter path and path only if the status is ok and ignore the unavailable one?
update!
#echo off
set drive=\\server\users\john\
net use > %drive%\%USERNAME%_temp_Networkdrive.txt <-- generating net use file
for /f "skip=6 delims=*" %%a in (%drive%\%USERNAME%_temp_Networkdrive.txt) do (
echo %%a >>%drive%\%USERNAME%_del_Networkdrive.txt ) <-- deleting the first 6 lines
xcopy %drive%\%USERNAME%_del_Networkdrive.txt %drive%\%USERNAME%_Networkdrive.txt /y <-- make a new copy of the network drive file after deleting the lines
findstr /v "The command completed successfully." %drive%\%USERNAME%_del_Networkdrive.txt > %drive%\%USERNAME%_Networkdrive.txt <-- find the string and delete them and make a new copy of file with just the network drives
del %drive%\%USERNAME%_del_Networkdrive.txt /f /q
del %drive%\%USERNAME%_temp_Networkdrive.txt /f /q
for /f "tokens=2,3,4" %%a in (%drive%\%USERNAME%_Networkdrive.txt) do ( net use %%a %%b ) **<-- find the letter path and the drive path and map accordingly.**
however..
in some cases, sometimes the "Microsoft Windows Network" is on the same line as the letter and Drive path and hence deleting the record/line.
can someone help pls?
Update.
I removed Microsoft Windows Network from the findstr line because the tokens in the for loop would only pick up the second and third strings for the net use command.
I have tested it and it works.
Also, it would be a good idea to use if exist command on the second line just to see if the file is exist before running the other commands.
#ECHO OFF
SETLOCAL
FOR /f "tokens=2*delims=: " %%a IN ('type q20294868.txt^|find "\"^|findstr /b "OK"') DO ECHO NET use %%a: %%b
ECHO(======================
FOR /f "tokens=2*delims=: " %%a IN ('type q20294868.txt^|find "\"^|findstr /b "OK"'') DO FOR /f %%c IN ("%%b") DO ECHO NET use %%a: %%c
GOTO :eof
This should do what you appear to want.
You should replace type q20294868.txt with net use for your situation. q20294868.txt is simply a file I used to save your test data.
There are two separate methods here. The text is filtered first for lines containing \ and then for those /b beginning "OK"
I'm unsure whether the network name may potentially be included on a data line rather than on a line by itself, consequently I've devised the second method. The first is simpler, the second more robust.
Note that your original findstr would have eliminated any lines containing ANY of the individual words contained in the quotes - see findstr /? from the prompt for more information.
And of course, the resultant NET USE command is merely ECHOed to the screen, not executed.

Windows batch file to get C:\ drive total space and free space available

I need a bat file to get C:\ drive total space and free space available in GB (giga bytes) in a Windows system and create a text file with the details.
Note: i dont want to use any external utilities.
cut 9 digits of the size by bytes to get the size in GB:
#echo off & setlocal ENABLEDELAYEDEXPANSION
SET "volume=C:"
FOR /f "tokens=1*delims=:" %%i IN ('fsutil volume diskfree %volume%') DO (
SET "diskfree=!disktotal!"
SET "disktotal=!diskavail!"
SET "diskavail=%%j"
)
FOR /f "tokens=1,2" %%i IN ("%disktotal% %diskavail%") DO SET "disktotal=%%i"& SET "diskavail=%%j"
(ECHO(Information for volume %volume%
ECHO(total %disktotal:~0,-9% GB
ECHO(avail. %diskavail:~0,-9% GB)>size.txt
TYPE size.txt
cmd can calculate only with numbers up to 2^31-1   (2,147,483,647 ~ 2.000001 Gigabytes)
Not a complete solution by any means, but someone might find this helpful:
dir | find "bytes"
This is probably not at all what you want since it uses PowerShell, but "external utilities" is a bit nebulous and leaves me some wiggle room. Plus, it's essentially a one-liner.
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 batch/CMD is bad at nearly everything, I decided to use PowerShell, which is meant for such stuff 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 spits out the two values separated by a comma. Now, if only we could do this in a FOR loop!
PowerShell has the nice ability to accept a Base64-encoded command (to eliminate the need for escaping and making the code hard to read), so all we need to do is shrink this command as much as possible (to reduce the size of the encoded string—strictly a nicety, not absolutely necessary). I also reduced the sizes to integers, which rounded them. It's at least closer than discarding the lower-order decimal digits.
Shrinking the encoded command and encoding it in PowerShell looks like this:
$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 more details.)
I would expect this to run on any Win7 or Win8 machine in existence. The PoSH code doesn't rely on any advanced features (except maybe the EncodedCommand bit), so if PoSH is installed on the XP or Vista machine, there's a good chance of it working. I can't speak about the history of MS pushing PoSH via Windows Update, but I think there's a good chance that this will work ubiquitously.
This should work in batch:
for /f "tokens=2" %%S in ('wmic volume get DriveLetter^, FreeSpace ^| findstr "^C:"') do set space=%%S
echo %space%

Windows command for file size only

Is there a Windows command that will output the size in bytes of a specified file like this?
> filesize test.jpg
65212
I know that the dir command outputs this information, but it outputs other information also.
I could easily write such a program, but I would prefer to use a native Windows command if possible, or only what is available in a fresh install of Windows XP.
If you are inside a batch script, you can use argument variable tricks to get the filesize:
filesize.bat:
#echo off
echo %~z1
This gives results like the ones you suggest in your question.
Type
help call
at the command prompt for all of the crazy variable manipulation options. Also see this article for more information.
Edit:
This only works in Windows 2000 and later
If you don't want to do this in a batch script, you can do this from the command line like this:
for %I in (test.jpg) do #echo %~zI
Ugly, but it works. You can also pass in a file mask to get a listing for more than one file:
for %I in (*.doc) do #echo %~znI
Will display the size, file name of each .DOC file.
Use a function to get rid off some limitation in the ~z operator. It is especially useful with a for loop:
#echo off
set size=0
call :filesize "C:\backup\20120714-0035\error.log"
echo file size is %size%
goto :eof
:: Set filesize of first argument in %size% variable, and return
:filesize
set size=%~z1
exit /b 0
Try forfiles:
forfiles /p C:\Temp /m file1.txt /c "cmd /c echo #fsize"
The forfiles command runs command c for each file m in directory p.
The variable #fsize is replaced with the size of each file.
If the file C:\Temp\file1.txt is 27 bytes, forfiles runs this command:
cmd /c echo 27
Which prints 27 to the screen.
As a side-effect, it clears your screen as if you had run the cls command.
Since you're using Windows XP, Windows PowerShell is an option.
(Get-Item filespec ).Length
or as a function
function Get-FileLength { (Get-Item $args).Length }
Get-FileLength filespec
Create a file named filesize.cmd (and put into folder C:\Windows\System32):
#echo %~z1
C:\>FORFILES /C "cmd /c echo #fname #fsize"
C:\>FORFILES /?
FORFILES [/P pathname] [/M searchmask] [/S]
[/C command] [/D [+ | -] {MM/dd/yyyy | dd}]
Description:
Selects a file (or set of files) and executes a
command on that file. This is helpful for batch jobs.
Parameter List:
/P pathname Indicates the path to start searching.
The default folder is the current working
directory (.).
Taken from here:
The following command finds folders that are greater than 100 MB in size on the D: drive:
diruse /s /m /q:100 /d d:
The /s option causes subdirectories to be searched, the /m option displays disk usage in megabytes, the /q:100 option causes folders that are greater than 100 MB to be marked, and the /d option displays only folders that exceed the threshold specified by /q.
Use the diskuse command to find files over a certain size. The following command displays files over 100 MB in size on the D: drive:
diskuse D: /x:104857600 /v /s
The /x:104857600 option causes files over 104,857,600 bytes to be displayed and is valid only if you include the /v option (verbose). The /s option means subdirectories from the specified path (in this case, the D: drive) are searched.
Using VBScript
' This code finds all files over a certain size.
' ------ SCRIPT CONFIGURATION ------
strComputer = "**<ServerName>**"
intSizeBytes = 1024 * 1024 * 500 ' = 500 MB
' ------ END CONFIGURATION ---------
set objWMI = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
set colFiles = objWMI.ExecQuery _
("Select * from CIM_DataFile where FileSize > '" & intSizeBytes & "'")
for each objFile in colFiles
Wscript.Echo objFile.Name & " " & objFile.Filesize / 1024 / 1024 & "MB"
next
This is not exactly what you were asking about and it can only be used from the command line (and may be useless in a batch file), but one quick way to check file size is just to use dir:
> dir Microsoft.WindowsAzure.Storage.xml
Results in:
Directory of C:\PathToTheFile
08/10/2015 10:57 AM 2,905,897 Microsoft.WindowsAzure.Storage.xml
1 File(s) 2,905,897 bytes
0 Dir(s) 759,192,064,000 bytes free
In PowerShell you can do:
$imageObj = New-Object System.IO.FileInfo("C:\test.jpg")
$imageObj.Length
In a batch file, the below works for local files, but fails for files on network hard drives
for %%I in ("test.jpg") do #set filesize=%~z1
However, it's inferior code, because it doesn't work for files saved on a network drive (for example, \\Nas\test.jpg and \\192.168.2.40\test.jpg). The below code works for files in any location, and I wrote it myself.
I'm sure there are more efficient ways of doing this using VBScript, or PowerShell or whatever, but I didn't want to do any of that; good ol' batch for me!
set file=C:\Users\Admin\Documents\test.jpg
set /a filesize=
set fileExclPath=%file:*\=%
:onemoretime
set fileExclPath2=%fileExclPath:*\=%
set fileExclPath=%fileExclPath2:*\=%
if /i "%fileExclPath%" NEQ "%fileExclPath2%" goto:onemoretime
dir /s /a-d "%workingdir%">"%temp%\temp.txt"
findstr /C:"%fileExclPath%" "%temp%\temp.txt" >"%temp%\temp2.txt"
set /p filesize= <"%temp%\temp2.txt"
echo set filesize=%%filesize: %fileExclPath%%ext%=%% >"%temp%\temp.bat"
call "%temp%\temp.bat"
:RemoveTrailingSpace
if /i "%filesize:~-1%" EQU " " set filesize=%filesize:~0,-1%
if /i "%filesize:~-1%" EQU " " goto:RemoveTrailingSpace
:onemoretime2
set filesize2=%filesize:* =%
set filesize=%filesize2:* =%
if /i "%filesize%" NEQ "%filesize2%" goto:onemoretime2
set filesize=%filesize:,=%
echo %filesize% bytes
SET /a filesizeMB=%filesize%/1024/1024
echo %filesizeMB% MB
SET /a filesizeGB=%filesize%/1024/1024/1024
echo %filesizeGB% GB
In PowerShell you should do this:
(Get-ChildItem C:\TEMP\file1.txt).Length
I'm not sure about remote ones, but for local Windows trough {File Sharing / Network}, %~z does work
for %%x in ("\\ComputerName\temp\temp.txt") do set "size=%%~zx"
More generalized version of this . The previous version may be not requiring enableDelayedExpansion enableExtensions, but can't run in for loops .
Some clarification --
| can't be used to pass an output value to set ; for /f doesn't support some characters in it's subject value (the path to edit), if without in-text Escaping ; for /l doesn't allow to change the count/condition values (after start) ; !<<variableName>>:<<escaped text>>*! doesn't work .
at keepOnlyAllBefore1stSpace, %%%%x is passed instead of !nu_f!, because that is needed for the same reason/use as %%%%x is made to be created .
#setLocal enableDelayedExpansion enableExtensions
#echo off
set "file=C:\Users\Admin\Documents\test.jpg"
for %%x in ("!file!") do set "name=%%~nxx"
for %%x in ("!file!") do set "storage=%%~pdx"
set "storage=!storage:~0,-1!"
dir "!storage!" > "!temp!\fileInfo.txt"
findstr /c:"!name!" "!temp!\fileInfo.txt" > "!temp!\fileInfo_1.txt"
del "!temp!\fileInfo.txt"
set /p "size=" < "!temp!\fileInfo_1.txt"
del "!temp!\fileInfo_1.txt"
call :for 1 2 "call :deleteCollumnFromStart size"
call :for 1 1 "call :keepOnlyAllBefore1stSpace %%%%x size"
:removeSpacesFromEnd
if /i "!size:~-1!" equ " " set "size=!size:~0,-1!"
if /i "!size:~-1!" equ " " goto removeSpacesFromEnd
echo(!size:,= ! bytes
pause
exit /b
:deleteCollumnFromStart
set "%~1=!%~1:* =!"
:removeAllSpacesFromStart
if /i "!%~1:~0,1!" equ " " set "%~1=!%~1:~1!"
if /i "!%~1:~0,1!" equ " " goto removeAllSpacesFromStart
goto :eof
:keepOnlyAllBefore1stSpace
if /i "!%~2:~%~1,1!" equ " " (
set "%~2=!%~2:~0,%~1!"
) else (
set /a "nu1_f= !nu1_f! + 1"
)
goto :eof
:for
set "nu_f=%~1"
set "nu1_f=%~2"
:f_repeatTimes
if not !nu1_f! lss !nu_f! (
rem echo(f_repeatTimes !nu_f! !nu1_f! %*
for %%x in (!nu_f!) do (
%~3
)
set /a "nu_f= !nu_f! + 1"
goto f_repeatTimes
)
goto :eof
wmic datafile where name='c:\\windows\\system32\\cmd.exe' get filesize /format:value

Resources