[python-win32] Finding users home directories

Tim Golden mail at timgolden.me.uk
Mon Jan 14 17:19:04 CET 2008


Giampaolo Rodola' wrote:
> 2008/1/12, Tim Golden <mail at timgolden.me.uk>:
>> Giampaolo Rodola' wrote:
>>> I'm trying to use the pywin32 extension to find out the users home directories.
>>> Currently I found a way for doing that but it requires to validate the
>>> user by providing its username + password:
>>>
>>> def get_homedir(username, password):
>>>    token = win32security.LogonUser(
>>>        username,
>>>        None,
>>>        password,
>>>        win32security.LOGON32_LOGON_NETWORK,
>>>        win32security.LOGON32_PROVIDER_DEFAULT
>>>        )
>>>    return win32profile.GetUserProfileDirectory(token)
>>>
>>>
>>> What I'd like to do is avoiding the requirement of the password, in
>>> the same way as if I would on UNIX where it would be enough just using
>>> the pwd module and providing the username only:
>>>
>>>  >>> import pwd
>>>  >>> pwd.getpwnam('user').pw_dir
>>>  '/home/user'
>>>
>>> Does someone know if it is possible to do that?
>> I thought it would be accessible via the win32net functions,
>> but it seems not. According to this page:
>>
>> http://www.microsoft.com/technet/scriptcenter/resources/qanda/jun05/hey0603.mspx
>>
>> it's possible, but not slick. If you wanted to follow their
>> line and use WMI to access the registry, you could additionally
>> use the WMI Win32_UserAccount class to work out the SID you need.
>> For example, to find my profile on this machine, the following
>> seems to work:
>>
>> (uses the wmi module from http://timgolden.me.uk/python/wmi.html)
>>
>> <code>
>> import _winreg
>> import win32api
>> import wmi
>>
>> #
>> # Use the current username in DOM\USER format
>> #
>> USERNAME = win32api.GetUserNameEx (2)
>> ## USERNAME = "GOYLE\\tim"
>>
>> HKLM = 0x80000002
>> profiles_key = r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"
>>
>> c = wmi.WMI (find_classes=False)
>> for account in c.Win32_UserAccount (Caption=USERNAME):
>>    sid = account.SID
>>    break
>> else:
>>    raise Exception, "User %s not found" % USERNAME
>>
>> registry = wmi.WMI (find_classes=False, namespace="default").StdRegProv
>> result, profile = registry.GetExpandedStringValue (
>>    _winreg.HKEY_LOCAL_MACHINE,
>>    profiles_key + "\\" + sid,
>>    "ProfileImagePath"
>> )
>>
>> print USERNAME, "has profile at", profile
>> </code>
>>
>> TJG
> 
> This is what I get when I try to run your code:
> 
> Traceback (most recent call last):
>   File "C:\Documents and Settings\billiejoex\Desktop\_test.py", line 25, in <mod
> ule>
>     "ProfileImagePath"
> TypeError: __call__() takes exactly 1 argument (4 given)

Strange. I did test it before I posted.
Ah; I forgot that the released version of
WMI doesn't allow for positional parameters.
Sorry. You can either:

1) Pull the latest release from here:
http://timgolden.me.uk/python/downloads/wmi-1.3.2.zip
and run again.

or

2) Change to the following (notice the named params):

result, profile = registry.GetExpandedStringValue (
   hDefKey=_winreg.HKEY_LOCAL_MACHINE,
   sSubKeyName=profiles_key + "\\" + sid,
   sValueName="ProfileImagePath"
)


I must report that, on my AD-attached machine, the
Win32_UserAccount query above is *not* fast. You might
well be better off following Mark Hammond's suggestion
of using win32security:

import win32security
user_sid = win32security.ConvertSidToStringSid (
   win32security.LookupAccountName(None, USERNAME)[0]
)

and using whatever registry-query module you find most
convenient -- there are a bunch of registry-wrappers
out there. I wouldn't bother using WMI just for that.

TJG


More information about the python-win32 mailing list