Setting Computer Name based on Inventory Preload/Asset Tag Field

nguyend
New Contributor

Hi, 

I am trying to create a naming script for computers in my organization based on the inventory preload /Asset Tag field. The goal is to have the computer name be set based on the serial number.

i.e.. If serial is 12345 then name be set to COMP-ID-01

Thanks, 

 

5 REPLIES 5

mickgrant
Contributor III

Try using the Jamf setComputerName command. 

While it doesn't explicitly give you the ability to pull from the asset tag field, it does let you Pull the data from a CSV file.

kacey3
Contributor II

If you are still looking for the solution to this, I recently wrote a script to do this exact thing. The only requirement is that there needs to be an Extension Attribute in the Preload Inventory to define the desired computer name.

It's got some built-in redundancies when naming the computer, but that was by design to make sure all bases were covered.

 

#!/bin/bash

##########################################################################################
#
# Set Computer from Extension Attribute
# Written by KClose - Created 07/17/2024.
#
# Note:	This script assumes that the desired computer name has been stored as an 
#		Extension Attribute as part of the Prestage Inventory.
#		This Extension Attribute can be changed in the variables, below.
#
##########################################################################################


### VARIABLES ###

# Jamf API Variables.
[[ -z "$4"  ]] && { echo "API Client ID required. Exiting."; exit 1; } || { client_id=$4; }
[[ -z "$5"  ]] && { echo "API Client Secret required. Exiting."; exit 1; } || { client_secret=$5; }
[[ -z "$6"  ]] && { echo "Jamf Pro URL not defined. Using default."; jss_url="https://your.url.com"; } || { jss_url=$6; }

# Extension Attribute names.
eaCompName="Unique Computer Name" # <--- Set this to the Extension Attribute that is used to name the computer.

### JAMF API AUTHORIZATION FUNCTIONS ###
getAccessToken() {
	response=$(curl --silent --location --request POST "${jss_url}/api/oauth/token" \
		--header "Content-Type: application/x-www-form-urlencoded" \
		--data-urlencode "client_id=${client_id}" \
		--data-urlencode "grant_type=client_credentials" \
		--data-urlencode "client_secret=${client_secret}")
	access_token=$(echo "$response" | plutil -extract access_token raw -)
	token_expires_in=$(echo "$response" | plutil -extract expires_in raw -)
	token_expiration_epoch=$(($current_epoch + $token_expires_in - 1))
}

checkTokenExpiration() {
	current_epoch=$(date +%s)
	if [[ token_expiration_epoch -ge current_epoch ]]
	then
		echo "Token valid until the following epoch time: " "$token_expiration_epoch"
	else
		echo "No valid token available, getting new token"
		getAccessToken
	fi
}

invalidateToken() {
	responseCode=$(curl -w "%{http_code}" -H "Authorization: Bearer ${access_token}" $url/api/v1/auth/invalidate-token -X POST -s -o /dev/null)
	if [[ ${responseCode} == 204 ]]
	then
		echo "Token successfully invalidated"
		access_token=""
		token_expiration_epoch="0"
	elif [[ ${responseCode} == 401 ]]
	then
		echo "Token already invalid"
	else
		echo "An unknown error occurred invalidating the token"
	fi
}

### MAIN SCRIPT FUNCTIONS ###

# Function to extract the desired data from the stored device inventory.
getExtAtt() {
	# Run a loop of all Extension Attributes, looking at the name of each.
	for ((i=0;i<$eaIndex;i++)); do
		eaName=$(/usr/bin/plutil -extract "general"."extensionAttributes".$i."name" raw -o - - <<< "$inventoryOutput")
		# Compare each Extension Attribute to the desired name from the function and grab the value.
		if [[ "$eaName" ==  "$1" ]]; then
			/usr/bin/plutil -extract "general"."extensionAttributes".$i."values".0 raw -o - - <<< "$inventoryOutput"
		fi
	done
}

# Function to report success or failure to logs and ARD Info 4.
ReportLog() {
	# Check for Log File location.
	if [ ! -d /tmp/JSSLogs/ ]; then
		mkdir /tmp/JSSLogs/
	fi
	
	# Collect variables for report.
	PassFail=$1
	ErrorLog=$2
	TimeStamp=$(date)
	
	# Report to Install Log.
	echo "$TimeStamp  - Automated Rename Computer $PassFail $ErrorLog" >> /tmp/JSSLogs/InstallLog.txt
	
	# Report to ARD Info and submit to JSS.
	defaults write /Library/Preferences/com.apple.RemoteDesktop \Text4 "Rename$PassFail"
	jamf recon
	
	# Wait for the jamf command to complete.
	sleep 15
}

### MAIN SCRIPT ###

# Get API Token
checkTokenExpiration 

### Use Jamf API Classic to get the Computer ID from the Serial Number ###
# Get device serial number.
mac_serial=$(ioreg -l | awk '/IOPlatformSerialNumber/ { print $4;}' | tr -d '"')

# Get device ID from serial number.
computerID=$(/usr/bin/curl -s -X GET "$jss_url/JSSResource/computers/serialnumber/$mac_serial" -H "accept: application/xml" -H "Authorization: Bearer $access_token" | xmllint --format - | xmllint --xpath "/computer/general/id/text()" -)

### Use Jamf Pro API to collect the device inventory from the Computer ID.
# Collect the device inventory and store it as a variable.
inventoryOutput=$(/usr/bin/curl -s -X GET "$jss_url/api/v1/computers-inventory-detail/$computerID?section=GENERAL" -H "Authorization: Bearer $access_token" -H "accept: application/json")

# Count the number of Extension Attributes for looping.
eaIndex=$(/usr/bin/plutil -extract "general"."extensionAttributes" raw -o - - <<< "$inventoryOutput")

# Using the getExtAtt function above, collect the necessary data.
desiredName=$(getExtAtt "$eaCompName")

# In the event that the Serial Number was not found, report the error and exit.	
if [ "$desiredName" == "" ]; then
	echo "Desired Name not Specified or Index not readable. Exiting."
	ReportLog "Failure" "Name not found or Index file not readable."
	exit 1
fi

echo "==============="
echo "Applying variables: $mac_serial, $desiredName"

# Set the computer name to all applicable instances.
scutil --set ComputerName "$desiredName"
scutil --set HostName "$desiredName"
scutil --set LocalHostName "$desiredName"
defaults write /Library/Preferences/SystemConfiguration/com.apple.smb.server NetBIOSName -string "$DesiredName"

# Wait for all names to change.
sleep 15

# Set the computer name in JAMF.
echo "Submitting computer name to JAMF."
jamf setComputerName -name "$desiredName"

# Wait for the JAMF command to complete.
sleep 15

# Check Host Name against Desired Name. Report success or failure to log and ARD Info 4. If successful, finish the script and move on.
if [[ "$(scutil --get ComputerName)" == "$desiredName" ]]; then
	echo "Computer name changed successfully. Running recon and moving on to the next imaging script."
	ReportLog "Success" ""
	jamf policy -event $followupPolicy
	exit 0
else
	echo "Failure: Computer name does not match."
	ReportLog "Failure" "Computer name does not match"
	exit 1
fi

 

 

Dawid-S
New Contributor

Hi, cam you help me with this, how to change your script to work 'Asset tag' (just grab Asset tag from Jamf and change the name of the computer to this)? Thanks

Dawid,

Because "asset_tag" is in a different section of the API output, it was easier to create a new script that references the separate section. This version uses "asset_tag" specifically.

#!/bin/bash

##########################################################################################
#
# Set Computer from Asset Tag
# Written by KClose - Created 09/5/2024.
#
# Note:	This script uses any of the standard "General" details to name the computer.
#		Currently, the options is set to "asset_tag." Other options include,
#		but are not limited to: "barcode_1" "barcode_2" "serial_number" "id"
#
##########################################################################################


### VARIABLES ###

# Jamf API Variables.
[[ -z "$4"  ]] && { echo "API Client ID required. Exiting."; exit 1; } || { client_id=$4; }
[[ -z "$5"  ]] && { echo "API Client Secret required. Exiting."; exit 1; } || { client_secret=$5; }
[[ -z "$6"  ]] && { echo "Jamf Pro URL not defined. Using default"; jss_url="https://your.url.com"; } || { jss_url=$6; }

# Extension Attribute names.
eaCompName="asset_tag" # <--- Set this to the general attribute that is used to name the computer.

