Skip to main content
Question

How to change local user account Picture through command terminal


Show first post

Forum|alt.badge.img+6
  • Contributor
  • May 12, 2017

@kquan Sweet!


Forum|alt.badge.img+6
  • Contributor
  • May 14, 2017

@quedayone link has 404'd. Can you repost the code, perhaps?


jhbush
Forum|alt.badge.img+26
  • Esteemed Contributor
  • May 14, 2017

Forum|alt.badge.img+6
  • Contributor
  • May 14, 2017

Oh, I see. The URL has a "<br>" in the original link. Thanks.


Forum|alt.badge.img+3

When I run @jhbush1973 script, I get the following error:

DS Error: -14120 (eDSPermissionError)

Not sure why. its able to find the picture.


Forum|alt.badge.img+8
  • Contributor
  • May 17, 2017

@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.


Forum|alt.badge.img+4

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.


Forum|alt.badge.img+1
  • New Contributor
  • March 14, 2018

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.


Forum|alt.badge.img+5
  • Contributor
  • June 18, 2018

@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!


Forum|alt.badge.img+6
  • Contributor
  • June 19, 2018
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.


Forum|alt.badge.img+5
  • Contributor
  • January 25, 2019

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


Forum|alt.badge.img+6
  • Contributor
  • March 19, 2019

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


Forum|alt.badge.img+8

@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"

Forum|alt.badge.img+5

@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.


mvu
Forum|alt.badge.img+20
  • Jamf Heroes
  • July 30, 2020

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


Forum|alt.badge.img+1
  • New Contributor
  • October 15, 2020

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.


Forum|alt.badge.img+8
  • Contributor
  • February 4, 2021

@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


Forum|alt.badge.img+1
  • New Contributor
  • February 5, 2021

@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.


Forum|alt.badge.img+7

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.


Forum|alt.badge.img
  • New Contributor
  • May 17, 2021

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

Reply


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings