Set user account images in Windows 10

30 Jan

Just a bit more updating a branding on Windows 10 Pro devices. All are running 1709 and the standard grey user image was a little boring.

 

I first replaced the default image with company branded versions in the same dimensions. The images all live in %programdata%\Microsoft\User Account Pictures

The images to replace are:

  • guest.bmp (448 x 448px)
  • guest.jpg (448 x 448px)
  • guest.png (448 x 448px)
  • user.bmp (448 x 448px)
  • user.jpg (448 x 448px)
  • user.png (448 x 448px)
  • user-32.png (32 x 32px)
  • user-40.png (40 x 40px)
  • user-48.png (48 x 48px)
  • user-192.png (192 x 192px)

Next I set users that had photos to use this AD photo. I found a script for using AD photos, but these are currently all 96x96px and need to be under 100k and when these are scaled up they look a bit grainy.

As I already have a readable file share with all photos setup, I changed it slightly to use these instead.

First, create a GPO and set you logoff user script:

$servername = "MyServer"

function Resize-Image
{
    Param([Parameter(Mandatory=$true)][string]$InputFile, [string]$OutputFile, [int32]$Width, [int32]$Height, [int32]$Scale, [Switch]$Display)

    # Add System.Drawing assembly
    Add-Type -AssemblyName System.Drawing

    # Open image file
    $img = [System.Drawing.Image]::FromFile((Get-Item $InputFile))

    # Define new resolution
    if($Width -gt 0) { [int32]$new_width = $Width }
    elseif($Scale -gt 0) { [int32]$new_width = $img.Width * ($Scale / 100) }
    else { [int32]$new_width = $img.Width / 2 }
    if($Height -gt 0) { [int32]$new_height = $Height }
    elseif($Scale -gt 0) { [int32]$new_height = $img.Height * ($Scale / 100) }
    else { [int32]$new_height = $img.Height / 2 }

    # Create empty canvas for the new image
    $img2 = New-Object System.Drawing.Bitmap($new_width, $new_height)

    # Draw new image on the empty canvas
    $graph = [System.Drawing.Graphics]::FromImage($img2)
    $graph.DrawImage($img, 0, 0, $new_width, $new_height)

    # Create window to display the new image
    if($Display)
    {
        Add-Type -AssemblyName System.Windows.Forms
        $win = New-Object Windows.Forms.Form
        $box = New-Object Windows.Forms.PictureBox
        $box.Width = $new_width
        $box.Height = $new_height
        $box.Image = $img2
        $win.Controls.Add($box)
        $win.AutoSize = $true
        $win.ShowDialog()
    }

    # Save the image
    if($OutputFile -ne "")
    {
        $img2.Save($OutputFile);
    }
}

#get photo from file share
$photodir = "\\"+$servername+"\User_Photos\400x400\"
 
$user_sid = [System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value

$userphotopath = $photodir + $env:UserName + ".jpg"

if (Test-Connection -ComputerName $servername -Quiet -count 1){

#continue if an image was returned
If ((Test-path $userphotopath) -eq $true)  
{
 
    #set up image sizes and base path
    $image_sizes = @(40, 96, 200, 240, 448, 192, 32, 48)
    $image_mask = "Image{0}.jpg"
    $image_base = $env:public + "\AccountPictures"
 
    #set up registry
    $reg_base = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AccountPicture\Users\{0}"
    $reg_key = [string]::format($reg_base, $user_sid)
    $reg_value_mask = "Image{0}"
    If ((Test-Path -Path $reg_key) -eq $false) { New-Item -Path $reg_key } 
 
    #save images, set reg keys
    ForEach ($size in $image_sizes)
    {
        #create hidden directory, if it doesn't exist
        $dir = $image_base + "\" + $user_sid
        If ((Test-Path -Path $dir) -eq $false) { $(mkdir $dir).Attributes = "Hidden" }
 
        #save photo to disk, overwrite existing files
        $file_name = ([string]::format($image_mask, $size))
        $path = $dir + "\" + $file_name
        Resize-Image -InputFile $userphotopath -Height $size -width $size -OutputFile $path 
 
        #save the path in registry, overwrite existing entries
        $name = [string]::format($reg_value_mask, $size)
        $value = New-ItemProperty -Path $reg_key -Name $name -Value $path -Force
        }
    }

}

Once you’ve configured that there are likely a few other changes where users are not local admins.

In the same GPO, head to Computer Configuration > Policies > Windows Settings > Security Settings.

Under Registry Add a Key: MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AccountPicture\Users and give Users full control. Also, set it to “Replace existing permissions on all subkeys with inheritable permissions”

Then look under File System and add a new path for “%SystemDrive%\Users\Public\AccountPictures” and again give Users full access.

Next time the user logs out, it will create a sub-folder with their sid under C:\Users\Public\AccountPictures. These images will be saved in the registry and display for the given user.

I could still do with a way to change the login screen background in Windows 10 Pro.

References: