none
Batch script to detect drive letter of a USB flash drive. RRS feed

  • Question

  • Hi, 

    can you guys pls help me with a script to detect the USB drive letter of a flash drive. 

    I was searching the forum here and I found one but it does not work. 

    Here is what the script looks like. It is a batch script. 

    @echo off


    setlocal EnableDelayedExpansion

    set PNPDeviceID=4002FDCCE0E4D094

    set Q='wmic diskdrive where "interfacetype='USB' and PNPDeviceID like '%%%PNPDeviceID%%%'" assoc /assocclass:Win32_DiskDriveToDiskPartition'

    echo %Q%

    for /f "tokens=2,3,4,5 delims=,= " %%a in (%Q%) do (

      set hd=%%a %%b, %%c %%d

      call :_LIST_LETTER !hd!)

    goto :_END


    :_LIST_LETTER

    (echo %1 |find  "Disk ") >nul|| goto :_EOF 

    for /f "tokens=3 delims==" %%a in ('WMIC Path Win32_LogicalDiskToPartition  ^|find %1') do set TMP_letter=%%a

    set Part_letter=%TMP_letter:~1,2% 

    echo %Part_letter% %1

    goto :_EOF



    :_END

    :_EOF

    :: *** end

    pause

     

    When I run the above script. I get an error as this. 

    'wmic diskdrive where "interfacetype='USB' and PNPDeviceID like '%4002FDCCE0E4D0

    94%'" assoc /assocclass:Win32_DiskDriveToDiskPartition'

    No Instance(s) Available.

    Press any key to continue . . .

    Can someone pls tell me how to fix this issue. I am executing this script on a Vista machine. 

    The idea is to copy some configuration files from USB drive to the local computer. Since the USB drive letter varies in computers. I need to have a script that detects the drive letter of USB. 

    Thanks

    Mhndr

    Monday, June 7, 2010 9:13 PM

Answers

  • It expected input on the command line.  If you're going to just double-click on it, it needs a tiny bit more code ...

    @echo off
      setlocal
      set vName=%1
      if [%1]==[] set /p vName=Enter volume to search for:
      set n=0
      set ltrs=ABCDEFGHIJKLMNOPQRSTUVWXYZ
     :Loop
      call set ltr=%%ltrs:~%n%,1%%
      set /a n +=1
      vol %ltr%: 2>nul|find /i " %vname%">nul||if %n% lss 26 goto :loop
      if %n% equ 26 (set "ltr="
        echo No matching volume label found.
      ) else (echo Volume %1 is drive %ltr%:)
      endlocal & set ltr=%ltr%
      pause

    Tom Lavedas
    • Marked as answer by Mhndr Monday, June 14, 2010 2:58 PM
    Friday, June 11, 2010 7:48 PM
    Moderator

