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 {
        [Parameter(Position=0, ParameterSetName='PicturePath')]
        [string]$UserName = ('{0}\{1}' -f $env:UserDomain, $env:UserName),

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

        [Parameter(Position=0, ParameterSetName='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)

                '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)

    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



Comments (8)

  1. 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. 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!

    1. Robin says:

      You should run the script in STA mode powershell. So we should use BAT script launch a STA mode powershell first. Try below script block:
      powershell.exe -executionpolicy unrestricted -STA -Command “& ‘%~dp0Set-AccoutPicture.ps1′”
      @REM pause

  5. @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

      1. Robin says:

        Hi James, Before you run the script, make sure that your current logon users have a thumbnailphoto in your ADaccount. Or you can modify the script to:
        $UserName = ‘{0}\{1}’ -f $env:UserDomain, $env:UserName
        [WinAPIs.UserAccountPicture]::SetUserTile($UserName, 0, $PicturePath)

Skip to main content