Mapping Drives on Windows

One of the first scripts I had to help translate from Kixtart to Python was our map drives script. In it, we would map drives based on either which group the user was in and/or what a custom registry entry said. Here is a partial example of each of these categories in Kixtart:


IF READVALUE("HKEY_LOCAL_MACHINE\SOFTWARE\MyOrg", "Office")= "officeName"
$Drive="g:" $Path="\\serverName\" + @userid Call "@lserver\\folderName"
ENDIF

IF InGroup("Dept XYZ")
$Drive="g:" $Path="\\serverName\" + @userid Call "@lserver\\folderName"
ELSE
ENDIF

Now, you'll notice that this script is calling another script called "ConnectDrive" to do the actual mapping. Basically all it contains was error handling and these few lines:


:ConnectDrive

USE $Drive /DELETE
USE $Drive $Path

Now let's take a look at what I use in Python to replace the Kixtart code. First, we need to get the groups that the user is in. You will notice below that there are two ways to get the group information that we need using different parts of the PyWin32 package.

from win32com.client import GetObject as _GetObject 

try:
    user = _GetObject("WinNT://%s/%s,user" % (pdcName, userid))
    fullName = user.FullName
    myGroups = _GetGroups(user)
except:
    try:
        from win32net import NetUserGetGroups,NetUserGetInfo
        myGroups = []
        groups = NetUserGetGroups(pdcName,userid)
        userInfo = NetUserGetInfo(pdcName,userid,2)
        fullName = userInfo['full_name']
        for g in groups:
            myGroups.append(g[0])
    except:
        fullname = "Unknown"
        myGroups = []

Then we can do the drive mapping. Notice that I attempt to unmap anything that's already mapped to a drive letter I want to map to. I do this because we have user's that will plug in USB drives that take over drives that my script maps. Sometimes this works and sometimes it does not.

import subprocess
import win32wnet
from win32netcon import RESOURCETYPE_DISK as DISK

drive_mappings = []
if "Dept XYZ" in myGroups:
    drive_mappings.append(('V:', '\\\\ServerName\\folderName'))

for mapping in drive_mappings:
    try:
        # Try to disconnect anything that was previously mapped to that drive letter
        win32wnet.WNetCancelConnection2(mapping[0],1,0)
    except Exception, err:
        print 'Error mapping drive!'

    try:
        win32wnet.WNetAddConnection2(DISK, mapping[0], mapping[1])
    except Exception, err:
        if 'already in use' in err[2]:
            # change the drive letter since it's being mis-assigned
            subprocess.call(r'diskpart /s \\%s\path\to\log\change_g.txt' % pdcName)
            # try mapping again
            win32wnet.WNetAddConnection2(DISK, mapping[0], mapping[1])

And that's all there is to it. It ended up being a little bit more complicated than the Kixtart was, but I think my code is more readable and I don't have to go searching across multiple files to understand it.

Copyright © 2024 Mouse Vs Python | Powered by Pythonlibrary