@quedayone link has 404'd. Can you repost the code, perhaps?
Oh, I see. The URL has a "<br>" in the original link. Thanks.
When I run @jhbush1973 script, I get the following error:
DS Error: -14120 (eDSPermissionError)
Not sure why. its able to find the picture.
@brian_mccarthy Did you run as root? I got the same error without sudoing.
Using a school logo, this script still gives the screenshot for me that @marklamont posted, but it at least displays correctly at the login screen.
Regardless, I also ran into the issue of our custom school logo not appearing on the login screen using dscl. I ended up replacing a built-in User Picture (eg, fun/Medal.tif) with our school logo and used dscl to use that picture and it shows up correctly at login. Simply using dscl to add the school logo (schoolLogo.tif) and the login logo is blank. No idea why.
Using the above Jamf Pro Script of user-picture-change, anyone know why I am getting the following error in the script?
Script result: <br/>Checking for: /Library/User Pictures/Compass.jpg . . .<br/><br/>found: /Library/User Pictures/Compass.jpg<br/><br/>Changeing user icon to: /Library/User Pictures/Compass.jpg<br/>sudo: dscl: command not found<br/>sudo: dscl: command not found<br/><br/>testuser Current user picture is:<br/>/Library/User Pictures/Compass.jpg<br/>
Specifically the "sudo: dscl: command not found<br/>sudo: dscl: command not found" part? It finds the current user fine, but can't run dscl?
Got to be something simple I am missing, but I haven't found it yet.
Here in 2018 running macOS 10.13.3 and the solution posted in this thread by @joshuasee way back in 2014 is the only one that comes close to working. On the first line I had to add dsAttrTypeStandard:PrimaryGroupID after dsAttrTypeStandard:UniqueID and on the same line changed Users 4 to Users 5.
#!/bin/bash
echo "0x0A 0x5C 0x3A 0x2C dsRecTypeStandard:Users 5 dsAttrTypeStandard:RecordName dsAttrTypeStandard:UniqueID dsAttrTypeStandard:PrimaryGroupID dsAttrTypeStandard:GeneratedUID externalbinary:dsAttrTypeStandard:JPEGPhoto" > import.txt
echo $USER:$UID:$(id -g):$(dscl . -read /Users/$USER GeneratedUID | cut -d' ' -f2):/path/to/user_picture.jpg >> import.txt
dscl . -delete /Users/$USER JPEGPhoto
dsimport /path/to/import.txt /Local/Default M -u diradmin
rm import.txt
On line 4 remember to change diradmin to a valid admin user name on your system.
NOTE: When run as sudo the script didn't set/change the user picture. Run the script as an admin user then wait for dsimport to prompt you for the password.
@tech-otaku Would you be able to provide a bit more info about how to use this script? I'm not quite following how I would use this to change the settings for a particular user. Do I need to define $USER and $UID? Also, is your note at the end saying that this script will send a manual password prompt? I'm looking for something to be triggered by a policy.
My specific use case is setting the profile picture for the secondary admin user created automatically by the pre-stage enrollment settings.
Edit: did some testing and got this working. My script looks like this:
#!/bin/bash
# Script to set the profile picture for user X to picture Y
# via https://www.jamf.com/jamf-nation/discussions/4332/how-to-change-local-user-account-picture-through-command-terminal#responseChild162438
USER="user_you_want_to_update"
UID="user_uid_you_want_to_update"
echo "0x0A 0x5C 0x3A 0x2C dsRecTypeStandard:Users 5 dsAttrTypeStandard:RecordName dsAttrTypeStandard:UniqueID dsAttrTypeStandard:PrimaryGroupID dsAttrTypeStandard:GeneratedUID externalbinary:dsAttrTypeStandard:JPEGPhoto" > /usr/local/share/import.txt
echo $USER:$UID:$(id -g):$(dscl . -read /Users/$USER GeneratedUID | cut -d' ' -f2):/path/to/picture/picture.jpg >> /usr/local/share/import.txt
dscl . -delete /Users/$USER JPEGPhoto
dsimport /usr/local/share/import.txt /Local/Default M -u user_you_want_to_update
rm /usr/local/share/import.txt
exit 0
Have tested executing the script with sudo
privs and it worked as designed. Will test executing it with a policy, but anticipate the same outcome since JSS acts with root privs. To use this script, update the variables USER and UID at the beginning of the script, update the path to the picture in line 11 (I placed mine in /Library/User Pictures/Custom/logo.jpg). As it happens, the user I'm updating the profile picture for is my hidden admin that support staff use, so on line 13, I wrote out that username explicitly even though it's the same user I defined in the variable in line 7. If you are using this script to update a user picture for a different user or a non-admin user, you may need to do some more testing.
Thanks for the script!
Do I need to define $USER and $UID?
Yes. Generally, in scripting communities, people will often declare variables with generic terms. In Bash communities, it is often connoted in uppercase (e.g. $USER_NAME or $GROUPID).
Also, I would advise against using subshell commands $()
inline an entire command, as it makes scripts hard to read or diagnose, and if your subshell returns a newline, it can sometimes cause unwanted results. If you want to insert a programmatic string, I'd suggest capturing it in a variable using double quotes:
ugroupID="$(id -g)"
ugenID="$(dscl . -read /Users/$USER GeneratedUID | cut -d' ' -f2)"
Personally I like to put other variables, such as paths, into variables at the top of my scripts so they can be easily changed, should the need come up.
picPath="/path/to/picture/picture.jpg"
outFile="/path/to/import.txt"
Then use the variables in the long string:
echo ${USER}:${UID}:${ugroupID}:${ugenID}:"${picPath}" >> "${outFile}"
Also, encapsulating your variables and double-quoting paths will help ensure your script won't break in case there are spaces in your path, etc.
Update on this.
This does work as a script and a policy on 10.14.x
dscl . delete /Users/admin jpegphoto
dscl . delete /Users/admin Picture
dscl . create /Users/admin Picture "/Library/User Pictures/wunderman.tif"
but since its a poilcy script make sure you use
sudo and use the correct path to /library/User Pictures/Sports/Hockey.tiff
you can not use the " " for full path name
Hi @pranzinic do you mind sharing the exact script that worked for you?
I have an admin account that needs the same profile pic to 400+ macs, with my own pic
Thanks
@k84 This is what I'm using:
#!/bin/sh
# Get Logged in User
loggedInUser=`python -c 'from SystemConfiguration import SCDynamicStoreCopyConsoleUser; import sys; username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [username,""][username in [u"loginwindow", None, u""]]; sys.stdout.write(username + "
");'`
# Delete any Photo currently used.
dscl . delete /Users/$loggedInUser jpegphoto
sleep 1
# Delete File path
dscl . delete /Users/$loggedInUser Picture
sleep 1
# Set New Icon
dscl . create /Users/$loggedInUser Picture "/Library/User Pictures/yourpicturehere.tif"
@landon_Starr does this work for you on Mojave? It seems to work for us, but after a restart all icons that I used to adjust with this script are now plain grey silhouette of a person. Our computers run FileVault, not sure if that is part of it as well as we enable FileVault via policy and it activates after the restart.
This worked for Catalina. Even for FileVault users, the pic holds. Thanks to all.
!/bin/sh
sudo dscl . delete /Users/admin jpegphoto
sudo dscl . delete /Users/admin Picture
sudo dscl . create /Users/admin Picture /Library/User Pictures/Fun/Pic123.png
exit 0
A script I put together based on joshuasee's comment in this thread way back in 2014. Tested with Mojave, Catalina and Big Sur developer beta 9.
GitHub repo at macos-user-image.
@tech-otaku how would I modify this to give all current users on the Mac the same picture? I want to use this for existing machines and for new enrollments where I won't know the user name beforehand
@davidi4 if you mean multiple users on a single Mac, I would do this. The following directory structure is assumed:
|-- scripts/
|-- users.sh
|-- set-user-image.sh
|-- images/
|-- giraffe.jpg
First, create a script named users.sh
like so:
#!/usr/bin/env bash
for U in $(dscl . list /Users | grep -v "^_"); do
EXCLUDE=(daemon Guest nobody root)
if [[ ! " ${EXCLUDE[@]} " =~ " $U " ]]; then
echo $U
fi
done
cd
into the scripts
directory and make the script executable with chmod +x users.sh
then run the script with ./users.sh
This script simply lists all users on a single Mac excluding users whose name begins with _
and the users daemon
, Guest
, nobody
and root
. These should be the users you want to target.
Next, replace echo $U
in the script with ./set-user-image.sh -u $U -i images/giraffe.jpg
so instead of echoing the user name it is passed as an option (-u
) to set-user-image.sh
script:
#!/usr/bin/env bash
for U in $(dscl . list /Users | grep -v "^_"); do
EXCLUDE=(daemon Guest nobody root)
if [[ ! " ${EXCLUDE[@]} " =~ " $U " ]]; then
./set-user-image.sh -u $U -i images/giraffe.jpg
fi
done
Note that the image name is hard-coded in the script, so you'll need to change this. In addition, don't include the -p
and the -r
options for the set-user-image.sh
script.
Next, make the set-user-image.sh
script executable with chmod +x set-user-image.sh
Finally, run ./users.sh
again to update the login picture for multiple users. I've tested this under macOS Big Sur 11.2 with just three users.
I think @davidi4 meant how to deploy this script in Jamf as a policy, assuming that you want to do the same thing I do. Have it set a admin account's default picture. To that end, I'd just assume we'd set -i and -u as variables we can call in the policy? Granted this is because we are already deploying a folder at provisioning with some common graphic resources.
Thanks for the script, @tech-otaku, very helpful. Here is how I modified/truncated this script for use in a Jamf policy. I am sure there are more changes that I could make, but this is working for now.
#!/usr/bin/env bash
# AUTHOR: Steve Ward [steve@tech-otaku.com]
# URL: https://github.com/tech-otaku/macos-user-image.git
# README: https://github.com/tech-otaku/macos-user-image/blob/master/README.md
# Ensure the `tidy_up` function is executed every time the script terminates regardless of exit status
trap tidy_up EXIT
# # # # # # # # # # # # # # # #
# FUNCTION DECLARATIONS
#
# Function to execute when the script terminates
function tidy_up {
rm -f $TF
if [ ! -z $REVOKE ]; then
sudo -k
fi
}
# # # # # # # # # # # # # # # #
# CONSTANTS
#
# IMAGE_FILE = The image to use
# PREFS = Open the Users & Groups pane of System preferences after the users's image has been changed
# REVOKE = Revoke user's root privileges when script terminates
# USER_TO_UPDATE = The user whose image to change
# TF = The import file to pass to `dsimport`
# ER = End of record marker in the `dsimport` file
# EC = Escape character in the `dsimport` file
# FS = Field separator in the `dsimport`
# VS = Value separator in the `dsimport` file
unset IMAGE_FILE PREFS REVOKE USER_TO_UPDATE
TF=$(mktemp)
ER=0x0A # `0x0A` (Hex) = `10` (ASCII) = `LF`
EC=0x5C # `0x5C` (Hex) = `92` (ASCII) = ``
FS=0x3A # `0x3A` (Hex) = `58` (ASCII) = `:`
VS=0x2C # `0x2C` (Hex) = `44` (ASCII) = `,`
# # # # # # # # # # # # # # # #
# SET-UP
#
USER_TO_UPDATE="$3"
IMAGE_FILE="$4"
# Authenticate user upfront
sudo -v
# Quit System Preferences
killall System Preferences 2> /dev/null # Write STDERR to /dev/null to supress message if process isn't running
# # # # # # # # # # # # # # # #
# UPDATE USER IMAGE
#
# Write a record description (header line) to the import file
echo "$ER $EC $FS $VS dsRecTypeStandard:Users 2 RecordName externalbinary:JPEGPhoto" > $TF
# Write the record to the import file
echo "$USER_TO_UPDATE:$IMAGE_FILE" >> $TF
# Delete the existing `JPEGPhoto` attribute for the user
sudo dscl . delete /Users/$USER_TO_UPDATE JPEGPhoto
# Import the record updating the `JPEGPhoto` attribute for the user
sudo dsimport $TF /Local/Default M