### JAMF API AUTHORIZATION FUNCTIONS ###
getAccessToken() {
	response=$(curl --silent --location --request POST "${jss_url}/api/oauth/token" \
		--header "Content-Type: application/x-www-form-urlencoded" \
		--data-urlencode "client_id=${client_id}" \
		--data-urlencode "grant_type=client_credentials" \
		--data-urlencode "client_secret=${client_secret}")
	access_token=$(echo "$response" | plutil -extract access_token raw -)
	token_expires_in=$(echo "$response" | plutil -extract expires_in raw -)
	token_expiration_epoch=$(($current_epoch + $token_expires_in - 1))
}

checkTokenExpiration() {
	current_epoch=$(date +%s)
	if [[ token_expiration_epoch -ge current_epoch ]]
	then
		echo "Token valid until the following epoch time: " "$token_expiration_epoch"
	else
		echo "No valid token available, getting new token"
		getAccessToken
	fi
}

invalidateToken() {
	responseCode=$(curl -w "%{http_code}" -H "Authorization: Bearer ${access_token}" $url/api/v1/auth/invalidate-token -X POST -s -o /dev/null)
	if [[ ${responseCode} == 204 ]]
	then
		echo "Token successfully invalidated"
		access_token=""
		token_expiration_epoch="0"
	elif [[ ${responseCode} == 401 ]]
	then
		echo "Token already invalid"
	else
		echo "An unknown error occurred invalidating the token"
	fi
}

### MAIN SCRIPT FUNCTIONS ###

# Function to report success or failure to logs and ARD Info 4.
ReportLog() {
	# Check for Log File location.
	if [ ! -d /tmp/JSSLogs/ ]; then
		mkdir /tmp/JSSLogs/
	fi
	
	# Collect variables for report.
	PassFail=$1
	ErrorLog=$2
	TimeStamp=$(date)
	
	# Report to Install Log.
	echo "$TimeStamp  - Automated Rename Computer $PassFail $ErrorLog" >> /tmp/JSSLogs/InstallLog.txt
	
	# Report to ARD Info and submit to JSS.
	defaults write /Library/Preferences/com.apple.RemoteDesktop \Text4 "Rename$PassFail"
	jamf recon
	
	# Wait for the jamf command to complete.
	sleep 15
}

### MAIN SCRIPT ###

# Get API Token
checkTokenExpiration 

### Use Jamf API Classic to get the Computer ID from the Serial Number ###
# Get device serial number.
mac_serial=$(ioreg -l | awk '/IOPlatformSerialNumber/ { print $4;}' | tr -d '"')

# Get desired computer name by looking up the system serial number.
desiredName=$(/usr/bin/curl -s -X GET "$jss_url/JSSResource/computers/serialnumber/$mac_serial" -H "accept: application/xml" -H "Authorization: Bearer $access_token" | xmllint --format - | xmllint --xpath "/computer/general/$eaCompName/text()" -)

# In the event that the Serial Number was not found, report the error and exit.	
if [ "$desiredName" == "" ]; then
	echo "Desired Name not Specified or Index not readable. Exiting."
	ReportLog "Failure" "Name not found or Index file not readable."
	exit 1
fi

echo "==============="
echo "Applying variables: $mac_serial, $desiredName"

# Set the computer name to all applicable instances.
scutil --set ComputerName "$desiredName"
scutil --set HostName "$desiredName"
scutil --set LocalHostName "$desiredName"
defaults write /Library/Preferences/SystemConfiguration/com.apple.smb.server NetBIOSName -string "$DesiredName"

# Wait for all names to change.
sleep 15

# Set the computer name in JAMF.
echo "Submitting computer name to JAMF."
jamf setComputerName -name "$desiredName"

# Wait for the JAMF command to complete.
sleep 15

# Check Host Name against Desired Name. Report success or failure to log and ARD Info 4. If successful, finish the script and move on.
if [[ "$(scutil --get ComputerName)" == "$desiredName" ]]; then
	echo "Computer name changed successfully. Running recon and moving on to the next imaging script."
	ReportLog "Success" ""
	jamf policy -event $followupPolicy
	exit 0
else
	echo "Failure: Computer name does not match."
	ReportLog "Failure" "Computer name does not match"
	exit 1
fi