How to change local user account Picture through command terminal

norett
New Contributor

hi there,

I currently want to change my local admin account's picture through command for about 50 macs.

I tried many things, and the command below seems to work but not all the time, wonder why...?

In Terminal :

su #my admin username...)
password #enter your password

dscl . -append "/Users/admin" picture "/Library/User Pictures/Animals/Cat.tif"

where admin is the local account you want to change the picture of and cat.tif the new picture.

It seemed to work on 10.6.8, do you have any other clues on how to change the picture with a script ?

I tried apple script but it does not work !

thanks a lot

45 REPLIES 45

obi-k
Valued Contributor II

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

tech-otaku
New Contributor II

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.

davidi4
Contributor

@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

tech-otaku
New Contributor II

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

darthmaverick
New Contributor III

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.

mattparker
New Contributor

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