I’ve been working on implementing Windows 10 at a company.
They wanted to import a photo of all the users to the Active Directory, and have all the other systems pull the pictures from it. I primarily focused on Windows clients, Lync and SharePoint.
Goal
Our goal is to have Windows 8 and 10 clients pull the pictures from Active Directory to the users local profiles.
1. Importing the pictures to Active Directory
Now there are several approaches for this. Getting the pictures into AD I prefer using PowerShell.
If you’re more into GUI style I can recommend this AD Photo Edit.
2. Create the required scripts
You need a (startup) script to download the data from Active Directory and convert them to JPEG-files.
The script then proceeds to set these images as your local users profile picture/tile.
The PowerShell-script I’m using was originally written by Jordan. I modified it for better functionality and to make it work better with Windows 10.
<# .SYNOPSIS Set-ADPicture.ps1 Written by Joakim at Jocha AB, http://jocha.se .DESCRIPTION Version 1.3 - Updated 2016-02-13 This script downloads and sets the Active Directory profile photograph and sets it as your profile picture in Windows. Remember to create a defaultuser.jpg in \\domain\netlogon\ 2016-02-13 : Slightly adjusted. 2015-11-12 : Added all picture sizes for Windows 10 compatibility. #> [CmdletBinding(SupportsShouldProcess=$true)]Param() function Test-Null($InputObject) { return !([bool]$InputObject) } # 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 # Continue if an image was returned If ((Test-Null $user_photo) -eq $false) { Write-Verbose "Photo exists in Active Directory." } # If no image was found in profile, use one from network share. Else { Write-Verbose "No photo found in Active Directory for $env:username, using the default image instead" $user_photo = [byte[]](Get-Content "\\$env:USERDNSDOMAIN\NETLOGON\defaultuser.jpg" -Encoding byte) } # 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 Try { 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)) $path = $dir + "\" + $file_name Write-Verbose " saving: $file_name" $user_photo | Set-Content -Path $path -Encoding Byte -Force # 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 } } Catch { Write-Error "Cannot update profile picture for $env:username." Write-Error "Check prompt elevation and permissions to files/registry." }
To make this script run hidden I resolved to creating a VBs wrapper that would silently execute the script
' ' Title: Set-ADPicture.vbs ' Author: Joakim at Jocha AB, http://jocha.se ' Modified: 2016-02-13 ' On Error Resume Next command = "powershell.exe -Noninteractive -ExecutionPolicy Bypass -Noprofile -File \\domain.local\NETLOGON\Set-ADPicture.ps1" set shell = CreateObject("WScript.Shell") shell.Run command,0
Now put both these scripts in your NETLOGON-folder (ie. \\domain.local\NETLOGON).
3. Setting up the GPO
Open the Group Policy Management Console and create a new GPO. Lets call it “Pictures”.
Edit it and go to
Computer Configuration > Policies > Windows Settings > Security Settings > Registry
Right Click on Registry and select Add Key. Then Add the Key:
MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AccountPicture\Users
Give Full Permission on this key (and sub keys) to <Domain>\Users.
Also make sure you have selected Replace Existing permission on all sub keys with inheritable permissions. Otherwise the script will not be able to update the necessary registry values.
4. Setting up the Task schedule
To run the function there are a couple of different approaches. You could either execute it from the “Logon Scripts” function in a Group policy or via Task Scheduler for example. Since you probably know how to set up a logon script, I’ll demo how to set up a scheduled job…
In the same Group Policy object as above, go to:
User Configuration > Preferences > Control Panel Settings > Scheduled Tasks
Right Click and select New Sheduled Task (At lest Windows 7) option.
Under the General tab Set Name as: Set-ADPicture
Under the Actions tab:
Create New Action Select Action “Start Program”.
From Program Script Option.
Select the VBs-script from NETLOGON.
5. Target the GPO
All the settings are now set. Go back to the Group Policy console and create your target links to the proper OUs.
Please let me know if I’ve missed something or if its not working for you.
Hi
I cannot get this to work on windows 10.
Photos are downloaded fra AD and I can see them locally. Gpo seems to run, and I have tried to run scheduled task manuelly with sucess… What should I see in regristry`?
It works ok . How I can put an image by default for users who have no image? You could modify the script to put a default image .
Hi Ismael,
I usually set a default picture (the company logo for example) when I create a new user.
But I guess you could put a "If ((Test-Null $user_photo) -eq $true)" in there and make it set a default image instead.
Best regards,
Joakim
Can you modify the powershell script to pull a high quality image from an exchange server?
using a link similar to this
https://exchangeserver.domain.com/ews/Exchange.asmx/s/GetUserPhoto?email=myemailname.domain.com&size=HR648x648
this would be really nice to be able to get high quality images
Thanks for the great work
Figured out a basic way to get the high image quality photo. Changed up your script enough to get the new photo from exchange
$url = "https://ExchangeServer.domain.com/ews/Exchange.asmx/s/GetUserPhoto?email=myemailaddress.domain.com&size=HR648x648"
$webclient = new-object System.Net.WebClient
I set it up with a Logon script to pull the image.
Thanks for getting me in the right direction.
$webclient.UseDefaultCredentials=$true
$webclient.DownloadFile($url, "C:\Users\Public\Pictures\userphoto.jpg")
$photobytes=$webclient.DownloadData($url)
Hi Billy is the any chance you could share your script or explain how you went about pulling the images from exchange server! The script above is great but the image resolution for pictures in AD is poor :(
Hi Ismael
The users you have succeed on are they local administrator or domain admin?
I have a lot of users that are not local admin, and I cannot get GPO to update REG. Eventviewer gives me a access denied? Any other have this problem?
JG
Hi Jesper,
I'm running this under regular users.
Make sure you set the registry update under "Computer Configuration" and not "User Configuration".
If it's under Computer it should apply regardless of the users permission level.
Works fine in Windows 10 but fails in Windows 8 … Is the Windows 8 version of the script available please?
Hi,
Seems to be running fine on Windows 8.1. Are you getting any error messages when running the script?
Works great on Windows 10 … any way to get it to work on Windows 7?
Can be done in Win7 but it's a bit funky.
BMP file needs to be copied to %userprofile%\AppData\Local\Temp with a name like %userdomain%+%username%.
Nothing goes to registry in Win7.
I use Windows 8.1 with ClassicShell. This script set user picture everywhere but not in old-style Start menu. When i set picture manually – start menu picture changed too. What can i do to fix this?
Hi,
I have problem with this. The picture downloads correctly to AccountPictures folder, but it isn't set – when user is login in, there is a still windows' standardard picture – not user picture. Please help.
BTW every created picture has the same dimensions – only filename is different – is it correct?
Regards
Hi,
Regarding the dimensions I believe this could be because the image that was uploaded to the profile is of a smaller size. Could you verify this, possibly by uploading a higher resolution picture.
Best regards,
Joakim
You're right – my fault :)
Regarding my problem, pictures are now loading, but not every time. I don't know what is the cause. Registry is set, pictures are downloading to corresponding folders but picture is not showing up. Sometimes picture shows only the 3rd, 4th time. Have you any idea what could be a cause? I thought picture will shows already after initially user login…
Regards
Just a heads up to anyone who got a "Network access was denied" error message on login when testing this: I had to add a 1 minute delay to the Trigger for it to work properly.
To clarify: Add a 1 minute delay to the Scheduled Task under the "Trigger tab > Edit > Advanced settings > Delay task for 1 minute" to give the OS a chance to boot up and connections to be established.
Will this work with Roaming Profiles?
Hi,
if the folder C:\ProgramData\AccountPictures does not exists ?
i have see that a ".accountpicture-ms" is created in appdata\roaming\Microsoft\Windows\accountpictures and a value in registry :
HKEY_USERS\S-1-5-21-3933378226-3492704917-825274496-2844\Software\Microsoft\Windows\CurrentVersion\AccountPicture
Best regards
That's very great. It can works on Windows 8.1 and Windows 10. Thanks very much!
Hi, the script seems to work fine. We are at a school with many users using the same machine. What we are trying to achieve is the students photo to appear as the user when they log in. At the moment there is the standard logo. At log in the students name appears but no photo. Can you help us here. Thanks
Hello Joakim,
I'm very new to all this so my question is probably simple. Where do I actually add the users photo in AD? Is there a GUI way to do it not that I followed the above directions? Thanks in advance.
Glenn
Hi Glenn,
You could use AD Photo Edit (link under chapter 1) if you prefer to use a GUI.
If you want it set up automatically you can use PowerShell instead.
Best regards,
Joakim
Hi joakim,
does the user need to be local administrator on the machine?
Hi Thaddeus,
No, the script can be executed as a normal user.
Hi Joakim,
Trying to get this working on TS 2012 R2, but when the reg path is created in the first step ({ New-Item -Path $reg_key } ) it doesn't inherit the registry rights I set a bow. So when the scripts try to create the item property ($value = New-ItemProperty -Path $reg_key -Name $name -Value $path -Force) it fails. After a while the Policy refreshes the rights in registry and then it works on a later login. Any ideas?
Awesome script! Works like a charm. Just what I needed.
Just one thing, I needed to use SYSVOL instead of NETLOGON but that is just a matter of taste. Instead of using the .vbs wrapper I published the script by using User Configuration\Windows Settings\Scripts\Logon in the GPO (Make sure you use the option Windows PowerShell scripts will run first").
it is not working for me
I converted your Script with PowerGUI to a EXE-File. So I can use it with task planer job (managed by GPO).
For Silent execution the EXE must be start with "hstart /noconsole" parameter (http://www.ntwind.com/software/hstart.html)
<a href="http://www.file-upload.net/download-11839794/jocha_ad_account_picture.exe.html">jocha_ad_account_picture.exe</a>
Thank you for the script.
Hi,
I have set up GPO etc and the AD pictures go in to the folder path but it fails on registry, here is the error i get:
New-ItemProperty : Requested registry access is not allowed.
At Set-ADPicture.ps1:58 char:18
+ … $value = New-ItemProperty -Path $reg_key -Name $name -Value $path …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (HKEY_LOCAL_MACH…1630424899-3182:String) [New-ItemProperty], SecurityException
+ FullyQualifiedErrorId : System.Security.SecurityException,Microsoft.PowerShell.Commands.NewItemPropertyCommand
Would like some help on how to get past this error.
Hi Ashley,
For troubleshooting try setting the GPO permissions in step 3 manually. If that works verify that the GPO is set up according to the guide.
Best regards.