Skip to main content

In our infrastructure every user has a picture saved in AD, which is then used for different purposes.



Obviously it would be nice to be able to use this picture also as the user pic for the local account.



The basic part of setting the picture is well documented here:
https://scriptingosx.com/2018/10/changing-a-users-login-picture/



The thing where i struggle is the extraction of the user pic from AD via cli.



Can someone point me in the correct direction or has someone already solved this / a similar problem?

You'd probably use ldapsearch for that. We don't use the photos in AD, but this might be a starting point:



#!/bin/bash

SERVER="dc1.us.yourcompany.com"
DN="CN=aUserLogin,OU=SomeOrgUnit,OU=AnotherOrgUnit,DC=dc1,DC=us,DC=yourcompany,DC=com"
PASSWORD="aUserLoginsPassword"
OU="ou=AnotherOrgUnit,dc=us,dc=yourcompany,dc=com"
userName="john_doe"

ldapsearch -h "$SERVER" -p 389
-x -D "$DN" -w "$PASSWORD"
-t -s sub -b "$OU" "(&(objectClass=user)(sAMAccountName=$userName))" "thumbnailPhoto"

exit 0


Source


Here is another example which might be better:



#!/bin/bash

SERVER="dc1.us.yourcompany.com"
DN="CN=aUserLogin,OU=SomeOrgUnit,OU=AnotherOrgUnit,DC=dc1,DC=us,DC=yourcompany,DC=com"
PASSWORD="aUserLoginsPassword"
OU="ou=AnotherOrgUnit,dc=us,dc=yourcompany,dc=com"
userName="john_doe"

ldapsearch -h "$SERVER" -p 389
-x -D "$DN" -w "$PASSWORD"
-t -s sub -b "$OU" "(&(objectClass=user)(sAMAccountName=$userName))" "thumbnailPhoto" | while read line ; do echo $line | egrep -q "^dn:" && name=`echo $line | sed 's/.*CN=([^,]+).*/1/'` && read line && file=`echo $line | sed 's/.*file:////'` && mv $file $name.jpg ; done


Partly stolen from here.


I actually went through this process a couple of years ago and wrote two different methods of pulling it from AD, one for bound machines (using the machine binding to auth) and another for unbound machines (using ldapsearch and an AD account to complete the lookup). Depending how your AD output is structured (usually hexdump or Base64), you'll need to convert using the xxd or base64 commands, respectively. I've used both in the code examples.



To your link of scriptingosx above, I've found dsimport works much more reliably if you build out a text file with some other attributes, and actually allows you to delete the picture/text file after you've completed the import.



Anyway, below are the two scripts:



Import on unbound computer (uses AD creds as privilege):



#!/bin/bash
#Created 2/13/17; NRJA

CurUser=$(ls -l /dev/console | cut -d " " -f 4)

#Create a folder to store the pic
mkdir ./PicFolder 2>/dev/null
ADPicPath=$(ldapsearch -LLL -x -D 'USERNAME' -H ldaps://ldap.address.com -w 'PASSWORD' -b DC=corp,DC=company,DC=com sAMAccountName=${CurUser} thumbnailPhoto | sed -n '/thumbnailPhoto/,/^$/p' | fmt -c | tr -d '
' | tr -d ' ' | cut -d ':' -f3)

if [[ ! ${ADPicPath} == "" ]]; then

echo "Saving ${CurUser}.jpg..."
base64 --decode <<< "${ADPicPath}" > ./PicFolder/"${CurUser}".jpg
chmod -f -R 777 ./PicFolder

else
echo "${CurUser} does not have a picture."
exit 1
fi

echo "0x0A 0x5C 0x3A 0x2C dsRecTypeStandard:Users 2 dsAttrTypeStandard:RecordName externalbinary:dsAttrTypeStandard:JPEGPhoto" > PicText.txt
echo "${CurUser}:./PicFolder/${CurUser}.jpg" >> PicText.txt

dscl . -delete /Users/"${CurUser}" JPEGPhoto
dsimport PicText.txt /Local/Default M

if [[ $? == 0 ]]; then
echo "AD picture successfully reimported."
else
echo "Failed to import AD picture."
#Exit and leave files intact to troubleshoot what went wrong
exit 1
fi

rm PicText.txt
rm -f -R ./PicFolder 2>/dev/null

exit 0


Import on a bound computer (uses machine bind as privilege):



#!/bin/bash
#Created 2/14/17; NRJA

CurUser=$(ls -l /dev/console | cut -d " " -f 4)
Photo=$(dscl /Search -read Users/${CurUser} dsAttrTypeNative:thumbnailPhoto 2>/dev/null | tail -1)
mkdir ./PicFolder 2>/dev/null
chmod -f -R 777 ./PicFolder

if [[ ! ${Photo} == "" ]]; then
echo "Saving ${CurUser}.jpg..."
echo ${Photo} | xxd -r -p > ./PicFolder/${CurUser}.jpg
dscl . create /Users/${CurUser} Picture ${Photo}
else
echo "ERROR: ${CurUser} does not have a picture or machine is not bound."
exit 1
fi

echo "0x0A 0x5C 0x3A 0x2C dsRecTypeStandard:Users 2 dsAttrTypeStandard:RecordName externalbinary:dsAttrTypeStandard:JPEGPhoto" > PicText.txt
echo "${CurUser}:./PicFolder/${CurUser}.jpg" >> PicText.txt

dscl . -delete /Users/$CurUser JPEGPhoto
dsimport PicText.txt /Local/Default M

if [[ $? == 0 ]]; then
echo "AD picture successfully reimported."
else
echo "Failed to import AD picture."
#Exit and leave files intact to troubleshoot what went wrong
exit 1
fi

rm PicText.txt
rm -f -R ./PicFolder 2>/dev/null

exit 0

Sorry to dig up this old thread, but it is still useful today.  When echo'ing to that PicText.txt file i'm sporadically getting some errors.  Has anyone else run into this?

/Library/Application Support/JAMF/tmp/getThumbnailPhoto.sh: line 51: PicText.txt: Read-only file system /Library/Application Support/JAMF/tmp/getThumbnailPhoto.sh: line 53: PicText.txt: Read-only file system

Unable to open import file 'PicText.txt'


Reply