Recently I was asked if it would be possible to show the free space of a disk using only batch files, preferably using numbers only.
Well, of course.
Basically, all we need to show free disk space is the
DIR command, which ends with a disk summary like this:
36 file(s) 107.432 bytes used
178.895.872 bytes free
Create a file called DISKFREE.DAT containing just one line and without a carriage return/line feed at the end of the line.
One way to create such a file, if you are not sure if your editor can create it, is by using the COPY CON command:
COPY CON DISKFREE.DAT CALL DISKFRE3.BAT <Ctrl-Z>
Don't forget the space before <Ctrl-Z>
<Ctrl-Z> means press Ctrl-Z here.
Press <Enter> after <Ctrl-Z> to end COPY CON
Now create the main batch file DISKFREE.BAT:
@ECHO OFF ECHO @ECHO OFF> DISKFRE3.BAT ECHO IF "%%2"=="K" SET DISKFREE=%%1000>> DISKFRE3.BAT ECHO IF NOT "%%2"=="K" SET DISKFREE=%%1>> DISKFRE3.BAT ECHO IF "%%2"=="K" ECHO %%1 %%2>> DISKFRE3.BAT ECHO IF NOT "%%2"=="K" ECHO %%1>> DISKFRE3.BAT COPY DISKFREE.DAT DISKFRE2.BAT DIR %1 | FIND /I "BYTES FREE" >> DISKFRE2.BAT CALL DISKFRE2.BAT DEL DISKFRE2.BAT DEL DISKFRE3.BAT
What it does:
First a secondary batch file DISKFRE3.BAT is created:
ECHO @ECHO OFF> DISKFRE3.BAT ECHO IF "%%2"=="K" SET DISKFREE=%%1000>> DISKFRE3.BAT ECHO IF NOT "%%2"=="K" SET DISKFREE=%%1>> DISKFRE3.BAT ECHO IF "%%2"=="K" ECHO %%1 %%2>> DISKFRE3.BAT ECHO IF NOT "%%2"=="K" ECHO %%1>> DISKFRE3.BAT
DISKFRE3.BAT will look like this:
@ECHO OFF IF "%2"=="K" SET DISKFREE=%1000 IF NOT "%2"=="K" SET DISKFREE=%1 IF "%2"=="K" ECHO %1 %2 IF NOT "%2"=="K" ECHO %1
As you may have noticed, the
"%%1" in DISKFREE.BAT has resulted in
"%1" in DISKFRE3.BAT.
Had we used
"%1" in DISKFREE.BAT then
"%1" would have been interpreted by DISKFREE.BAT before redirection to DISKFRE3.BAT.
This is prevented by using
"%%1" in DISKFREE.BAT.
DISKFRE3.BAT sets the variable %DISKFREE% to %1 multiplied by 1000 instead of adding a "K" (multiplier by 1024) to it, so that the variable %DISKFREE% will contain numbers only. The ECHO command will show a "K" if applicable.
Then DISKFREE.DAT is copied to DISKFRE2.BAT and the last line from the DIR command is appended to it:
COPY DISKFREE.DAT DISKFRE2.BAT DIR %1 | FIND /I "BYTES FREE" >> DISKFRE2.BAT
In our example DISKFRE2.BAT would look like this:
CALL DISKFRE3.BAT 178.895.872 bytes free
When DISKFRE2 is called, it will call DISKFRE2.BAT in turn, which will ignore the spaces preceding the first parameter, and thus display only the amount of free disk space in bytes.
If you want to check if there is enough free space to install your files, DOS batch files won't get you much further than telling you the order of magnitude of the amount of free space.
Using Ziff Davis' BATCHMAN would be a lot easier. Try it, it's a great utility combining lots of features still missing in DOS.
|Note:||Search the examples for batch files that list free space in Windows NT 4 and later.
For Windows XP use this simple WMIC example.
Another example of redirection is a batch file I wrote to lock single user programs when in use on a network.
To remotely logoff a disconnected user from an NT Terminal Server "farm" (several servers transparently clustered together) you need to know which server that user was logged onto, and his/her session ID.
To find the session ID the QUERY USER command can be used.
With the resulting session ID the user can be remotely logged off.
If the user logged on immediately after his/her session crashed, problems may arise with remote logoff. This situation can be recognized by different numbers for the connection and session ID.
The connection ID takes the form ica-16#nn (for 16 bit clients, that is), whereas the session ID is a plain number. If the session ID does not equal the number nn in the connection ID, the user should first logon, and logoff again, himself.
The following batch file takes into account all that, and will only logoff a user if he/she is disconnected and if the connection and session ID's match:
@ECHO OFF IF "%1"=="" GOTO Usage QUERY USER /SERVER:%2 | FIND /I "%1" > TEMP.BAT ECHO IF NOT "ica-16#%%2"=="%%1" LOGOFF %%2 /SERVER:%2 > %1.BAT CALL TEMP.BAT DEL TEMP.BAT DEL %1.BAT GOTO End :Usage ECHO Usage: %0 userid server :End
The following, more sophisticated, version kills all user's disconnected sessions, but only if they do not have any "relevant programs" active. It doesn't need redirection to temporary files at all.
@ECHO OFF :: KillDisc :: Kill all disconnected NT 4 Terminal Server :: sessions, except when running relevant programs :: Version 2.10 :: Written by Rob van der Woude IF NOT "%1"=="" GOTO :Syntax FOR /F "TOKENS=1,2* DELIMS=*- " %%A IN ('QUERY TERMSERVER') DO IF "%%B"=="" CALL :FindDisc %%A GOTO :EOF :FindDisc :: SERVER = %1 ECHO. ECHO Looking for disconnected sessions on server %1 . . . FOR /F "TOKENS=1,2*" %%B IN ('QUERY USER /SERVER:%1 ˆ| FIND " disc "') DO CALL :ChkPrcs %%B %%C %1 GOTO :EOF :ChkPrcs :: USER = %1 :: ID = %2 :: SERVER = %3 ECHO. ECHO Checking relevant processes for %1 on server %3 QUERY PROCESS %1 /SERVER:%3 | FIND /I /V "explorer.exe" | FIND /I /V "winfile.exe" | FIND /I /V "iavlogon.exe" | FIND /I "%1" IF NOT ERRORLEVEL 1 ECHO Skipping logoff for %1 on server %3 IF ERRORLEVEL 1 CALL :KillDisc %1 %2 %3 GOTO :EOF :KillDisc :: USER = %1 :: ID = %2 :: SERVER = %3 ECHO Logging off %1 from server %3 . . . LOGOFF %2 /SERVER:%3 GOTO :EOF :Syntax CLS ECHO. ECHO KillDisc ECHO. ECHO Kill all disconnected NT 4 Terminal Server sessions, ECHO except when running "relevant" programs ECHO. ECHO Version 2.10 ECHO Written by Rob van der Woude ECHO. ECHO Usage: %~n0
By modifying the line
QUERY PROCESS %1 /SERVER:%3 | FIND /I /V "explorer.exe" | FIND /I /V "winfile.exe" | FIND /I "%1"
you can define what you mean by "relevant programs". For example, adding
| FIND /I /V "winword.exe"
between explorer.exe and winfile.exe will even kill sessions with MS-Word active. Be careful, though: this may cause loss of unsaved data!
@ECHO OFF REM Create temporary batch file ECHO @ECHO OFF> REPLY.BAT ECHO SET connect=1>>REPLY.BAT ECHO Checking connection, please wait... ECHO @ECHO OFF> CHKCONN.BAT PING 18.104.22.168 | FIND "Reply from " >>CHKCONN.BAT REM Set "default" value, which may or may not be altered by CHKCONN.BAT SET connect=0 CALL CHKCONN.BAT DEL CHKCONN.BAT DEL REPLY.BAT IF "%connect%"=="0" ECHO You have NO active connection to the internet IF "%connect%"=="1" ECHO You have an active connection to the internet
The following enhanced (simpler) version doesn't need redirection to temporary batch files at all, but uses FIND's return codes instead (enhancement by "Jawade", one of alt.msdos.batch's contributors).
Use the "old" version to learn the use of temporary batch files only.
@ECHO OFF ECHO Checking connection, please wait... PING 22.214.171.124 | FIND "Reply from " > NUL IF NOT ERRORLEVEL 1 ECHO You have an active connection to the internet IF ERRORLEVEL 1 ECHO You have NO active connection to the internet
See the sample batch files that check if their parameter is a valid device name.
Batch file code for DOS as well as for OS/2.