How to use Active Directory user photos in Windows 10

[Update] This post was updated on May 22, 2019

User photos stored in Active Directory can be used by applications like Outlook, Skype for Business (Lync) or SharePoint to display the picture of currently logged-in user in their interface. However, you can take even more advantage of Active Directory photos and use them as account pictures in Windows 10 (and other versions of Windows as well, starting from Windows 7). All you have to do is make sure that you already have user photos added in Active Directory (or add them yourself) and create a Group Policy object (GPO) that will execute a script to change users’ account pictures in your domain automatically. Optionally, you may also need to globally change some of the users’ privileges, but we’ll get back to that later. Some of these steps can easily be done using CodeTwo Active Directory Photos, which is completely free! As for the other steps, this article will guide you through them smoothly.

Take a good look at this default account picture, as you will probably see it for the last time:

How to use Active Directory user photos in Windows 10 - Default Windows 10 account picture

Follow these steps to use Active Directory user photos in Windows 10

Importing photos into Active Directory

There is a simple Set-ADUser cmdlet that can be used to import user photos to Active Directory. It saves an image file in the thumbnailPhoto Active Directory attribute. An example of the command that needs to be run in PowerShell looks as follows:

$ADphoto = [byte[]](Get-Content <path to file> -Encoding byte)
Set-ADUser <username> -Replace @{thumbnailPhoto=$ADphoto}

Just remember to provide an exact path to the image file and the user’s name (learn about other ways of identifying your Active Directory users in this MS TechNet article), for example:

$ADphoto = [byte[]](Get-Content C:\AD_Photos\ad-brian-johnson -Encoding byte)
Set-ADUser BrianJ -Replace @{thumbnailPhoto=$ADphoto}

Of course, this is a no-go when you want to import photos for a lot of users. A similar command can be used to import multiple pictures into Active Directory. But first, you need to prepare a CSV file with the list of users and their respective photos. Here’s an example content of such a file:

AD_user, path_to_file
AlexD , C:\AD_Photos\ad-alex-darrow.jpg
AnneW, C:\ AD_Photos\ad-anne-wallace.jpg
BrianJ, C:\ AD_Photos\ad-brian-johnson.png

Once the file is ready, use the following command:

Import-Csv C:\AD_Photos\photos.csv |%{Set-ADUser -Identity $_.AD_user -Replace @{thumbnailPhoto=([byte[]](Get-Content $_.path_to_file -Encoding byte))}}

Creating such a file can also be quite time-consuming. This is where CodeTwo Active Directory Photos comes into play. The program not only allows you to quickly connect to Active Directory and import (single or multiple) files, but it comes with the ability to match photos automatically with respective Active Directory users. Plus, you can do all that from an intuitive and user-friendly interface.

How to use Active Directory user photos in Windows 10 - Matching photos in CodeTwo Active Directory Photos

There is also one important aspect that hasn’t been mentioned yet – the photo stored in the thumbnailPhoto attribute cannot be bigger than 100 kB, and the recommended size is 96 x 96 pixels. Here you can also make use of CodeTwo Active Directory Photos, as it lets you adjust both the size of the file as well as its dimensions.

How to use Active Directory user photos in Windows 10 - Editing photos in CodeTwo Active Directory Photos

With this program, you will also instantly know which users don’t have their photos added to Active Directory by merely looking at the user’s list.

How to use Active Directory user photos in Windows 10 - Viewing users in CodeTwo Active Directory Photos

Otherwise, you can, for example, open the Active Directory Users and Computers tool and check if the thumbnailPhoto attribute shows any value. If you see <not set>, it means there is no photo there.

How to use Active Directory user photos in Windows 10 - Checking thumbnailPhoto attribute in Active Directory Users and Computers

If you can’t find the Attribute Editor tab in the Properties window, make sure the Advanced Features options on the View menu is checked.

How to use Active Directory user photos in Windows 10 - Enabling Advanced Features in Active Directory Users and Computers

Creating a new GPO for your domain

Now, to propagate these Active Directory photos as Windows 10 account pictures, you can make use of Group Policy objects. Or more specifically – a Group Policy logoff scripts. They are used to perform automated tasks on each machine in a specified domain when a user logs off in Windows. That way, changes are introduced without any conflicts and even without any interaction on users’ part.

The script that we’re going to use was found on this site. You can adjust this code to your needs, or just copy it as it is and paste it into an empty text document. Save the file and change its extension from .txt to .ps1. Next, copy the file to a network location, e.g. %logonserver%\netlogon.
[CmdletBinding(SupportsShouldProcess=$true)]Param()
function Test-Null($InputObject) { return !([bool]$InputObject) }
Function ResizeImage() {
param([String]$ImagePath, [Int]$Quality = 90, [Int]$targetSize, [String]$OutputLocation)
Add-Type -AssemblyName "System.Drawing"
$img = [System.Drawing.Image]::FromFile($ImagePath)
$CanvasWidth = $targetSize
$CanvasHeight = $targetSize
#Encoder parameter for image quality
$ImageEncoder = [System.Drawing.Imaging.Encoder]::Quality
$encoderParams = New-Object System.Drawing.Imaging.EncoderParameters(1)
$encoderParams.Param[0] = New-Object System.Drawing.Imaging.EncoderParameter($ImageEncoder, $Quality)
# get codec
$Codec = [System.Drawing.Imaging.ImageCodecInfo]::GetImageEncoders() | Where {$_.MimeType -eq 'image/jpeg'}
#compute the final ratio to use
$ratioX = $CanvasWidth / $img.Width;
$ratioY = $CanvasHeight / $img.Height;
$ratio = $ratioY
if ($ratioX -le $ratioY) {
$ratio = $ratioX
}
$newWidth = [int] ($img.Width * $ratio)
$newHeight = [int] ($img.Height * $ratio)
$bmpResized = New-Object System.Drawing.Bitmap($newWidth, $newHeight)
$graph = [System.Drawing.Graphics]::FromImage($bmpResized)
$graph.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic
$graph.Clear([System.Drawing.Color]::White)
$graph.DrawImage($img, 0, 0, $newWidth, $newHeight)
#save to file
$bmpResized.Save($OutputLocation, $Codec, $($encoderParams))
$bmpResized.Dispose()
$img.Dispose()
}
#get sid and photo for current user
$user = ([ADSISearcher]"(&(objectCategory=User)(SAMAccountName=$env:username))").FindOne().Properties
$user_photo = $user.thumbnailphoto
$user_sid = [System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value
Write-Verbose "Updating account picture for $($user.displayname)..."
#continue if an image was returned
If ((Test-Null $user_photo) -eq $false)
{
Write-Verbose "Success. Photo exists in Active Directory."
#set up image sizes and base path
$image_sizes = @(32, 40, 48, 96, 192, 200, 240, 448)
$image_mask = "Image{0}.jpg"
$image_base = "C:\ProgramData\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))
$pathtmp = $dir + "\_" + $file_name
$path = $dir + "\" + $file_name
Write-Verbose " saving: $file_name"
$user_photo | Set-Content -Path $pathtmp -Encoding Byte -Force
ResizeImage $pathtmp $size $size $path
Remove-Item $pathtmp
#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
}
Write-Verbose "Done."
} else { Write-Error "No photo found in Active Directory for $env:username" }

What does this script do? Generally, it exports the photo stored in the thumbnailPhoto attribute and saves it on your machine, in a specified folder (in this case: C:\ProgramData\AccountPictures\{User SID}). You will notice that there will be eight JPG files stored in this folder, each of different size (from 32×32 px to 448×448 px), and name, specifying photo’s size (Image32.jpg, Image96.jpg, etc.). Additionally, new registry keys will be created under MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AccountPicture\Users\{User SID} in the Windows registry, with paths to these photos.

To create a new GPO, open Group Policy Management console (if you can’t find it, follow these steps to install it), find your domain in the console tree, right-click it and select Create a GPO in this domain, and Link it here.

How to use Active Directory user photos in Windows 10 - Creating a new GPO

Provide any name you want and click OK. A new GPO will appear under Group Policy Objects.

How to use Active Directory user photos in Windows 10 - Newly created Group Policy Object

Adding a logoff script to GPO

Right-click this GPO and choose Edit. The Group Policy Management Editor window will open. Navigate to User Configuration > Policies > Windows Settings > Scripts (Logon/Logoff), and then double-click Logoff in the right pane.

How to use Active Directory user photos in Windows 10 - Adding a new Logoff script

In the Logoff Properties window, go to the PowerShell Scripts tab. Click Add > Browse and point to the PS1 script file in the %logonserver%\netlogon path. Leave the Script Parameters field empty.

How to use Active Directory user photos in Windows 10 - Custom Windows 10 account picture - Selecting the script file

When done, just click OK two times.

And this should do the trick. The next time a user logs off from any machine in this domain and logs in again, the account picture should update automatically. However, this will only work if users in your domain have local administrative privileges assigned. If not, there is one more thing you need to do. And it also involves GPO.

How to use Active Directory user photos in Windows 10 - Custom Windows 10 account picture

Adding registry key permissions in GPO

