Get Drive-Letter of Storage Drive By Name/ID in Python

2.8k Views Asked by At

I am trying to create some code that checks if a drive is connected and then edits files on that drive if it is. The issue is that the letter associated with that drive will not always be the same. Is there some way I can check if a drive with a given 'name' is connected or not and then get the letter for this drive similar to what this person is asking? Like if the drive I'm interested in is called Backup Drive, then could I check if a drive by this name is connected or not and find its assigned letter if it is? Or is there some sort of hardware ID specific to that drive that can accomplish the same thing?

Ultimately, I could also just go through every drive connected checking if a specific directory exists or not to find the letter assignment as well, but that's a rather obtuse solution and I'd like to avoid it if I can.

I'd also prefer that this be done in Python as that is what the rest of my code is in, but if a solution exists in Powershell or something else then I would consider outsourcing the work. I'm also happy to have a solution that is platform-dependent and works only on Windows as that is what I'm working in.

3

There are 3 best solutions below

3
On BEST ANSWER

Did you try using the WMI module?

import wmi

DRIVE_TYPES = {
  0 : "Unknown",
  1 : "No Root Directory",
  2 : "Removable Disk",
  3 : "Local Disk",
  4 : "Network Drive",
  5 : "Compact Disc",
  6 : "RAM Disk"
}

c = wmi.WMI ()
for drive in c.Win32_LogicalDisk ():
    # prints all the drives details including name, type and size
    print(drive)
    print (drive.Caption, drive.VolumeName, DRIVE_TYPES[drive.DriveType])
0
On

In Python 3.12, there is now a listdrives function. you can make use of this

  • Add os.listdrives(), os.listvolumes() and os.listmounts() functions on Windows for enumerating drives, volumes and mount points. (Contributed by Steve Dower in gh-102519.)

https://docs.python.org/3/library/os.html#os.listdrives

0
On

For anyone who might have this problem in the future (and for my own future reference on this issue), this answer compiles details from answers by Thaer A on this thread and Felix Heide here into a more comprehensive way of finding a drive based on its volume name.

So let's assume you have a drive with the name Backup Drive that you do not know the letter of, or whether or not the drive is even connected. You would do the following:

First, to check if the drive is connected we will create a list of all the drive names that are connected to check if any match Backup Drive later on and a list of all of the drive letters for later use. It is also worth noting that it's probably not a bad idea to use strip and lower for much of this process, but I'm not going to bother with that here (at least for now). So we get:

looking_for = "Backup Drive"
drive_names = []
drive_letters = []

Next, let's set up our WMI object for later:

import wmi
c = wmi.WMI()

Now we loop through all of the connected drives and fill in our two lists:

for drive in c.Win32_LogicalDisk ():
    drive_names.append(str(drive.VolumeName))
    drive_letters.append(str(drive.Caption))

We can also backwards verify here with the win32api module by checking if

win32api.GetVolumeInformation(str(drive.Caption) + "\\")[0]

is equal to drive.VolumeName.

Then we can check if the drive is connected or not and print the drive letter if it is:

if looking_for not in drive_names:
    print("The drive is not connected currently.")
else:
    print("The drive letter is " + str(drive_letters[drive_names.index(looking_for)]))

So in total, also adding in strip and lower very liberally, we get:

import wmi
import win32api, pywintypes # optional

looking_for = "Backup Drive"
drive_names = []
drive_letters = []

c = wmi.WMI()
for drive in c.Win32_LogicalDisk ():
    drive_names.append(str(drive.VolumeName).strip().lower())
    drive_letters.append(str(drive.Caption).strip().lower())
    #    below is optional
    #    need a try catch because some drives might be empty but still show up (like D: drive with no disk inserted)
    try:
        if str(win32api.GetVolumeInformation(str(drive.Caption) + "\\")[0]).strip().lower() != str(drive.VolumeName).strip().lower():
            print("Something has gone horribly wrong...")
    except pywintypes.error:
        pass

if looking_for.strip().lower() not in drive_names:
    print("The drive is not connected currently.")
else:
    print("The drive letter is " + str(drive_letters[drive_names.index(looking_for.strip().lower())]).upper())