Help with a script to set computer name

GreggPattison
New Contributor

I am having some trouble with a script to change the computer name to First Last Computer Model.  Here is what I currently have and it is only changing it to First Last.  Any help would be appreciated. Here is what I have currently.

 

#!/bin/sh

#gets current logged in user
getUser=$(ls -l /dev/console | awk '{ print $3 }')

#gets model name
model=$(/usr/sbin/ioreg -rd1 -c IOPlatformExpertDevice | /usr/bin/awk -F { print $2 } | /usr/bin/sed 's/[0-9]*//g')

#gets named
firstName=$(finger -s $getUser | head -2 | tail -n 1 | awk '{print toupper($2)}')
lastName=$(finger -s $getUser | head -2 | tail -n 1 | awk '{print toupper($3)}')

computerName="$firstName $lastName $Model"

#set all the name in all the places
scutil --set ComputerName "$computerName"
scutil --set LocalHostName "$computerName"
scutil --set HostName "$computerName"

9 REPLIES 9

easyedc
Valued Contributor II

Not knowing exactly how you want your computers to be named, I would personally use a few different tools compared to what you've shown above.  Once you have your current user, take a look at dscl - 

dscl . -read /Users/$getUser

 and pull out whatever info from that you're after.   Dscl doesn't play nicely with grep, so you'd end up calling data in this format:

/usr/bin/dscl . -read /Users/$GetUser dsAttrTypeStandard:RealName | sed 's/RealName://g' | tr '\n' ' ' | sed 's/^ *//;s/ *$//'

As for the model, is this what you're after?

/usr/sbin/system_profiler SPHardwareDataType | grep Identifier | /usr/bin/awk '{ print $NF }'

 Your commands were missing a few ' marks in a few key places. Can you provide an example name that you're after?  Also, FWIW, since many folks don't use directory service based accounts anymore, some of the data you get may be not what you're looking for if users are allowed to self-set up through ABM enrolled devices. 

Also, if your computers are connected to the network but idle/no one logged in, you might get some false positives, so checking 

if [ "($GetUser)" == "_windowserver" ]; then
echo "<result>No one logged in</result>"
exit 1
else
echo "<result>$GetUser logged in</result>"
fi
exit 0

 Good Luck!

Thanks for the info. An example I am looking for would be JohnSmithMacBookPro

joshuasee
Contributor III

With an eye towards fewer commands and less parsing at some cost to readability:

#!/bin/sh
getUser=$(/usr/bin/id -F $(/usr/bin/stat -f%Su /dev/console));
modelId=$(/usr/libexec/PlistBuddy -c "Print :Dict:model" /dev/stdin <<< $(/usr/sbin/ioreg -ard1 -c IOPlatformExpertDevice));
/usr/local/bin/jamf setComputerName -name ${getUser/[^a-zA-Z\d\s]/_}_${modelid/,/_};

What's going on:

  1. The stat command is ask to provide the name of the owner of the console, which is the logged in user.
  2. The id command looks up the long form of the user name given by stat.
  3. ioreg produces a report of computer information, including the desired model identifier, in XML.
  4. Plistbuddy gets the model from the ioreg report.
  5. Bash variable substitutions, also compatible with zsh, swap out commas, spaces, and other non-alphanumerics for underscores to create an acceptable hostname.
  6. The jamf set computername command is called to name the computer.

Some notes:

  • Apple has a more complex command for getting the console that better covers some edge cases than stating /dev/console, but they are edge cases, usually involving multiple simultaneous logged in users, which doesn't seem likely here.
  • This doesn't check for a user being logged in before generating a name.
  • Using PlistBuddy eats more processor cycles than parsing with awk and sed, so perhaps its not the best choice for an EA, but it provides reliable parsing thanks to XML. Xmllint and an xpath might make for clearer code.
  • This might still choke on valid user long names with non-latin characters. Using user names for hostnames is often not a good idea.

Thanks for the info. That gets me where I already am, but with a lot let and is more simplified. Still not pulling the model getting error: Script result: Print: Entry, ":Dict:model", Does Not Exist

 

Hmm. Here are a couple of different versions of that line. The second is slower, but hopefully easier to read:

modelId=$(/usr/sbin/ioreg -rd1 -c IOPlatformExpertDevice | /usr/bin/sed -n '/[0-9]\,[0-9]/!d;s/[\"<>,]//g;s/[0-9]//g;s/.*.model.=.//p');
modelId=$(/usr/sbin/system_profiler -detailLevel mini SPHardwareDataType | /usr/bin/sed -n 's/ //g;s/ModelName://p');

 

jcarr
Release Candidate Programs Tester

I would strongly recommend not using First or Last name in the device name for devices.  Since the device name is broadcast in the clear on any associated network, PII in the device name could be a security and even a safety risk, especially in an EDU setting where devices may be in the hands of minor children.

 

Here's an example of a one-line command that can be used with the 'Files and Processes' payload in a policy to set a unique computer name:

 

/usr/local/bin/jamf setComputerName -name "Mac-$(ifconfig en0 | awk '/ether /{print $2}' | tr -d :’)"

I assumed that using names was manadated by someone other than the OP, but yes, using them isnt great from a privacy perspective. The jamf binary has a simpler method for a unique name, however:

jamf setComputerName -useSerialNumber

jcarr
Release Candidate Programs Tester

Agreed, but as SMEs, it's sometimes our responsibility as IT admins to inform leadership about potential security and safety risks and advocate to adjust policies accordingly.  As a parent, I would be very concerned about my district exposing PII in this manner.

 

Good point on the setComputerName command.  My one-liner has been around a while, so it may predate this capability.  I'll have to revisit the options there.

 

Thanks!

howie_isaacks
Valued Contributor II

You could use the user's initials instead or at least not the whole name. I have several Mac naming scripts that I have written for clients in the past who wanted specific computer naming schemes. The only problem with using initials is that some users may have the same initials. You could combine user initials with the serial number of the Mac. 

This will give you the computer's serial number:

system_profiler SPHardwareDataType | grep "Serial Number" | /usr/bin/awk '{print $4}'

This will give you the user's first initial and convert it to a capital letter:

firstInitial=$(finger -s $currentUser | head -2 | tail -n 1 | awk '{print toupper ($2)}' | cut -c 1)

This will give you the user's last initial and convert it to a capital letter:

lastInitial=$(finger -s $currentUser | head -2 | tail -n 1 | awk '{print toupper ($3)}' | cut -c 1)

Use the command for the serial above to create the variable for "serial".

serial=$(system_profiler SPHardwareDataType | grep "Serial Number" | /usr/bin/awk '{print $4}')

Now create a variable for the computer name. I added a dash between the serial and the initials:

computerName=""$serial"-"$firstInitial""$lastInitial""

The final result when you echo $computerName will be:

VXJ1PWLM2C-HI

*That's not my real serial I made up that one. You would then use what ever command you want to use to rename the computer using the "computerName" variable.