Posted on 12-21-2018 05:06 AM
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?
Posted on 12-21-2018 06:10 AM
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
Posted on 12-21-2018 06:57 AM
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.
Posted on 12-21-2018 09:12 AM
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
Posted on 07-06-2022 01:25 PM
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'