All replies

  • If you are using exactly the same USB device every time, why not search by volume name (or serial no.) instead?

    I have a script to detect a ramdisk, but that's written in vbscript/jscript.

    Friday, June 11, 2010 5:25 PM
  • can you pls tell me the command to search by volume name?

     

    Friday, June 11, 2010 5:28 PM
  • Here's one way to do it with a batch file ...

     @echo off
      if [%1]==[] echo Volume label input missing & goto :eof
      setlocal
      set n=0
      set ltrs=ABCDEFGHIJKLMNOPQRSTUVWXYZ
     :Loop
      call set ltr=%%ltrs:~%n%,1%%
      set /a n +=1
      vol %ltr%: 2>nul|find /i " %1">nul||if %n% lss 26 goto :loop
      if %n% equ 26 (set "ltr="
        echo No matching volume label found.
      ) else (echo Volume %1 is drive %ltr%:)
      endlocal & set ltr=%ltr%


    Tom Lavedas
    Friday, June 11, 2010 6:29 PM
    Moderator
  • You could run diskpart.exe, then process the output it generates. It's not a particularly elegant method but it will report which disks are USB mass storage devices and what their drive letters are:

    DISKPART> detail disk
    JetFlash Transcend 2GB USB Device
    Disk ID: 40794078
    Type   : USB
    . . .
      Volume ###  Ltr  Label        Fs     Type
      ----------  ---  -----------  -----  ----------
      Volume 4     H    2 GB Flash   NTFS   Removable

    DISKPART> detail disk
    Sony Storage Media USB Device
    Disk ID: C3072E18
    Type   : USB
      Volume ###  Ltr  Label        Fs     Type
      ----------  ---  -----------  -----  ----------
      Volume 5     G    LARGE USB    NTFS   Partition

    To generate the above report I used this command:
    diskpart < diskpart.scr

    The contents of diskpart.scr were:
    select disk 1
    detail disk
    select disk 2
    detail disk

    Friday, June 11, 2010 7:26 PM
  • Do I have to change anything on this script??

    When I run it as is. I get an error. 

     

    The screen closes instantly when I click on the batch file. 

    Friday, June 11, 2010 7:28 PM
  • It expected input on the command line.  If you're going to just double-click on it, it needs a tiny bit more code ...

    @echo off
      setlocal
      set vName=%1
      if [%1]==[] set /p vName=Enter volume to search for:
      set n=0
      set ltrs=ABCDEFGHIJKLMNOPQRSTUVWXYZ
     :Loop
      call set ltr=%%ltrs:~%n%,1%%
      set /a n +=1
      vol %ltr%: 2>nul|find /i " %vname%">nul||if %n% lss 26 goto :loop
      if %n% equ 26 (set "ltr="
        echo No matching volume label found.
      ) else (echo Volume %1 is drive %ltr%:)
      endlocal & set ltr=%ltr%
      pause

    Tom Lavedas
    • Marked as answer by Mhndr Monday, June 14, 2010 2:58 PM
    Friday, June 11, 2010 7:48 PM
    Moderator
  • The screen closes instantly when I click on the batch file. 

    Edit batch file with any common script editor (notepad, etc, etc) and on a separate line append the following

    pause

    on the very last line.  It would be really helpful if we were able to get the output that your program was producing.

    Friday, June 11, 2010 7:49 PM
  • When you test a batch file then it is compulsory to run it off a Command Prompt. If you run it off the Run box then you never see the error messages.

    Note also that the output I posted needs to be massaged in order to extract the drive letters.

    • Proposed as answer by RBode Saturday, November 13, 2010 5:31 PM
    Friday, June 11, 2010 8:42 PM
  • @echo off
    setlocal EnableDelayedExpansion 
    set _Alphabeth=ABCDEFGHIJKLMNOPQRSTUVWXYZ
    
    set _Number=0
    :Loop
    	call set _Letter=%%_Alphabeth:~%_Number%,1%%
    	if "%_Letter%"=="" goto ExitLoop
    	for /f "tokens=*" %%a in ('vol %_Letter%: 2^>nul ^| find " %_Letter% "') do (
    		setlocal
    		set _Volume=%%a
    		set _Volume=!_Volume:* %_Letter% =!
    		set _Volume=!_Volume:* =!
    		set !_Volume!=!_Letter!:
    	)
    	set /a _Number += 1
    Goto :Loop
    :ExitLoop
    set _Alphabeth=
    set _Letter=
    set _Number=
    set _Volume=
    @echo on
    
    if defined Voyager RoboCopy %Voyager%\Programs \\LaCie\openshare\Programs /mir
    

    This snippet creates an environment variable for every volume label which refers to the drive letter.

    The last line is an example (the volume label of my USB drive is: "Voyager")

    I  have tried to make it as multilingual as possible (also knowning that volume names might include spaces)...

    Saturday, November 13, 2010 5:37 PM
  • Let's simplify, shall we?

    @echo off

    for /F "usebackq tokens=1,2,3,4 " %%i in (`wmic logicaldisk get caption^,description^,drivetype 2^>NUL`) do ( if %%l equ 2 ( echo %%i is a USB drive. ) ) Pause




    • Edited by sparky3489 Saturday, November 23, 2013 4:24 AM
    • Proposed as answer by sparky3489 Wednesday, February 22, 2017 5:04 AM
    Friday, November 22, 2013 10:12 PM
  • How would I modify this to find a file in the root drive of the USB stick I'm using. 

    Basically I want this to return just a drive letter that holds this file in its root.

    I would then use that returned letter as a variable to call a USB stick program that may change drive letters as the stick moves to new computers....unless there is a single html or JavaScript coding that would get this done.

    Wednesday, January 28, 2015 1:38 PM
  • Can you put up that code? I need it

    Monday, September 19, 2016 11:34 PM
  • Let's simplify, shall we?

    @echo off

    for /F "usebackq tokens=1,2,3,4 " %%i in (`wmic logicaldisk get caption^,description^,drivetype 2^>NUL`) do ( if %%l equ 2 ( echo %%i is a USB drive. ) ) Pause

    This works fine in Windows full install, but in WinPE it return nothing. Any idea why?

    Seb

    Tuesday, February 21, 2017 12:19 PM
  • If you run it from the USB, this is a simple option. Create a flag file on the USB and then use a FOR command to search the possible drive letters for that file. It works well for me!

    @echo off
    echo 1>flag.txt
    FOR %%G IN (A:,B:,D:,E:,F:,G:,H:,I:,J:,K:,L:,M:,N:,O:,P:,Q:,R:,S:,T:,U:,V:,W:,X:,Y:,Z:,) DO (
    %%G 
    if exist %%G\flag.txt set driveletter=%%G
    )
    cls
    %driveletter%
    del flag.txt
    echo %driveletter%
    pause



    • Proposed as answer by S. Rische Saturday, June 1, 2019 2:53 AM
    • Edited by S. Rische Thursday, June 6, 2019 3:46 PM
    Saturday, June 1, 2019 1:48 AM
  • Replies to half century old posts are unhelpful.  Batch files no longer exist in the modern times.  Please consult you local priest, rrabbi or imam to find out how to join these long dead trends.

    RIP - please abandon necrophilia.  It is bad for you health.  The FDA has placed it on the most deadly risk list.


    \_(ツ)_/

    Saturday, June 1, 2019 1:52 AM
  • On the serious side.  Batch files are obsolete.  This can be done in one line with PowerShell.,

    Get-PsDrive | Where{ $_.Description -eq 'MyUSB'}

    It can also be done with one line in a batch file.  There is never a need to add a file to the drive.


    \_(ツ)_/

    Saturday, June 1, 2019 3:03 AM
  • @echo off

    echo 1>flag.txt
    FOR %%G IN (A:,B:,D:,E:,F:,G:,H:,I:,J:,K:,L:,M:,N:,O:,P:,Q:,R:,S:,T:,U:,V:,W:,X:,Y:,Z:,) DO (
    %%G 
    if exist %%G\flag.txt set driveletter=%%G
    )
    cls
    %driveletter%
    del flag.txt
    echo %driveletter%\NAME OF FILE YOU HAVE IN USB ROOT .EXTENSION
    pause

    If you want it to run the file automatically, you just change the command at the beginning of the second to last line from echo, to startThen erase the pause as it would no longer be necessary. As long as the file you want to open doesn't have any spaces in the name, this should work out fine.

    Before:

    echo %driveletter%\NAME OF FILE YOU HAVE IN USB ROOT .EXTENSION

    After:

    start %driveletter%\NAME OF FILE YOU HAVE IN USB ROOT .EXTENSION


    • Edited by S. Rische Thursday, June 6, 2019 4:11 PM Change of file name
    Saturday, June 1, 2019 3:53 AM
  • Thanks for your input relating to the topic! I meant to use a simple logic based (easier for a newcomer to understand) solution, but yours seems more practical. I recently worked for an 11 billion dollar company that still uses batch files quite often and effectively. Efficient people don't spend lots of $$$ on easy and sufficient solutions. They still run, so people still use them. No doubt a batch file doesn't always cut it for many reasons like security and overall ability, but I digress. Thanks again!
    Thursday, June 6, 2019 4:10 PM
  • I settled on this:

    @Echo off
    setlocal enabledelayedexpansion
    Set "USB="
    REM get removable loaded drives:
    for /f "tokens=1-5" %%a in (
     'wmic logicaldisk list brief'
    ) do if %%b Equ 2 if %%d gtr 0 Set USB=!USB! %%a
    Echo:Usb removable drives:%USB%
    EndLocal&Set USB=%USB:~1%&Goto :Eof

    which works in full Windows as well in WinPE

    Sunday, June 23, 2019 7:33 AM
  • for /f %%i in (
    'powershell "(get-volume | where drivetype -eq removable).driveletter"'
    ) do set USB=%%i
    • Edited by JS2010 Monday, June 24, 2019 3:29 PM
    Sunday, June 23, 2019 8:18 PM
  • While it will work, one does not really want/need powershell in WinPE
    Tuesday, June 25, 2019 1:33 PM
  • It depends.  Powershell 6 ("pwsh") can be run from a file share, by the way, in winpe or netbooted osx.

    • Edited by JS2010 Tuesday, June 25, 2019 3:26 PM
    Tuesday, June 25, 2019 2:49 PM
  • Thanks, good to know!
    Wednesday, June 26, 2019 9:11 PM
  • Well, just been trying powershell 6 & it is not as easy as just run it
    Saturday, July 6, 2019 2:02 PM
  • Aww, there's no get-volume in ps6, if that's what you're saying.

    pwsh -c "(Get-CimInstance win32_logicaldisk | where drivetype -eq 2).deviceid -replace ':'"


    • Edited by JS2010 Saturday, July 6, 2019 3:16 PM
    Saturday, July 6, 2019 2:23 PM