Skip to content Skip to sidebar Skip to footer

What Is The Windows Equivalent Of Pwd.getpwnam(username).pw_dir?

The Python pwd module provides access to getpwnam(3) POSIX API, which can be used to get the home directory for a particular user by username, as well determining if the username i

Solution 1:

Reading the 2.6 documentation shows that os.path.expanduser() is broken on Windows:

On Windows, HOME and USERPROFILE will be used if set, otherwise a combination of HOMEPATH and HOMEDRIVE will be used. An initial ~user is handled by stripping the last directory component from the created user path derived above.

Say whaat? This assumes all user homes have to be under the same parent directory. Nuh-ugh!

It was a bit hard to dig but here is a solution that will look up a local user by given name:

from win32security import LookupAccountName, ConvertSidToStringSid
from _winreg import OpenKey, QueryValueEx, HKEY_LOCAL_MACHINE

defgetUserDir(userName):
    ssid = ConvertSidToStringSid(LookupAccountName(None, userName)[0])
    key = OpenKey(HKEY_LOCAL_MACHINE, r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\\' + ssid)
    return QueryValueEx(key, 'ProfileImagePath')[0]

Solution 2:

I am new to Windows security... but reading MSDN and some blogs it seems to me that the way MS want us to handle other users specific data is by getting a user token.

There used to be a nice wiki of Keith Brown .Net Developers Guide to Windows Security... you can still find it in Google cache for "pluralsight keith.guidebook"

Case 1: If you don't have the user password:

For local accounts you can try reading the Windows registry as Nas Banov already suggested and there are some other recipes on SO or the Internet.

I am not sure how various Windows versions behaves for freshly create users ... those which have never performed an interactive session login ... does it automatically creates their registry, home folder and profile data? I have done some tests on Windows XP and those registry keys were not present after creating an local account ... but in this case you can try to guess it based in All Users registry values ... or just fail :)

For desktop applications, when the application is running as a logged in user, I am using something like this to get the home folder.... and to get the equivalent of ~/.local I am using CSIDL_APPDATA, for roaming profiles, or just CSIDL_LOCAL_APPDATA.

from win32com.shell import shell, shellcon
# See microsoft references for further CSIDL constants# http://msdn.microsoft.com/en-us/library/bb762181(VS.85).aspx
folder_name = shell.SHGetFolderPath(0, shellcon.CSIDL_PROFILE, 0, 0)

Reading Keith Brown article "How To Get A Token For A User" .. you can look for some other ways of getting an user token without a password...

Case 2: If you have the user password:

Reading the MSDN I got the impressing that if I have an user token, I can get its folders by calling something like the code below... but it did not worked for me. (not sure why)

token = win32security.LogonUser(
            username,
            None, # we uses UPN format for username
            password,
            win32security.LOGON32_LOGON_NETWORK,
            win32security.LOGON32_PROVIDER_DEFAULT,
            )
folder_name = shell.SHGetFolderPath(0, shellcon.CSIDL_PROFILE, token, 0)

This is why I ended up with this code...which is far from being perfect due to the fact that it requires username and password.

token = win32security.LogonUser(
            username,
            None, # Here should be the domain ... or just go withdefaultvalues
            password,
            win32security.LOGON32_LOGON_NETWORK,
            win32security.LOGON32_PROVIDER_DEFAULT,
            )
win32security.ImpersonateLoggedOnUser(token)
folder_name = shell.SHGetFolderPath(0, shellcon.CSIDL_PROFILE, 0, 0)
win32security.RevertToSelf()

This question is somehow related: How to find the real user home directory using python?

Solution 3:

you could go the win32api.GetUserName() (current user only) or win32net.NetUserGetInfo() (any user on any server, localhost included) route. the latter could be a bit slow since it can take some time to get this information back from the OS.

import win32net

  defuserDir(username):
        return win32net.NetUserGetInfo(None, username, 1).get("home_dir")

alternatively you could expand the environment variable USERPROFILE on windows or HOME on unix to get the information about the currently logged in user:

  def userDir():
      ifos.platform.system() == 'Windows':
          returnos.environ['USERPROFILE']
      elif os.platform.system() == 'Linux':
          returnos.environ['HOME'] 
      else:
          return None

Solution 4:

This seems to be only applicable to the current user, but on my (winxp) machine, os.path.expanduser('~') returns my home directory.

Post a Comment for "What Is The Windows Equivalent Of Pwd.getpwnam(username).pw_dir?"