Remember the registry key mentioned before? The key MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AccountPicture\Users is where the information about the account picture is stored. Users cannot change their account pictures unless they are granted Full Control permission to that key. This can also be done via GPO. You can even use the same one you’ve created to run the logoff script.

Back in the Group Policy Management Editor, go to Computer Configuration > Policies > Windows Settings > Security Settings, right-click the Registry node and select Add Key.

How to use Active Directory user photos in Windows 10 - Configure a registry key using GPO

Navigate to MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AccountPicture\Users (or just copy this key and paste it under the Selected key field) and click OK.

How to use Active Directory user photos in Windows 10 - Selecting specific registry key

Select Users under Group or user names and tick the Allow checkbox next to Full Control.

How to use Active Directory user photos in Windows 10 - Granting Full Control permissions to a registry key

Once you click OK, another window will open. Select the Replace existing permissions on all subkeys with inheritable permissions option and click OK.

How to use Active Directory user photos in Windows 10 - Configuring additional permission options

Now, it may take some time for the GPO to make the change in the Registry Editor – it is usually also required to restart the client machine. But once a non-admin user has full access to the registry key in question, and once they sign out and in again, their profile picture should be updated.

But there is one more thing CodeTwo Active Directory Photos can do for you. Once you have deployed the logoff script, it will be executed every time a user logs off (until you delete this GPO). Thanks to that, you can use this free tool to quickly change user photos in the Active Directory, and the account pictures will also change automatically.

How to use Active Directory user photos in Windows 10 - Changing user photos in CodeTwo Active Directory Photos

You can use this feature to, for example, change user photos for the upcoming holiday season or any important events affecting your company.

To sum up, using Active Directory user photos to personalize profile pictures in Windows 10 is quite an easy task that won’t take long to complete. Plus, as mentioned at the beginning of this article, these photos will also be used in programs like Skype or Outlook. Use this opportunity to personalize your email signatures as well!

Further reading

How to add, edit, manage or remove Active Directory photographs

How to manage users’ photos in Microsoft Lync, Outlook and Exchange Server

