windowsbatch-filecmdremovable-storagedrive-letter

Detecting Removable drive letter in CMD


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."?


Solution

  • 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

    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
    
    ==>