Help with a computer rename script

morsepacific
New Contributor III

I've been using this script for the last year and it's worked fine, but is now failing with the following error.
We get the username from the computer record in Jamf Pro as well as the model, truncate the model name (so MacBookPro16,1 becomes MacBookPro), then rename the machine username-xxx depending on the hardware.

Script exit code: 0 Script result: awk: can't open file J152fAP

I don't understand where this is coming from / why it's suddenly started happening / how to fix it. My script-fu is poor so I'd appreciate any insight!

#!/bin/sh

jssUser=$4
jssPass=$5
jssHost=$6


serial=$(ioreg -rd1 -c IOPlatformExpertDevice | awk -F'"' '/IOPlatformSerialNumber/{print $4}')

username=$(/usr/bin/curl -H "Accept: text/xml" -sfku "${jssUser}:${jssPass}" "${jssHost}/JSSResource/computers/serialnumber/${serial}/subset/location" | xmllint --format - 2>/dev/null | awk -F'>|<' '/<username>/{print $3}')

model=$(ioreg -rd1 -c IOPlatformExpertDevice | awk -F'"' '/model/{print $4}' model=$(ioreg -rd1 -c IOPlatformExpertDevice | awk -F'"' '/model/{print $4}') | sed 's/[0-9]*//g')

if [ "$username" == "" ]; then
    echo "Error: Username field is blank. Running Recon."
    jamf recon -endUsername $(stat -f%Su /dev/console)

fi

if [ "$model" == "MacBook," ]; then

scutil --set HostName "$username-mb"
scutil --set LocalHostName "$username-mb"
scutil --set ComputerName "$username-mb"

fi

if [ "$model" == "MacBookAir," ]; then

scutil --set HostName "$username-mba"
scutil --set LocalHostName "$username-mba"
scutil --set ComputerName "$username-mba"

fi

if [ "$model" == "MacBookPro," ]; then

scutil --set HostName "$username-mbp"
scutil --set LocalHostName "$username-mbp"
scutil --set ComputerName "$username-mbp"

fi

if [ "$model" == "iMac," ]; then

scutil --set HostName "$username-mac"
scutil --set LocalHostName "$username-mac"
scutil --set ComputerName "$username-mac"

fi

if [ "$model" == "MacPro," ]; then

scutil --set HostName "$username-mp"
scutil --set LocalHostName "$username-mp"
scutil --set ComputerName "$username-mp"

fi

echo "New computer name is set."

exit 0
3 REPLIES 3

Mauricio
Contributor II

@morsepacific Put the script into a verbose mode but adding (set -x).

#!/bin/bash
set -x

I tend to add right at the top after the shell declaration so one can get a full check, this will help with the error part.

Looking you script, it my be a copy&paste issue, but the model line looks odd and there is also an extra ) causing a parse error. I image it should be:

model=$(ioreg -rd1 -c IOPlatformExpertDevice | awk -F'"' '/model/{print $4}' | sed 's/[0-9]*//g')

As you mentioned the script has been working fine, are you seen this error on macOS Big Sur by any chance?

We use a lot of API calls here and I took the liberty to change your script (apologies for that) and added some extra checks/tests.
Also using case statement it reduces the numbers of ifs and make it short.

#!/bin/bash

jssUser="$4"
jssPass="$5"
jssHost="$6"

serial=$(/usr/sbin/ioreg -rd1 -c IOPlatformExpertDevice | /usr/bin/awk -F'"' '/IOPlatformSerialNumber/{print $4}')
model=$(/usr/sbin/ioreg -rd1 -c IOPlatformExpertDevice | /usr/bin/awk -F'"' '/model/{print $4}' | /usr/bin/sed 's/[0-9]*//g')

# make the request
response=$(/usr/bin/curl --silent --insecure --location --write-out "
%{http_code}" --request GET  --user "${jssUser}:${jssPass}" "${jssHost}/JSSResource/computers/serialnumber/${serial}/subset/location" 
--header 'Content-Type: text/xml' 
--header 'Accept: text/xml')

# get the last line which is the server's response code
http_code=$(/usr/bin/tail -n1 <<< "$response")
# get all data but the last line
content=$(/usr/bin/sed '$ d' <<< "$response")

# check the response from server
if [[ $http_code == 200 ]]; then
  #  200 is OK, so get the username
  username=$(echo "$content" | /usr/bin/xmllint --format --xpath 'string(/computer/location/username)' -)
  # check if there is info there
  if [[ -n  "$username" ]]; then
      echo "$username"
    else
      echo "Error: Username field is blank. Running Recon."
      # update jamf with logged user
      /usr/local/bin/jamf recon -endUsername $(/usr/bin/stat -f%Su /dev/console)
      # set the username variable to the logged user
      username=$(/usr/bin/stat -f%Su /dev/console)
  fi
else
  #  possible error codes: 401 = not found, 409 = conflict, 5xx =server error
  echo "Unable to get data, curl exit code: $http_code"
  exit 1
fi

setComputerName() {
  suffixModel="$1"
  computerName="${username}-${suffixModel}"
  scutil --set HostName "$computerName"
  scutil --set LocalHostName "$computerName"
  scutil --set ComputerName "$computerName"
  echo "Set new computer name to $computerName"
}

# sort the model and set the computer name
case "$model" in
  "MacBook," ) setComputerName "mb" ;;
  "MacBookAir," ) setComputerName "mba" ;;
  "MacBookPro," ) setComputerName "mbp" ;;
  "iMac," ) setComputerName "mac" ;;
  "MacPro," ) setComputerName "mp" ;;
  * ) echo "Model not defined" && exit 3 ;;
esac

exit 0

I hope it helps
Regards,

morsepacific
New Contributor III

Thanks @Mauricio !
Yes, I was testing against Big Sur and it looks like it failed there but not on Catalina. I will test this out now, thank you so much.

morsepacific
New Contributor III

I finally figured out where the 'J152fAP' was coming from; both scripts were pulling both Model and Bridge-Model, so I was getting MacBookPro,16,1
J152fAP

Or

MacBookPro,
JfAP

After the numbers were removed.

I switched the model line to use the product name, and it's working πŸ™‚

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