Tuesday, July 10, 2012

Assign Drive Letters by Volume Name in Batch

I ran across a problem with my backup software and USB drives a while back. Namely, when I changed out the drives they would sometimes randomly change the drive letter, since the backup was looking for a specific path E:\ or whatever it would fail. Failed backups are of no use to me. I don't want to take the time to go plug in the backup drives, then log into the server and check to make sure they have the proper drive letter assigned. It's a repetitive task the does not offer me any gained value.

The biggest hassle of this is that I use diskpart. Microsoft has seen fit to have diskpart not display the same output two times in a row when running diskpart and not keeping it open. So if you run diskpart and output volumes list, then close it and run it again you're going to get two different outputs, same data, different order. Long story short you have to keep diskpart running somewhere in the background to get the output of commands to be the same.


@echo off
Set mm=%date:~4,2%
Set dd=%date:~7,2%
Set yyyy=%date:~10,4%
Set h=%time:~0,2%
if "%h:~0,1%"==" " set h=0%time:~1,1%
set m=%time:~3,2%
start /min diskpart.exe
diskpart /s script.txt > output.txt
for /f "tokens=3,4 delims= " %%a in (output.txt) do if /i %%b==VOLUMENAME if /i %%a==G goto end1
for /f "tokens=3,4 delims= " %%a in (output.txt) do if /i %%b==VOLUMENAME if /i not %%a==G goto AssignG
echo Assigning G
for /f "tokens=1,2 delims= " %%a in ('type output.txt ^| find /i "VOLUMENAME"') do echo select %%a %%b > assigng.txt
echo assign letter = G >> assigng.txt
diskpart /s assigng.txt
del /f/ q assigng.txt
echo %mm%/%dd%/%yyyy% %h%:%m% >> logs.txt
echo Drive letter was changed and should be assigned properly >> logs.txt
taskkill /f /im diskpart.exe
del /f /q output.txt
echo %mm%/%dd%/%yyyy% %h%:%m% >> logs.txt
echo drive letter assigned properly >> logs.txt
taskkill /f /im diskpart.exe
del /f /q output.txt

The beginning part is just some log keeping I like to do, sets variables with the date and time.

Then we start our background diskpart, this allows us to get consistent output from diskpart. The diskpart script (diskpart /s script.txt) is simply "list volume", basically dumping a list of all volumes currently on the system.

Next we do some checks to see if VOLUMENAME (replace with the name of the volume you're looking for) matches the letter it needs to be (in this case G).
If everything is proper and VOLUMENAME is assigned the drive letter G then it writes the output to the log file and exits.
If something has gone awry and VOLUMENAME is not assigned to G then it set off to change it in the :AssignG

AssignG sets to writing out a diskpart script to change the drive letter to G. It then starts diskpart /s assigng.txt to do the actual work, then does a bit of logging to tell me that it had to change it.
Then it kills the background diskpart task, as we can't have these things running about wild.

That's is. It's handy. One less thing I have to do everyday. Less repetitive tasks are better, that leaves more time for mayhem.


  1. i assigned a letter "A" for a drive. Now that drive is shown before "C" drive in my computer. Now please tell me how do i set "C' drive as first drive in my computer using cmd or diskpart without removing the that letter "A"

  2. Well, first off you should never assign a drive the letter A unless it's a floppy disk drive.

    Other than that there's no way I know of to change the order that they appear as it's assigned by alphabetical order.

    tl;dr - Pick a different letter to assign to the drive.


All comments moderated.
Comments like "sweet dude" or "this is awesome" or "thanks" will be denied,
if you've got something genuinely interesting to say, say it. Other than that just sit back and bask in the glory.