Detecting Removable drive letter in CMD

2019-05-21 09:39发布

问题:

I'm trying to write a script, which will detect the letter of my USB Removable Drive called "UUI" and then create folder on it. I've written few commands for CMD which, when run separately, work. However when I put them into a bat file, I always get some errors. Here are the commands in a bat file:

for /F "tokens=1 delims= " %i in ('WMIC logicaldisk where "DriveType=2" list brief ^| c:\windows\system32\find.exe "UUI"') do (echo %i > drive.txt)
set /p RemovableDriveLetter2= < drive.txt
del /F /Q drive.txt
set RemovableDriveLetter=%RemovableDriveLetter2:~0,1%
%RemovableDriveLetter%:
md MyNewFolder
cd MyNewFolder

When I go to cmd.exe and run the file by calling "myScript.bat" or "call myScript.bat", I get an error:

C:\Users\UUI\Desktop>myScript.bat

\windows\system32\find.exe was unexpected at this time.

C:\Users\UUI\Desktop>for /F "tokens=1 delims= " \windows\system32\find.exe "UUI"') do (echo i > drive.txt)

C:\Users\UUI\Desktop>

I can see that MyNewFolder was not created. However, when I copy all lines and run them in CMD as such (e.g. not in the .bat file) and run them one by one, it is fully functional within the cmd.exe instance.

How can I create bat a file, which will successfully run and detects the drive letter of my removable drive without issues? Or how can I solve the error "\windows\system32\find.exe was unexpected at this time."?

回答1:

You need to double the % sign used to mark a FOR loop control variable in a batch script (.bat or .cmd), i.e. use %%i instead of %i used in pure CLI.

However, there is another possible approach how-to parse wmic output. See also Dave Benham's WMIC and FOR /F: A fix for the trailing <CR> problem

@echo OFF
SETLOCAL enableextensions
set "USBCounter=0"
for /F "tokens=2 delims==" %%G in ('
    WMIC logicaldisk where "DriveType=2" get DeviceID /value 2^>NUL ^| find "="
') do for /F "tokens=*" %%i in ("%%G") do (
    set /A "USBCounter+=1"
    echo %%i
    rem your stuff here
)
echo USBCounter=%USBCounter%
rem more your stuff here
ENDLOCAL
goto :eof

Here the for loops are

  • %%G to retrieve the DeviceID value;
  • %%i to remove the ending carriage return in the value returned: wmic behaviour: each output line ends with 0x0D0D0A (CR+CR+LF) instead of common 0x0D0A (CR+LF).

One could use Caption or Name instead of DeviceID:

==>WMIC logicaldisk where "DriveType=2" get /value | find ":"
Caption=F:
DeviceID=F:
Name=F:

Note there could be no or more disks present having DriveType=2:

==>WMIC logicaldisk where "DriveType=2" get /value | find ":"
No Instance(s) Available.

==>WMIC logicaldisk where "DriveType=2" list brief
DeviceID  DriveType  FreeSpace   ProviderName  Size        VolumeName
F:        2          2625454080                3918512128  HOMER
G:        2          999600128                 1029734400  LOEWE

Script output for no, then one and then two USB drive(s), respectively:

==>D:\bat\SO\31356732.bat
USBCounter=0

==>D:\bat\SO\31356732.bat
F:
USBCounter=1

==>D:\bat\SO\31356732.bat
F:
G:
USBCounter=2

==>