Mon 12 May 2008
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) 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,1,0) except Exception, err: print 'Error mapping drive!' try: win32wnet.WNetAddConnection2(DISK, mapping, mapping) except Exception, err: if 'already in use' in err: # 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, mapping)
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.