Search code examples
pythonwindowswindows-shellnetwork-drive

How to find a unassigned drive letter on windows with python


I needed to find a free drive letter on windows from a python script. Free stands for not assigned to any physically or remote device.

I did some research and found a solution here on stackoverflow (cant remember the exact link):

# for python 2.7
import string
import win32api

def getfreedriveletter():
    """ Find first free drive letter """
    assigneddrives = win32api.GetLogicalDriveStrings().split('\000')[:-1]
    assigneddrives = [item.rstrip(':\\').lower() for item in assigneddrives]
    for driveletter in list(string.ascii_lowercase[2:]):
        if not driveletter in assigneddrives:
            return driveletter.upper() + ':'

This works fine for all physically drives and connected network drives. But not for currently disconnected drives. How can I get all used drive letter, also the temporary not used ones?


Solution

  • Creating a child process is relatively expensive, and parsing free-form text output isn't the most reliable technique. You can instead use PyWin32 to call the same API functions that net use calls.

    import string
    import win32api
    import win32wnet
    import win32netcon
    
    def get_free_drive():
        drives = set(string.ascii_uppercase[2:])
        for d in win32api.GetLogicalDriveStrings().split(':\\\x00'):
            drives.discard(d)
        # Discard persistent network drives, even if not connected.
        henum = win32wnet.WNetOpenEnum(win32netcon.RESOURCE_REMEMBERED, 
            win32netcon.RESOURCETYPE_DISK, 0, None)
        while True:
            result = win32wnet.WNetEnumResource(henum)
            if not result:
                break
            for r in result:
                if len(r.lpLocalName) == 2 and r.lpLocalName[1] == ':':
                    drives.discard(r.lpLocalName[0])
        if drives:
            return sorted(drives)[-1] + ':'
    

    Note that this function returns the last available drive letter. It's a common practice to assign mapped and substitute drives (e.g. from net.exe and subst.exe) from the end of the list and local system drives from the beginning.