31 thoughts on “How to use Active Directory user photos in Windows 10


  1. Permissions
    Since I’m a security freak, I experimented with registry permissions until I found the most restrictive possible without loss of functionality.

    On HKLM\Software\Microsoft\Windows\CurrentVersion\AccountPicture\Users:
    * domain or local Users group: ONLY the following advanced permissions added to that key only (and NOT propagated or applied to sub-keys at all): Set Value, Create Subkey, Enumerate Subkeys.
    * CREATOR OWNER: Should already have Full Control permissions on Subkeys only

    These permissions are conceptually identical to NTFS permissions used on network shares holding redirected shell folders (e.g., Documents, Pictures, etc.)

    ImageBase
    Running any recent Win10 semi-annual release, computers already have the C:\Users\Public\AccountPictures imagebase folder preconfigured with correct NTFS permissions (via the INTERACTIVE user group) for this purpose. I’d change the script to use that imagebase path by default (why not?).

    • Hi Andy,
      Thanks for sharing! I will test it on my end and add this info to the article. If you don’t mind, that is.

  2. Adam; I believe it is working now. Originally I placed the new Group Policy onto the OU containing the User account. After trial & error I placed the Group Policy onto the OU containing the Workstation. Is this what was needed all along? If so, please update the document for future users. Again, thank you for all of your help, this is a Fantastic feature that our management will love

    • Glad you managed to get it to work! I’m still not sure what the issue was – I have created an OU containing a few test users and a GPO linked to this OU worked perfectly fine. Maybe you had some “Deny” permissions in place? Anyway, I will continue to investigate and will make sure to post any updates as soon as I learn anything new.

  3. Adam; Thank you for the follow up.
    The Server is Windows Server 2012 R2. The Workstations I have tried on are: Windows 10, Windows 8.1 Pro and Windows 7. I know the script is running because the Account Pictures are created. I believe the problem is the User is not being granted Full Rights to the folder. If I open the workstation Registry and go to Computer\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\AccountPicture\Users, right-click the Users folder and look at the permissions, the Users (workstationName\Users) had Read only. I tried going back to the Group Policy and adding Everyone, Authenticated Users and Domain Users but it did not fix it either. There is a SID S-1-5-##########-##########-##########-#### which does nave Full Control permissions. But the pics to not show when logging in.
    Also, if I edit the registry manually by checking Full Control on the Users (workstationName\Users), it works fine. But I cannot go to every workstation and do this manually.

    So close to getting this working, what an I missing

  4. Thank you for the excellent tutorial. I am encountering a problem, the script runs, creates the programdata images, but the registry is not getting the Full Permission applied. I have tried adding Domain Users, Authenticated Users and even Everyone, but the permission does not add the Full Permissions. I don’t know if Microsoft changed anything with an update that is causing it to not work or what, any ideas? Thanks in advance

    • Hello Thomas,
      It would help a great deal if you specified which server and client version you are using. Recently, I have made some changes to the article (yes, one of the Windows updates broke something unexpectedly), so it should work with the newest builds.
      As a side note, it sometimes takes a few client machine reboots before the GPO kicks in.

  5. Fantastic write up, thank you so much for laying this out and making it easy for us. That being said, I just completed these instructions this morning and it is not working. The Group Policy is working because the export is creating the 8 pictures in the designated folder. I already had the thumbnail image in all of the users AD profiles. They already appeared in each Users Outlook, Skype for Business and SharePoint. By adding this Policy I am looking for the User Image to appear in their Account Picture. I included the additional Key and permissions. Any ideas where I can look to resolve?

  6. Good morning, first of all excellent tutorial, but I am encountering the following problem, the first user with which I have tried to work, but then with all the others it does not show me the image, nevertheless I have gone to the folder of programdata and all the images are downloaded, I checked the permissions of the registry key and the code and they are correct, any ideas? Thanks in advance

    • Have you tried launching the script manually on a user’s machine? Maybe you will get an error message which will help troubleshoot the issue. Another thing – is there anything special about the first user (the one for whom it works)?

  7. Hi,

    I’ve followed all the steps in this article, however the pictures still aren’t updating.

    The folder with the images is being created, and so are the reg keys, however the photos still aren’t updating after gpupdate and logging off. This is being done on a test OU and not the whole domain like in the example.

    Cheers.

    • I’ve just created a new, test OU, added users to this OU, and linked GPO to it. Then, I made sure everything is done according to the article. Took two logoffs to update the picture.
      Not sure what the problem is in your case, could you specify what is your environment? As much as I’d like to help, I don’t have enough data to do so, right now.

  8. To anyone interested in this topic:
    I’ve taken another look at this article and made some changes to freshen it up. The whole process should run more smoothly, now.

  9. I have been fighting with this for over 4 hours.

    The Active Director User pictures program is fantastic, but this GPO setup is not working. I have tried every iteration on this page and also what some people have posted in the comments section, but alas the Power Shell script will not automatically run, in fact it slows down the logoff process so much we have to force a dirty shut down on the affected workstation and manually apply the script by browsing to the net logon folder and right-clicking the script and using “Run with power shell” option.

    I myself have 12 years of active directory experience, and my boss is an MCSE and we still can’t get it work, so kudos to whoever can figure this out, until then We will not be recommending this program or the group policy, in fact we will b posting against on Reddit and our other communities.

    • Hi Frank,
      Sorry to hear that something went wrong. I’m reviewing the whole procedure once again to make sure I have not missed anything and to find out what could have gone wrong.
      I’ll post an update as soon as I find anything out. In the meantime, could you specify which Exchange Server version you are using? Is this a hybrid environment? I’m trying to reproduce this problem and any environment-related information might come in handy.

  10. I created the script and the ProgramData folder was created and the pics are there, but the pics are still not showing up. What am I missing? Looking for advice.

    • Hi Rico,
      I’m currently reviewing the whole procedure to find out if Microsoft changed anything related to this topic and to find out which part could go wrong. I’ll post an update as soon as I learn anything in this matter. In the meantime, could you specify any basic information about your environment (like Windows Server version)? The issue might be specific to certain environments and I’m trying to reproduce this in my test environment.

  11. Thank for this Great article. Do you know if any of these routines can be used with Azure AD and Intune, or if there are other routines there in ordet to have the personal picture from Azure into Windows 10 Profile pic?

  12. Hi Adam,

    We’ve implemented this successfully but are noticing that photos are displaying with a less than desirable quality. CodeTwo indicates that AD requires a 100K size thumbnail photo. Is there a way around this?

    • Hi Ryan,
      There is no way to upload a photo which exceeds the 100 KB quota. On the other hand, 100 KB should be more than enough to ensure a desirable quality. A few tips:

      1. If you are using CodeTwo Active Directory Photos (freeware) to upload the photos, you can automatically resize the photos,
      2. It is best to use square photos which have dimensions equal to 96×96 px or its multiple (383×383, 426×426 and so on).
      3. Use jpg file format and try to use white background
      4. It is also a good idea to crop the picture, so that it focuses mainly on the face
  13. I struggled to get the LogOff script to run via GPO on Windows 10 Enterprise 1803 with my Server 2016 AD Domain and after a lot of trial and error, the solution I found is quite simple:

    Do not use Powershell.exe as the Script name, instead click Browse and select the *.ps1 file you created and saved to the netlogon share. Leave the Script Parameters blank.

    Everything worked great after that. Thank you for the article!

    • Thanks for the info! The script used to run flawlessly before, I will update the article to include the change in the procedure.

  14. Hi,

    i did all the steps and the modification proposed by DGCupit but it is still not working on my domain.
    If i execute the script locally it works fine, otherwise i don’t have any error message or warning but it is not working.

    Does anyone have the same problem ?

    Thank you,
    Regards,

  15. I wanted to let those know that it seems something has changed in the formulation to the PS commands. Not sure how Microsoft broke the previous command, since it was in place and working for months, but I have found that this command string has resolved the Access Is Denied issues I was seeing:

    %windir%\System32\WindowsPowerShell\v1.0\powershell.exe -Noninteractive -ExecutionPolicy Bypass -Noprofile -windowstyle hidden -command “&{. \\%logonserver%\netlogon\ADPhoto\Set-ADPicture.ps1}”

  16. Hi,
    I’ve got a Windows 10 Client and a 2016 DC.
    The powershell script is located in %logonserver%\netlogon
    If I call it by hand, it works fine.
    Afterwards in the registry I delete the subkey under “Users” and the folder “accountpictures” from c:\programdata.
    All other GPOs are running fine.
    In the eventviewer I only get a event ID 1130 Grouppolicy.
    I also tried the other two policy settings you discribed:
    ” User Config->Policies->Admin Templates->System->Scripts and enable the Display instructions in logoff scripts as they run option and disable the Run Windows PowerShell scripts first at user logon, logoff”
    Do you have any more hints?
    Thanks in advance!

  17. Hello, I have followed the instructions and the profile picture shows up in the settings and the Start Menu but not during login. I am on Windows 10 1803. I would also like to state that the 8 pictures that the script made are all the same original size just different names.

  18. Good Morning Adam,

    Hope you’re still monitoring this. Anyway, I thought I’ve done a good job of following your directions but I cannot get the script to execute at logoff. If I logon to a machine and run the script from its location on the DC it works as expected. However, launching as part of the logoff process fails. I’ve turned on Notifications in the GPO so when I logoff I see the Powershell window come up, the dreaded red error code and the machine immediately completes the logoff process. I tried putting a Pause at the end of the script but I suppose the logoff process is too far in to stop. If I look in the Event Log after I see the very generic Logoff Script failed to execute. If you can think of anything else I could try I would appreciate it.

    Thanks!

    • Hello Don,
      Sometimes there is a problem with logoff scripts in Windows 10. One of the way to fix it is to go to their settings: User Config->Policies->Admin Templates->System->Scripts and enable the Display instructions in logoff scripts as they run option and disable the Run Windows PowerShell scripts first at user logon, logoff. If it still does not work, it would be very helpful to know what does the red error code of the failed script say.

  19. Hi, i’ve created the GPO following everything named here (i’ve even used the same name for the script and things like that) in order to test it before implementing in my production infrastructure. The problem here is: My AD got the GPO running and working fine. However, none of the testing stations (using win10 pro) got the GPO running, even trying using gpupdate. Can u give any tips?

  20. Hi, I have created the GPO policy to modify the permissions in registry values, but the policy doesn’t apply because (is written) there privileges are not enough. There is a solution about this issue? I use windows 10 clients and windows 2016 as a server, with the last security fix. Thank you!

    • Hello Christian,
      please tell me, which GPO settings weren’t applied – the one that should change users’ permissions in registry or the one with the script? I set up the same environment (Windows Server 2016 + Win 10, with all the recent updates installed) just to be sure everything works. And it does, at least for me. Please verify those two things:
      1) check, if the permissions were changed for all users. Open the Registry Editor and navigate to the key in question (MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AccountPicture\Users), right-click Users, and select Permissions. Check, if “Users (YourDomain\Users)” is shown in the upper pane, and when you click it – if the “Full Control” box is checked.
      2) check, if the script itself works. Simply navigate to the folder specified in the script (by default it was C:\ProgramData\AccountPictures) and see, if there are any folders there (GUIDs with image files inside).

      Also make sure that you’ve linked GPO to the correct Domain in the Group Policy Management console and that the script file is placed in the specified network location.

      Please let me know, if the problem still persists, or if these tips helped you. One thing I’ve noticed this time is that the changes didn’t work the first time I signed out using a non-admin account, but after the second logoff. Changes to registry took even longer time. Give Windows some time to propagate any necessary changes.

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*