Jmardian wrote:
I didn't include the initial call in the script above:
#!/bin/bash
## This function calls the Jamf (newer) "Pro" API to generate a token for subsequent calls to the "Pro" or "Classic" APIs.
function getAPIToken() {
jamfURL=$1
basicAuth=$2
authToken=$(curl -s \\
--request POST \\
--url "${jamfURL}/api/v1/auth/token" \\
--header "Accept: application/json" \\
--header "Authorization: Basic ${basicAuth}" \\
2>/dev/null \\
)
## Courtesy of Der Flounder
## Source: https://derflounder.wordpress.com/2021/12/10/obtaining-checking-and-renewing-bearer-tokens-for-the-jamf-pro-api/
if [[ $(/usr/bin/sw_vers -productVersion | awk -F . '{print $1}') -lt 12 ]]; then
api_token=$(/usr/bin/awk -F \\" 'NR==2{print $4}' <<< "$authToken" | /usr/bin/xargs)
else
api_token=$(/usr/bin/plutil -extract token raw -o - - <<< "$authToken")
fi
echo ${api_token}
}
## Get the token and verify connection
# basicAuth=$(echo -n "${jamfuser}:${jamfpass}" | base64)
token=$(getAPIToken "${jamfurl}" "${basicAuth}")
if [[ "${token}" == "" ]]; then
echo "Error: Unable to authenticate"
exit 1
fi
####################################################################################################
#
# This is the essential components needed to make an encrypted API call with variables
#
####################################################################################################
# HARDCODED VALUE FOR JAMF PRO URL IS SET HERE
jamfurl="XXX"
jamfuser="XXX"
jamfpass="XXX"
# ENCRYPTION IS DEFINED HERE. FOR MORE INFORMATION ON HOW TO CREATE ENCRYPTION IN A SCRIPT, VISIT
# https://docs.jamf.com/education-services/resources/20190418/400_Resources_S2_L5_.html
EncryptedString=$4
Salt='ca89daaf664dae66'
Passphrase='06ebc9f526579b8523b376e4'
####################################################################################################
#
# SCRIPT CONTENTS - DO NOT MODIFY BELOW THIS LINE
#
####################################################################################################
# Getting the computer's serial number to make the API call
serialnumber=$(system_profiler SPHardwareDataType | awk '/Serial/ {print $4}')
# Decrypting the string above
function DecryptString() {
echo "${1}" | /usr/bin/openssl enc -md md5 -aes256 -d -a -A -S "${2}" -k "${3}"
}
string=$(DecryptString $EncryptedString $Salt $Passphrase)
model=$(system_profiler SPHardwareDataType | grep "Model Identifier" | awk '{print $3}' | sed 's/[1-9].*$//')
case $model in
MacBookPro) short=MBS ;;
MacBook) short=MB ;;
MacBookAir) short=MBA ;;
iMac) short=IMC ;;
*) short=UNK ;;
esac
# A basic API Call that's getting information for the computer.
# computerxml=$(curl -s -H “Authorization: Bearer ${token}” -H ${jamfurl}/JSSResource/computers/serialnumber/${serialnumber} -X GET)
# Finding a specific component of the XML using xpath (in this case, the ID)
# id=$(echo $computerxml | xpath 'string(/computer/general/id)')
# Create an array of Computer Names in Jamf
var=$(curl -s -H “Authorization: Bearer ${token}” -H ${jamfurl}/JSSResource/computers -X GET | tidy -xml | grep '<name>' | sed -n 's|<name>\\(.*\\)</name>|\\1|p' | grep $short | cut -d'-' -f 2)
# Add computer names to array called "name"
name=($var)
# Adds the number of values in array to varialbe "namen"
namen=${#name[@]}
# Adds the highest number in array to variable "hinumber"
IFS=$'\\n'
hinumber=$(echo "${name[*]}" | sort -nr | head -n1)
# Adds the highest number +1 to a varialbe "NUM"
NUM=$(($hinumber+1))
computerName=${short}-${NUM}
serialnumber=$(system_profiler SPHardwareDataType | awk '/Serial/ {print $4}')
curl -s -H “Authorization: Bearer ${token}” -H "Content-Type: application/xml" ${jamfurl}/JSSResource/computers/serialnumber/${serialnumber} -d "<computer><general><name>${computerName}</name></general></computer>" -X PUT
scutil --set ComputerName ${computerName}
scutil --set HostName ${computerName}
scutil --set LocalHostName ${computerName}
echo "Computer name changed to $computerName"
jamf displayMessage -message "The computer name is ${computerName} - Please make a label reflecting this. "
Do I still need curl call that you mentioned above? Clearly, I'm a little out of my scope here with scripting, as I inherited this script with my enrollment workflow. If I do need the Curl you mentioned where exactly would it need to go? Thanks for your help!
Also, here is the script result I am seeing:
Script result: No warnings or errors were found.
To learn more about HTML Tidy see http://tidy.sourceforge.net Please send bug reports to html-tidy@w3.org HTML and CSS specifications are available from http://www.w3.org/ Lobby your company to join W3C, see http://www.w3.org/Consortium <html> <head> <title>Status page</title> </head> <body style="font-family: sans-serif;"> <p style="font-size: 1.2em;font-weight: bold;margin: 1em 0px;">Unauthorized</p> <p>The request requires user authentication</p> <p>You can get technical details <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2">here</a>.<br> Please continue your visit at our <a href="/">home page</a>. </p> </body> </html>Computer name changed to MBA-1
Looks like you might have an order of operations issue. On line 29 you call the function getAPIToken with the arguments jamfurl & basicAuth, but you don't define jamfurl until line 44. Plus, basicAuth is defined in line 28, but that line commented out (and uses the variables jamfuser and jamfpass that are not defined lines 45 & 46. You need to define your variables before you start calling them.
Not trying to be mean, but this definitely looks like a script that has been updated and modified multiple times. For example, it has a function to use "encrypted" strings (line 68), but then never uses the decrypted string.Lots of commented lines that may or may not be necessary.
At this point, I would suggest doing some rubber duck debugging. https://en.wikipedia.org/wiki/Rubber_duck_debugging
Work through your script one line at a time. Try running the script locally with the command bash -x /path/to/script.sh. That will output each line as it runs, so you can confirm that commands are running successfully and, most importantly, variables are being substituted correctly. Also, you will want to run the script with exit point after key point. For example, add an exit statement right after getting the token (and add an echo $token to see the result before the exit). Run the script. Did you get a token successfully? If so, remove the exit statement and move down the line to the next major step (pull the computer list?) and repeat the process.
Being able to to debug a script, especially if you didn't write it, is a learned skill. And, while I encourage you to try to resolve this yourself, ChatGPT is a quick way to do simple troubleshooting. Try tuning your script through ChatGPT and ask it to help debug. You will still want to review your script, and it probably won't work exactly as presented. But compare the output to your original script and see if you understand the differences.