Batch script doesn't run, although its code runs in CMD
Batch script doesn't run, although its code runs in CMD
I was looking for an easy way to get the system volumes info in GB (batch) so I got this:
for /f "tokens=1-3" %a in ('WMIC LOGICALDISK GET FreeSpace^,Name^,Size ^|FINDSTR /I /V "Name"') do @echo wsh.echo "%b" ^& " free=" ^& FormatNumber^(cdbl^(%a^)/1024/1024/1024, 2^)^& " GiB"^& " size=" ^& FormatNumber^(cdbl^(%c^)/1024/1024/1024, 2^)^& " GiB" > %temp%tmp.vbs & @if not "%c"=="" @echo(& @cscript //nologo %temp%tmp.vbs >> c:testtest2.txt | type C:testtest2.txt
It works fine if I just copy and paste it to the CMD but if I run it from a .bat file it just don't do anything.
What could I be doing wrong?
PD: I can't use PowerShell, I need it in batch.
Batch files require the
%
-signs for all for
meta-variables to be doubled, like %%a
, for instance... By the way, I don't understand the | type C:testtest2.txt
; shouldn't it actually read & type C:testtest2.txt
?– aschipfl
2 days ago
%
for
%%a
| type C:testtest2.txt
& type C:testtest2.txt
I can't use powershell because I need to run this on different machines and some of them have powershell disabled. @aschipfl I'll add the missing %, If I use "&" symbol it actually displays the output two times but if I use " | " it displays the output 1 time as it should be. Not sure if "| " is not a valid symbol, I'm a linux guy and this is my first time dealing with windows scripts.
– Oscar Salas
2 days ago
Related: Get size of a directory in 'MB' using batch file. By the way, you should not query the
Name
but the DeviceID
value; see also this SU post...– aschipfl
2 days ago
Name
DeviceID
1 Answer
1
There are the following issues in your code:
for
%
cmd
%a
%%a
wmic
findstr /V
skip=1
for /F
Name
DeviceID
Name
Caption
DeviceID
wmic LogicalDisk
where "DriveType=3"
if
for /F
>
>>
type
type
|
&
type
echo(
Correcting all these things lead to a batch script like this (I do not write it all in a single line for readability):
> "C:testtest2.txt" (
for /F "skip=1 tokens=1-3" %%a in ('
wmic LogicalDisk where "DriveType=3" get DeviceID^,FreeSpace^,Size
') do @(
if not "%%c"=="" (
> "%TEMP%tmp.vbs" echo WScript.Echo "%%a" ^& " free=" ^& FormatNumber^(CDbl^(%%b^) / 1024 / 1024 / 1024, 2^) ^& " GiB" ^& " size=" ^& FormatNumber^(CDbl^(%%c^) / 1024 / 1024 / 1024, 2^) ^& " GiB"
CScript //NoLogo "%TEMP%tmp.vbs"
)
)
)
type "C:testtest2.txt"
del "%TEMP%tmp.vbs"
The whole approach could be improved though:
for /F
echo
^&
::::
exit /B
findstr
for /F
So this is what I mean:
> "%TEMP%tmp.vbs" (for /F "tokens=* delims=:" %%z in ('findstr /B "::::" "%~f0"') do @echo/%%z)
> "C:testtest2.txt" (
for /F "skip=1 tokens=1-3" %%a in ('
wmic LogicalDisk where "DriveType=3" get DeviceID^,FreeSpace^,Size
') do @(
if not "%%c"=="" CScript //NoLogo "%TEMP%tmp.vbs" "%%a" "%%b" "%%c"
)
)
type "C:testtest2.txt"
del "%TEMP%tmp.vbs"
exit /B
::::If WScript.Arguments.Count < 3 Then WScript.Quit 1
::::WScript.Echo WScript.Arguments.Item(0) & _
:::: " free=" & FormatNumber(CDbl(WScript.Arguments.Item(1)) / 1024 / 1024 / 1024, 2) & " GiB" & _
:::: " size=" & FormatNumber(CDbl(WScript.Arguments.Item(2)) / 1024 / 1024 / 1024, 2) & " GiB"
You could even avoid a temporary file holding the VBScript code when applying the technique demonstrated in this thread: Is it possible to embed and execute VBScript within a batch file without using a temporary file?
(Refer also to these Microsoft articles: Using Windows Script Files (.wsf), and How Come You Guys Don’t Use .WSF Files?.)
<!-- :Batch script section
> "C:testtest2.txt" (
for /F "skip=1 tokens=1-3" %%a in ('
wmic LogicalDisk where "DriveType=3" get DeviceID^,FreeSpace^,Size
') do @(
if not "%%c"=="" CScript //NoLogo "%~f0?.wsf" "%%a" "%%b" "%%c"
)
)
type "C:testtest2.txt"
exit /B
---- WSF script section -->
<job>
If WScript.Arguments.Count </job>
And here is yet another approach that does not use a temporary VBScript file, applying the method illustrated in this thread: HTA & Batch Hybrid, passing variables from BATCH section. The disadvantage of this is brief flickers of HTA windows appearing and disappearing.
(Refer also to this Microsoft article: HTML Applications (HTAs).)
<!-- ::Batch script section ----
> "C:testtest2.txt" (
for /F "skip=1 tokens=1-3" %%a in ('
wmic LogicalDisk where "DriveType=3" get DeviceID^,FreeSpace^,Size
') do @(
if not "%%c"=="" set "DeviceID=%%a" & set "FreeSpace=%%b" & set "Size=%%c" & MSHTA "%~f0"
)
)
type "C:testtest2.txt"
exit /B
---- ::HTA script section -->
Set Env = CreateObject("WScript.Shell").Environment("Process")
Set StdOut = CreateObject("Scripting.FileSystemObject").GetStandardStream(1)
If Not Env("DeviceID") = "" Then
StdOut.WriteLine(Env("DeviceID") & _
" free=" & FormatNumber(CDbl(Env("FreeSpace")) / 1024 / 1024 / 1024, 2) & " GiB" & _
" size=" & FormatNumber(CDbl(Env("Size")) / 1024 / 1024 / 1024, 2) & " GiB")
End If
Set StdOut = Nothing
Set Env = Nothing
Close()
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
That's not batch, it's a fruitless attempt to write vbs in a single line pass values to it wrap that in a for /f processing wmic output. wmic can return proper values but batch is limited to signed 32bit calculations what's +/-2GB. Why can't you use PowerShell? There were 2 similar questions the last two days. Use the search box above.
– LotPings
2 days ago