[python-win32] Finding users home directories

Giampaolo Rodola' billiejoex at gmail.com
Mon Jan 14 18:08:31 CET 2008


2008/1/14, Tim Golden <mail at timgolden.me.uk>:
> 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
>


Ok, this is what I've done. Surely not nice to watch but it seems to work:

<code>
import _winreg
import win32security

username = 'Administrator'
sid = win32security.ConvertSidToStringSid(
        win32security.LookupAccountName(None, username)[0]
        )
key = _winreg.OpenKey(
        _winreg.HKEY_LOCAL_MACHINE,
        r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" + "\\" + sid
        )
value, type = _winreg.QueryValueEx(key, "ProfileImagePath")
print value
</code>


What I find very strange is that there's no API for doing such a thing
in better/nicer ways.
Anyway, thanks a lot for your precious help.


-- Giampaolo


More information about the python-win32 mailing list