Set the Windows 7 user account picture


Not too long ago, I was asked if it's possible and how to set the Windows 7 user account picture (the one you see in the Start menu, and in the Lock screen) using PowerShell.
There is no official documented way of doing it, but it can be accomplished quite easily using the SetUserTile static function from Shell32.dll.

The complete PowerShell example function is:

function Set-AccountPicture {
    [cmdletbinding(SupportsShouldProcess=$true)]
    PARAM(
        [Parameter(Position=0, ParameterSetName='PicturePath')]
        [string]$UserName = ('{0}\{1}' -f $env:UserDomain, $env:UserName),

        [Parameter(Position=1, ParameterSetName='PicturePath')]
        [string]$PicturePath,

        [Parameter(Position=0, ParameterSetName='UsePictureFromAD')]
        [switch]$UsePictureFromAD
    )
    
    Begin {
        Add-Type -TypeDefinition @'
        using System; 
        using System.Runtime.InteropServices; 
        namespace WinAPIs { 
            public class UserAccountPicture { 
                [DllImport("shell32.dll", EntryPoint = "#262", CharSet = CharSet.Unicode, PreserveSig = false)] 
                public static extern void SetUserTile(string username, int notneeded, string picturefilename); 
            }
        }
'@ -IgnoreWarnings
    }

    Process {
        if ($pscmdlet.ShouldProcess($UserName, "SetAccountPicture")) {
            switch ($PsCmdlet.ParameterSetName) {

                'PicturePath' {
                    if (Test-Path -Path $PicturePath -PathType Leaf) {
                        [WinAPIs.UserAccountPicture]::SetUserTile($UserName, 0, $PicturePath)
                    } else {
                        Write-Error ('Picture file {0} does not exist!' -f $PicturePath)
                    }
                    break
                }

                'UsePictureFromAD' {
                    $PicturePath = '{0}\{1}_{1}.jpeg' -f $env:Temp, $env:UserDomain, $env:UserName
                    $photo = ([ADSISEARCHER]"samaccountname=$($env:username)").findone().properties.thumbnailphoto
                    $photo | Set-Content -Path $PicturePath -Encoding byte
                    $UserName = '{0}\{1}' -f $env:UserDomain, $env:UserName
                    [WinAPIs.UserAccountPicture]::SetUserTile($UserName, 0, $PicturePath)
                    break
                }

            }
        }
    }
    End { }
}

Then, to set a specific picture for a specific user:

Set-AccountPicture -UserName 'CONTOSO\martin' -PicturePath 'C:\Temp\martin.jpeg'

or, to set the current logged-on user the picture from his thumbnailphoto attribute in ActiveDirectory:

Set-AccountPicture -UsePictureFromAD –Verbose

 

/Martin.

Comments (6)

  1. Denis Beuermann says:

    Thank you, exactly what I’m looking for.

  2. Antonin Audard says:

    Can you explain how to use this chunk of code in context ?
    Do we have to copy this into a *.ps1 file ? Do we have to import a module ? i tried a couple things but nothing worked so far… :(

  3. Martin Schvartzman says:

    The code in the post is a function. You can copy it into the console (or ISE, and run it), then you can call it as shown in the examples. You could also copy it to a ps1 file, and "dot source" the file. e.g. ". .myScript.ps1"

  4. Glenn Klemetz says:

    Tried to run this as a logon script, but can’t seem to get this working.
    Any hints would be appreciated!

  5. Martin Schvartzman says:

    @Glenn,
    If you have just the function in a ps1 file, make sure you add the following line at the end of the script to call the function with the required parameters:
    Set-AccountPicture -UsePictureFromAD
    Obviously, make sure you are allowing script to run (ExecutionPolicy)

    1. James Szivos says:

      I get a COMException error:

      Exception calling “SetUserTile” with “3” argument(s): “Error HRESULT E_FAIL has been returned from a call to a COM component.”
      At line:45 char:21
      + [WinAPIs.UserAccountPicture]::SetUserTile($UserName, 0, $Pic …
      + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
      + FullyQualifiedErrorId : COMException