Login user picture on domain

Solution 1:

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.