Batch Files

Find Drive Letter of a Volume



Introduction

When an external drive is used on Windows it is not guaranteed to be assigned the same drive letter as the last time it was used. That makes it awkward if you're running a batch file that depends on a certain drive being attached, such as when doing backups, without having to change the drive letter used in the batch file.

Luckily there are several utility commands that return the volume name for a disk drive, among them is Vol and another is the more sophisticated Windows Management Instrumentation Command-line (WMIC).

A Simple Batch file

Vol returns the volume information of a given drive letter. Attaching my backup external drive, which as the volume label "Backup1" to the computer I can see in Explorer that the drive letter is H:. Using

vol H:

at a command prompt returns

Volume in drive H is Backup1
Volume Serial Number is C070-804B

Knowing what the text returned from the utility is, it should be fairly simple to parse it using Find and return the label information. We'll need to check all possible drive letters.

@echo off
for %%a in (a b c d e f g h i j k l m n o p q r s t u v w x y z) do (vol %%a: | find "Backup1"
if not errorlevel 1 set myDrive=%%a:)
if "%myDrive%"=="" (echo Cannot find volume
) else (
echo Drive letter is %myDrive%)
)
pause

What the above batch file does is loop through every letter then uses Find to check the text returned from Vol for the volume name. If it finds it then it sets a variable called MyDrive to the drive letter found to match the volume name.

The output of that file is

The system cannot find the path specified.
The system cannot find the path specified.
The device is not ready.
The system cannot find the path specified.
The system cannot find the path specified.
The system cannot find the path specified.
The system cannot find the path specified.
The system cannot find the path specified.
The system cannot find the path specified.
The system cannot find the path specified.
The system cannot find the path specified.
The system cannot find the path specified.
The system cannot find the path specified.
The system cannot find the path specified.
The system cannot find the path specified.
The system cannot find the path specified.
The system cannot find the path specified.
The system cannot find the path specified.
The system cannot find the path specified.
The system cannot find the path specified.
The system cannot find the path specified.
Drive letter is h:
Press any key to continue . . .

Let's see if we can get rid of the system messages. 0 is stdin, 1 is stdout, and 2 is stderr. We can send a lot of the system messages and errors to the null device using >nul

@echo off
for %%a in (a b c d e f g h i j k l m n o p q r s t u v w x y z) do (vol %%a: 2>nul | find "Backup1" >nul
if not errorlevel 1 set myDrive=%%a:)
if "%myDrive%"=="" (echo Cannot find volume
) else (
echo Drive letter is %myDrive%)
)
pause

The output from the batch file is now

Drive letter is h:
Press any key to continue . . .

The batch file can be reduced a little by using &&, which means carry out the next command if the previous was successful. We can use it to replace the errorlevel test line

@echo off
for %%a in (a b c d e f g h i j k l m n o p q r s t u v w x y z) do vol %%a: 2>nul | find "Backup1" >nul && set myDrive=%%a:
if "%myDrive%"=="" (echo Cannot find volume
) else (
echo Drive letter is %myDrive%)
)
pause

The output from the batch file is still

Drive letter is h:
Press any key to continue . . .

A List of Attached Drives

Wouldn't it be nice if there was some way we could just test the attached drives and not have to go through the entire alphabet? Windows does have a couple of utilities that can do this. One is using the Fsinfo subset of Fsutil. On my computer, the command

fsutil fsinfo drives

returns

Drives: C:\ D:\ E:\ F:\ H:\

The problem is that Fsutil requires that it be run as an administrator, which is not suitable for all occasions. For more information on Fsutil see Microsoft Technet or SS64. For more specific information on Fsutil Fsinfo see Microsoft Technet.

Another command that can get a computers drive letters is Mountvol. Mountvol is used to creates, delete, or list a volume mount point. If used without any parameters it will list the computers drives.

mountvol

gives this output

mountvol

Creates, deletes, or lists a volume mount point.

MOUNTVOL [drive:]path VolumeName
MOUNTVOL [drive:]path /D
MOUNTVOL [drive:]path /L
MOUNTVOL [drive:]path /P
MOUNTVOL /R
MOUNTVOL /N
MOUNTVOL /E

path Specifies the existing NTFS directory where the mount point will reside.
VolumeName Specifies the volume name that is the target of the mount point.
/D Removes the volume mount point from the specified directory.
/L Lists the mounted volume name for the specified directory.
/P Removes the volume mount point from the specified directory, dismounts the volume, and makes the volume not mountable.
You can make the volume mountable again by creating a volume mount point.
/R Removes volume mount point directories and registry settings for volumes that are no longer in the system.
/N Disables automatic mounting of new volumes.
/E Re-enables automatic mounting of new volumes.

Possible values for VolumeName along with current mount points are:

\\?\Volume{49212869-d741-11e2-a5f6-806e6f6e6963}\
C:\

\\?\Volume{a8016890-06d3-11e3-96da-0016d4fcb256}\
F:\

\\?\Volume{7c9501ee-d86b-11e2-bf27-0016d4fcb256}\
H:\

\\?\Volume{49212868-d741-11e2-a5f6-806e6f6e6963}\
D:\

\\?\Volume{4921286c-d741-11e2-a5f6-806e6f6e6963}\
E:\

The output of this can be parsed using Find for just the drive letters and those passed to the Vol command to find and match the volume labels. This means the batch file should be more efficient as it does not have to check every drive letter, just the ones that Mountvol reports as being attached.

@echo off
for /f "tokens=1 delims=\ " %%a in ('mountvol^|find ":\"') do vol %%a 2>nul | find /i "Backup1" >nul 2>&1 && set myDrive=%%a
if "%myDrive%"=="" (echo Cannot find volume
) else (
echo Drive letter is %myDrive%)
)
pause

The output of this batch file is

Drive letter is H:
Press any key to continue . . .

There's a couple of things that need explaining about this batch file

/f mean it is going to process text or a text file
tokens=1 is the first item in a list of items that are delimited by \
^ means the next character is not part of the text to be searched for. Basically it is telling the command processor that the pipe character (|) is a pipe character and not plain text.

More information on Mountvol can be found on Microsoft Technet or SS64.

Windows Management Instrumentation Command-line (WMIC)

Is there a way without having to parse one utility and passing the output to Find then pass the result of that to Vol?

I don't think we can do without the parsing part using find, because I do not know of a utility that returns the drive letter when the volume label is entered. If there was then we wouldn't be writing this batch file. There is a way of getting the information without using Vol and that is by using the Windows Management Instrumentation Command-line (WMIC) utility.

Here's one form of the command

wmic volume get DriveLetter,Label

and that gives

DriveLetter Label
C: SQ004466V01
F: Working
H: Backup1
D:
E:

Here's another form of the command

wmic logicaldisk get caption,volumename

and this gives

Caption VolumeName
C: SQ004466V0
D:
E:
F: Working
H: Backup1
Z:

Notice in the second form the drives are listed alphabetically and include drive Z: which is a network drive on my system. More information can be found about WMIC can be found at Microsoft Technet and SS64.

Using this information a new batch file can be formed:

@echo off
for /f %%a in ('wmic logicaldisk get caption^,volumename^| find "Backup1"') do set myDrive=%%a
if "%myDrive%"=="" (echo Cannot find volume
) else (
echo Drive letter is %myDrive%)
pause

The output of this is:

Drive letter is H:
Press any key to continue . . .

Multiple Drives

For some tasks multiple external drives may be needed. The following batch file uses a For loop to test for the drives in the list and will give an error message if any are not present.

@echo off
For %%a in (Working Backup1 Backup2) do call :fnddrv %%a
goto EOF:

:fnddrv
set ltr=
for /f %%b in ('wmic logicaldisk get caption^,volumename^| find "%1"') do set ltr=%%b

if "%ltr%"=="" goto ERROR
if %1==Working (
set workdrv=%ltr%
goto :EOF)
if %1==Backup1 (
set bkp1drv=%ltr%
goto :EOF)
if %1==Backup2 (
set bkp2drv=%ltr%
goto :Process)

:Error
echo Cannot find %1
echo.
echo Attach correct drive and try again
echo.
pause
exit

:Process
echo Working drive is %workdrv%
echo Backup drive 1 is %bkp1drv%
echo Backup drive 2 is %bkp2drv%
echo.
pause

:EOF

The output of this file, if all three drives are present is:

Working drive is F:
Backup drive 1 is H:
Backup drive 2 is G:

Press any key to continue . . .

Some Words of Warning

The Find utility is used in many of these batch files to find text in the output of other programs such as Vol and Mountvol. Care must be taken that the volume label of the drive you are looking for us not one of the words in the output of these programs.

The volume names must be unique. For example if Find is used to find "back" it will also find "backup."

This page created 15th February 2015, last modified 15th February 2015