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 profile directory, say jdoe, you can then use:
# See more robust alternative below.
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, it is better to use:
Get-ItemPropertyValue "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$((Get-LocalUser jdoe).SID)" ProfileImagePath
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
}
Answer from mklement0 on Stack OverflowHello Powershellers
In my current environment, there are several users who’s profile folder name is different than their username due to AD changes. So I’m looking for a way to find the profile path of the logged in user and I can’t necessarily rely on the username. The other twist is that the power shell script is run by third party software and I’m not sure which service it runs as because $env:Userprofile variable doesn’t work when using the software. Any other ideas on how I can do this? My end goal is to copy a shortcut that is under a users profile to the startup folder.
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 profile directory, say jdoe, you can then use:
# See more robust alternative below.
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, it is better to use:
Get-ItemPropertyValue "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$((Get-LocalUser jdoe).SID)" ProfileImagePath
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
}
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
Videos
In powershell, use the Win32_UserProfile WMI Object to find profiles remotely:
gwmi -ComputerName <computername> Win32_UserProfile
To find user profiles not on a server (or that are, either way), you could do something like:
gwmi -ComputerName <computername> Win32_UserProfile | ? {"C:\Users\<username>" -contains $_.LocalPath}
If the path exists, it will give results if not then it won't. You can do fancier stuff than this, but basically this should accomplish what you need without using regular expressions.
For current user run:
$env:USERPROFILE
To get list of all environmental variables, run:
Get-ChildItem Env:
I am working on a script to install Epicor.exe through PowerShell. I am using $desktopPath = "$($env:userprofile)\Desktop" for part of this script but instead of going to the logged on user's desktop it is going to the user desktop of the person running the script. I.E. If an admin runs this, it will go to the admins desktop.
$env:username will take the username of whatever account is running the script, it will not get the logged in user.
Windows can create a user-profile on-demand, using the CreateProfile API
However, if don't want to create an executable to perform this operation, you can call the API in PowerShell. Others have already done it: example on github.
Relevant part of the code:
$methodName = 'UserEnvCP'
$script:nativeMethods = @();
Register-NativeMethod "userenv.dll" "int CreateProfile([MarshalAs(UnmanagedType.LPWStr)] string pszUserSid,`
[MarshalAs(UnmanagedType.LPWStr)] string pszUserName,`
[Out][MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszProfilePath, uint cchProfilePath)";
Add-NativeMethods -typeName $MethodName;
$localUser = New-Object System.Security.Principal.NTAccount("$UserName");
$userSID = $localUser.Translate([System.Security.Principal.SecurityIdentifier]);
$sb = new-object System.Text.StringBuilder(260);
$pathLen = $sb.Capacity;
Write-Verbose "Creating user profile for $Username";
try
{
[UserEnvCP]::CreateProfile($userSID.Value, $Username, $sb, $pathLen) | Out-Null;
}
catch
{
Write-Error $_.Exception.Message;
break;
}
All you need to do is run a command as that user, Windows will create the profile:
psexec.exe -u foobar -p Abcd123! cmd.exe /c exit
https://docs.microsoft.com/en-us/sysinternals/downloads/psexec