There is no UI to set the picture of a different specific user, but you can do it by creating versions of the picture with all necessary sizes and modifying the Registry to point to them. Specifically, each user's account picture is stored under this key as described in this other answer:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AccountPicture\Users
Each subkey's name is the SID of the user whose picture it specifies. Each subkey has a handful of Image###
entries, one for each image size, e.g. Image32
, storing the full path to the image. The most recent Windows 10 version has entries for 32, 40, 48, 64, 96, 192, 208, 240, 424, 448, and 1080 pixels. When you create an account picture with the Settings app, the images are stored in a subfolder of C:\Users\Public\AccountPictures
named for your SID. The files should be readable by Everyone. Strangely, both the subkeys and subfolders allow full control only to the singular Administrator account instead of the Administrators group, so writing to them requires adjusting the ACL, after taking ownership in the case of the folder.
To automate this process, I wrote a PowerShell script based on this forum post:
Param(
[string]$UserName,
[string]$PicturePath
)
# Get identifiers for path components
$sid = [System.Security.Principal.NTAccount]::new($UserName).Translate([System.Security.Principal.SecurityIdentifier]).ToString()
$pictureGuid = [guid]::NewGuid().ToString().ToUpper()
# Load the new image
Add-Type -AssemblyName System.Drawing
$picture = [System.Drawing.Image]::FromFile((gi $PicturePath).FullName)
# Create or gain access to the AccountPictures subfolder
$picturesFolder = Join-Path (Join-Path $env:PUBLIC 'AccountPictures') $sid
If (Test-Path $picturesFolder) {
Push-Location $picturesFolder
takeown /f . /a | Out-Null
icacls . /grant 'Administrators:(OI)(CI)F' | Out-Null
Pop-Location
} Else {
mkdir $picturesFolder | Out-Null
Push-Location $picturesFolder
icacls . /grant 'Everyone:(OI)(CI)R' | Out-Null
Pop-Location
}
# Create or gain access to the picture Registry key
$picturesKey = Join-Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AccountPicture\Users $sid
If (Test-Path $picturesKey) {
$keySubpath = "SOFTWARE\Microsoft\Windows\CurrentVersion\AccountPicture\Users\$sid"
$keyObject = [Microsoft.Win32.RegistryKey]::OpenBaseKey('LocalMachine', 'Registry64').OpenSubkey($keySubpath, 'ReadWriteSubTree', 'ChangePermissions')
$acl = $keyObject.GetAccessControl()
$acl.AddAccessRule([System.Security.AccessControl.RegistryAccessRule]::new('Administrators', 'FullControl', 'ContainerInherit', 'None', 'Allow'))
$keyObject.SetAccessControl($acl)
$keyObject.Dispose()
} Else {
mkdir $picturesKey | Out-Null
}
# Prepare the JPG encoder
$encoder = [System.Drawing.Imaging.ImageCodecInfo]::GetImageEncoders() | ? { $_.MimeType -eq 'image/jpeg' } | select -First 1
$encoderParams = [System.Drawing.Imaging.EncoderParameters]::new()
$encoderParams.Param[0] = [System.Drawing.Imaging.EncoderParameter]::new([System.Drawing.Imaging.Encoder]::Quality, 90)
# Create resized versions of the picture
(32, 40, 48, 64, 96, 192, 208, 240, 424, 448, 1080) | % {
$picturePath = Join-Path $picturesFolder "{$pictureGuid}-Image$_.jpg"
$resized = [System.Drawing.Bitmap]::new($_, $_)
$graphics = [System.Drawing.Graphics]::FromImage($resized)
$graphics.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic
$graphics.DrawImage($picture, 0, 0, $_, $_)
$resized.Save($picturePath, $encoder, $encoderParams)
$resized.Dispose()
Set-ItemProperty $picturesKey -Name "Image$_" -Value $picturePath
}
It takes the account name of the user whose picture to change and the path to the picture. The picture can be in any common format, but should be square since it will be stretched to square dimensions. The script appropriately configures the folder and Registry key, creates the several resized versions of the picture, and writes their paths to the Registry. Changes frequently take effect immediately, but if you don't see them, reboot.
To use run the script, save it as a PS1 file, e.g. accountpicture.ps1
. If you haven't already, follow the instructions in the Enabling Scripts section of the PowerShell tag wiki. You can then run the script from an administrative PowerShell prompt like so:
.\accountpicture.ps1 -UserName newuser -PicturePath .\photo.png