Search code examples
windowspowershelladsihome-directory

How can I retrieve the home directory/profile path of a different local user with Windows Powershell


Rather than looking for "$env:HOMEDIR", I'm looking for a way to query the home directory of a different user account. The powershell equivalent of "~bob".

I attempted using [ADSI]:

# After creating a local account called 'other.user'
PS> $user = [ADSI]'WinNT://localhost/other.user,user'
PS> $user.name
other.user
PS> $user.HomeDirectory

PS>

even when executed from the Administrator account in an elevated powershell.

For sanity, I tried doing the same check on the existing user:

PS> $user = [ADSI]('WinNT://localhost/{0},user' -f [Environment]::UserName)
PS> $user.name
this.user    # paraphrase
PS> $user.HomeDirectory

PS> $user.properties.HomeDirectory

PS>

Solution

  • You can combine Get-CimInstance with Get-LocalUser:

    $userName = 'other.user'
    (
      Get-CimInstance Win32_UserProfile -Filter "SID = '$((Get-LocalUser $userName).Sid)'"
    ).LocalPath
    

    This outputs the path of the targeted user's profile directory, such as C:\Users\other.user.

    Note: The profile directory is typically, but not necessarily the same as a user's home directory - the latter can be configured to point elsewhere, such as to a network share, and is reflected in a pair of environment variables for the current user, HOMEDRIVE and HOMEPATH.


    To get the true home directory:

    • If the targeted user is stored in Active Directory, the following may work (untested):

      $userName = 'other.user'
      $user = Get-ADUser $userName -Property HomeDrive, HomeDirectory
      '{0}{1}' -f $user.HomeDrive, $user.HomeDirectory
      
    • For a local-only user:

      • I'm personally not aware of a method, given that the HOMEDRIVE and HOMEPATH environment variables are dynamically added to the registry, when that user logs on to a window station (creates an OS session), under HKEY_CURRENT_USER\Volatile Environment. By contrast, if you load another user's profile file (the hidden NTUSER.DAT file located in the user's profile directory) into the registry on demand, such as via reg.exe load or via the CreateProcessWithLogon() WinAPI function (as also used by runas.exe[1]), these values are not added.

      • If someone knows if and where the home-directory information is contained in the non-volatile information of a user's profile (as accessible via the registry after loading it), do let us know.


    As for what you tried:

    The relevant properties of the System.DirectoryServices.DirectoryEntry (whose type accelerator is [adsi]) instance should be .Profile and .HomeDirDrive / .HomeDirectory, but at least on my Windows 10 machine they aren't populated; e.g.:

    PS> ([adsi] 'WinNT://localhost/jdoe,user') | Format-List *
    
    # ...
    HomeDirectory              : {}
    # ...
    Profile                    : {}
    HomeDirDrive               : {}
    # ...
    

    [1] Beware that something like runas.exe /profile /user:$userName cmd /c echo %HOMEDRIVE%HOMEPATH% in effect reports %HOMEDRIVE% as C: and %HOMEPATH% as \Windows\System32(!), based on the behavior of CreateProcessWithLogon(), which - strangely - sets these variables to the working directory of the launched process, which defaults to C:\Windows\System32.