7

How can I change the "user picture" for each indivudal user that is displayed during the logon for Windows Vista, 7, 2008, 2008R2 machines throughout a domain?

4
  • Changing the user picture to a default, for all users, or changing it on a per-user basis? Not going to submit an answer (yet at least), because I've researched this repeatedly and found numerous answers for setting a default, but none for setting it on a per-user basis.
    – aNullValue
    Jul 29, 2010 at 22:40
  • I'm interested in setting this on a per-user basis.
    – Nate
    Jul 30, 2010 at 13:42
  • Here's a way you can do this -- ivan.dretvich.com/2011/02/gal-photos-in-exchange-2010
    – pk.
    Mar 21, 2011 at 22:20
  • Found an article that describes how to upload pictures to Active Directory and how to get them to show on the end-users computers. blog.jocha.se/tech/ad-user-pictures-in-windows-10
    – user306631
    Aug 25, 2015 at 8:10

1 Answer 1

3

For the OSs you mention, there is an unpublished function in shell32.dll that is just the ticket. Using it will be unsupported by Microsoft, but I have no had any problem in several environments. The entry point is #262.

You could import it for use in PowerShell like below:

# Set user tile
$code = @"
[DllImport("shell32.dll", EntryPoint = "#262", CharSet = CharSet.Unicode, PreserveSig = false)]
 public static extern void SetUserTile(string username, int whatever, string picpath);

public static void ChangeUserPicture(string username, string picpath) {
    SetUserTile(username, 0, picpath);
}
"@


Add-Type -MemberDefinition $code -NameSpace Shell32 -Name ChangeUserTile

Which would mean you could call it in the same script as simply as:

[Shell32.ChangeUserTile]::ChangeUserPicture(<username>,<pathtoimage>)

I have used the following as a logon script that also grabs the image out of AD too:

# Set User Photo Script
# Reads user's photo from AD and sets as users local display picture

# Find User
$search = [System.DirectoryServices.DirectorySearcher][System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().GetDirectoryEntry()
$search.Filter = "(sAMAccountName=$env:username)"
$user = $search.FindOne().GetDirectoryEntry()

# Save image to %appdata%
$user.thumbnailphoto | Set-Content $env:appdata\usertilecache.jpg -Encoding byte

# Set user tile
$code = @"
[DllImport("shell32.dll", EntryPoint = "#262", CharSet = CharSet.Unicode, PreserveSig = false)]
 public static extern void SetUserTile(string username, int whatever, string picpath);

public static void ChangeUserPicture(string username, string picpath) {
    SetUserTile(username, 0, picpath);
}
"@

Add-Type -MemberDefinition $code -NameSpace Shell32 -Name ChangeUserTile
[Shell32.ChangeUserTile]::ChangeUserPicture(($env:userdomain + "\" + $env:username),($env:appdata + "\usertilecache.jpg"))

# Tidy up
Remove-Item ($env:appdata + "\usertilecache.jpg")

I should point out that I have since switched to using a compiled .NET app which does the same, but with much better performance - critical at at logon time.

It also gave me the option to call at start-up time and set the image for users that had not yet logged into a machine, which was a nice little addition for new users that got to see their face on their assigned PC rather than the default orange flower!

It might also be worth pointing out that for Windows 8 onwards we had to re-engineer completely - there is a brand new mechanism from MS now.

1
  • 1
    Could you elaborate upon the Windows 8 method you use?
    – Signal15
    Apr 21, 2017 at 15:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .