Get the user picture from AD and set as the local users picture

AndreasRumpl
New Contributor III

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?

4 REPLIES 4

ryan_ball
Valued Contributor

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

ryan_ball
Valued Contributor

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.

NoahRJ
Contributor II

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

Jason
Contributor II

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'