I'm writing a script to perform some file operations in the USERPROFILE folder of each (local) user on a Windows machine.
I have found various examples that use $env:USERPROFILE
to identify the profile directory of the current logged-in user. I have also seen examples that assume all user profiles are saved in C:\Users\ and iterate/filter over that folder.
However, profile folders can be moved on Windows. My aim is to find (robustly) the profile directory of a specific user, given either that user's username (string) or a LocalUser object.
I can get an array of User objects based on active accounts with-
$users = Get-LocalUser | Where-Object Enabled -eq true
But the properties of those LocalUser objects are limited, and the UserProfile path is not among them. I believe this information is stored in the registry. I've through the PowerShell docs multiple times, but I haven't yet found the correct incantation that will give me the path of a user profile for a given user, which I can use in a loop to iterate across all users and their profile folders.
CodePudding user response:
Perhaps something along this line:
$users = Get-LocalUser | Where-Object Enabled -eq true
$profilesRootDir = @(
Get-ItemPropertyValue 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList' ProfilesDirectory)
ForEach ($User in $Users) {
$UserPath = Join-Path -Path "$profilesRootDir" -ChildPath "$User"
"User : $User`n"
"User-Path: $UserPath"
}
Output:
User : Bruce
User-Path: C:\Users\Bruce
CodePudding user response:
You can retrieve the root (parent) directory of all user profile directories from the registry as follows:
$profilesRootDir =
Get-ItemPropertyValue 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList' ProfilesDirectory
To get a specific user's (say jdoe
) profile directory, you can then use:
Join-Path $profilesRootDir jdoe
However, the ultimate source of truth is the ProfileImagePath
value in the subkeys of the above registry key path, named for each user's SID (security identifier), which Get-LocalUser
does provide (the output objects have a .SID
property):
Thus, to reliably get the profile directories of all enabled local users, use the following:
Get-LocalUser |
Where-Object Enabled |
ForEach-Object {
# Note the use of ...\ProfileList\$($_.SID) and value name ProfileImagePath
Get-ItemPropertyValue "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$($_.SID)" ProfileImagePath
}