Computer Rename Based on JamfPro Object Attributes

HNTIT
Contributor II

First some Basic Background

We are beginning to Use Apple DEP for new MAC's, so when they come, fresh out of the box, the user gets no Options, the MAC immediately looks at DEP and gets pointed at out JamfPro Cloud.

This is working great, we Have a Prestage Enrollment set up and working, so we just Add the new machine to the Scope and all is peachy.

The problem is that as an out of the box machine, it will default to a generic name "iMAC" or "MacbookPro" or "Mac Mini", this is no good to me as we have a strict naming standard to follow. The Prestaging via DEP does not seem allow for assigning a name in advance on a per machine basis, and believe me, although it would be useful to simply get the users to enter the name at a prompt, it's a no go option, and we want to try and make this as automated as possible.

So we are now looking like waiting for the machine to be plugged in, and as soon as it Enrolls we just manually update a field on its object and at next check in it will rename and then proceed to domain join.

My hope was to Have an Extension Attribute set up called "Target Computer Name" and use a Smart Group to compare it to the Computer Name, and if they didn't Match, launch a Script to rename the Machine and then possibly set another attribute to show it had been done so I could use it as a trigger for a Domain Join.

It appears Smart Groups wont allow comparison of 2 Attributes, so I looked at a script to do it.
My First Option was to use the "Target Computer Name" Extension attribute as a Variable for the script, Computer Name is automatically sent as Variable $1 so I was hoping that I could set Variable $4 as the contents of my Extension Attribute, apparently this is a No No as well.

I have been looking instead at a script to pull the "Target Computer Name" Extension Attribute directly using the API, do the rename if required and write a True/False to another Extension Attribute "Computername Matches" and use that as a trigger for my Domain Join next step. However it would appear a little tricky and every post I have found so far all look to do it in slightly differing ways, and none of them work, at least not on the version I am running (JAMF Pro 10.1.1 in the Cloud)

Can anyone offer help on this or possibly even some of the other methods I have already tried and failed with ?

1 ACCEPTED SOLUTION

HNTIT
Contributor II

It's Working Now

Thanks ALL

334487bbf5a04930901db127b77cee1e

View solution in original post

15 REPLIES 15

NoahRJ
Contributor II

What's the strict naming convention that you have to follow? Is it something where you can pull information from the machine itself and set the computer name that way (e.g. MAC address) or is it something non-machine specific like a particular location and a numerical designation?

Either way, you can probably do this in a single script to check against the current machine name value by running something like scutil --get ComputerName and if it's not the expected value or pattern the name follows, reset it. The logic will be a little more complex if it's something that can't be pulled from the computer name, but it's doable.

HNTIT
Contributor II

Sadly It's not based on any information that can be collected.

Its a 4 letter designation based on the region of the world, followed by a 2 letter code based on the device type, then a 3 number code assigned to the country/office and then an ascending 4 digit number basically assigned in the order the device arrives.

Example

EMEA-MB-0440112

EMEA - The Europe, Middle East and Africa Region
MB - Its a MacBook
044 - International Dialing Code for the UK
0112 - the 112'th MacBook in that location

So the only place we can do this is to Manually type the desired number into the Computer Object in JAMF as soon as is appears, and then try to grab it from there.

NoahRJ
Contributor II

Is there a rhyme or reason to network segments specific to region so you could segment this out based on IP addresses and assign the region and the international dialing code based on identifiable network information? You can pull the hardware information from the machine by running system_profiler SPHardwareDataType, and then maybe query the API to pull down a list of other machines that match the values you've assigned up to that point, find the last one in the set with the highest number, and add one to the value to name this new machine.

mm2270
Legendary Contributor III

Some of that it may be possible to get from the device. Certainly the 2 character device type can be gleaned in a script using ioreg or system_profiler to get the model type and then using a case statement to assign the 2 character device code.

As for both the geo region and the international dialing code, let me ask. Do user accounts get assigned to the Mac that are tied into any directory service, like AD? Or are these strictly local accounts? If it's the former, I wonder if getting user information out of the directory service to see where the user location is can be used in a script to determine the dialing code. Might be complicated to do, but might be feasible.
The last bit sounds difficult. I'm not sure how you would track the iteration of the Mac in a specific location to increment the number. I wonder if you could just use the Jamf Pro computer ID number instead, which will be unique across any Macs enrolled in the console.

HNTIT
Contributor II

The Naming standard has been in place for over 15 years now, I am not going to be able to change it just for a shortcoming in JAMF I'm afraid.

The information is not going to be able to be Generated by the machine or a combination of machine or AD information we can pull.

I need to be able to Enter a Text String into JAMF somewhere that will be used to rename the MAC, and that needs to be completed before we bind to the AD Domain.

Apologies its such a knotty issue

mm2270
Legendary Contributor III

Ok, so next question. You mentioned setting up or looking at setting up a "Target Computer Name" Extension Attribute. Is that something you are able to do? Are you populating that string today? What problem are you running into when trying to pull that string with the API exactly? There's likely a way to do it, but it may take some work and experimentation to make it work reliably.

HNTIT
Contributor II

Yes I Have set up the Extension Attribute without issue and I can enter data into it.

Every Script I can find on how to pull this out using the API does not work, most of them seem to have been written a while ago for a previous version, I cant find anything that comes close to working now. :(

NoahRJ
Contributor II

@HNTIT I just threw this together and it works fine for me on Jamf Pro 10:

#!/bin/sh

apiURL='https://FULLY-QUALIFIED-DOMAIN:8443/JSSResource/computers/serialnumber/'
apiUser='USERNAME'
apiPass='PASSWORD'

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

Extension_Attributes=$(curl -s -u ${apiUser}:${apiPass} "${apiURL}${serial}" | xpath '/computer/extension_attributes/extension_attribute' 2>/dev/null)

echo "${Extension_Attributes}"

You can drill deeper with xpath to get the specific value of the extension attribute you're looking for, but replace my values with the ones you'll be using for name, password, FQDN of your Jamf Pro endpoint, swap out with serial number (or whatever you'll be using as an identifier for the machine) if you want to test on a specific machine, and give that a go.

NoahRJ
Contributor II

Fleshing this out a little more here - you can specify the EA ID (at the EA# field below) in this and it'll return the computer name you've assigned for each one:

#!/bin/sh

apiURL='https://FULLY-QUALIFIED-DOMAIN:8443/JSSResource/computers/serialnumber/'
apiUser='USERNAME'
apiPass='PASSWORD'

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

ComputerName=$(/usr/bin/curl -s -u ${apiUser}:${apiPass} "${apiURL}${serial}" | /usr/bin/xpath '/computer/extension_attributes/extension_attribute[id = "EA#"]/value/text()' 2>/dev/null)

echo "${ComputerName}"

#Set the computer name from the returned value above
hostname $ComputerName
scutil --set ComputerName $ComputerName
scutil --set LocalHostName $ComputerName
scutil --set HostName $ComputerName

mm2270
Legendary Contributor III

Not tested here, but can you try something like this? Be sure to plug in your information, like the API username and password. If it works, you can later pass those strings as parameters to the script instead of keeping them hardcoded in.

#!/bin/bash

## Fill in these variables with your own information
jssURL="https://your.jamfpro.address:8443/"
apiUser="apiusername"
apiPass="apipassword"

## The display name of the Extension Attribute goes here
EAName="<some name goes here>"

## This gets the Mac's serial number
serialNumber=$(ioreg -rd1 -c IOPlatformExpertDevice | awk -F'"' '/IOPlatformSerialNumber/{print $4}')

## This gets the Mac's current name
macName=$(scutil --get ComputerName)

## This attempts to get the EA value using the API and the above variables
assignedName=$(curl -H "Accept: application/xml" -sfku "${apiUser}:${apiPass}" "${jssURL}JSSResource/computers/serialnumber/${serialNumber}/subset/extension_attributes" 2>/dev/null | xmllint --format - | grep -A2 "$EAName" | awk -F'>|<' '/<value>/{print $3}')

## Now compare the EA value with the current computer name
if [ ! -z "$assignedName" ]; then
    if [[ "$macName" != "$assignedName" ]]; then
        ## Rename the Mac to the assigned name
        /usr/local/bin/jamf setComputerName -name "$assignedName"
        exit 0
    else
        echo "Mac name already matches assigned name. Exiting..."
        exit 0
    fi
else
    echo "Could not get assigned name from computer record"
    exit 0
fi

Edit: I was in "long post limbo" and didn't see the ones above from @NoahRJ before hitting the Post It button. Looking at the other responses, I like the way he's getting the EA value using xpath and the EA ID a little better since that's likely more reliable. Maybe combine what he has and the rename section of my script together and it should get you where you need to be.

HNTIT
Contributor II

Very Odd, it does not work for me, tried copying and pasting it onto a terminal window, the line with the curl in it never completes, just sits there forever.

If I remove the port 8443 from the URL it completes but returns no results.

I'm using an admin, is there some special permissions you need for the API user account ???

HNTIT
Contributor II

It's Working Now

Thanks ALL

334487bbf5a04930901db127b77cee1e

ScottyBeach
Contributor

I need to figure out the same thing. Could you post the final script you settled on?
Thanks,
- Scott

McLeanSchool
New Contributor III

Here's the script I use, I name computers with the following scheme "MBA-Username". This simplifies AirDrop, as we have MacBooks and iPads, so it's easy to distinguish computers and iPads.

#!/bin/sh

jssUser=*
jssPass=*

SERIAL=$(ioreg -c IOPlatformExpertDevice -d 2 | awk -F" '/IOPlatformSerialNumber/{print $(NF-1)}')

USERINFO=$(curl -k https://jss.mcleanschool.org:8443/JSSResource/computers/serialnumber/${SERIAL}/subset/location -H "Accept: application/xml" --user "${jssUser}:${jssPass}")
USERNAME=$(echo $USERINFO | /usr/bin/awk -F'<username>|</username>' '{print $2}' | tr [a-z] [A-Z])

DEVICEINFO=$(curl -k https://jss.mcleanschool.org:8443/JSSResource/computers/serialnumber/${SERIAL}/subset/hardware -H "Accept: application/xml" --user "${jssUser}:${jssPass}")
MODEL=$(echo $DEVICEINFO | /usr/bin/awk -F'<model_identifier>|</model_identifier>' '{print $2}')

if [ -z "$USERNAME" ]
then
    USERNAME="$SERIAL"
fi

if echo "$MODEL" | grep -q "MacBookAir"
then
    PREFIX="MBA"
elif echo "$MODEL" | grep -q "MacBookPro"
then
    PREFIX="MBP"
elif echo "$MODEL" | grep -q "iMac"
then
    PREFIX="IMAC"
else
    echo "No model identifier found."
    PREFIX="MBA"
fi

COMPUTERNAME="${PREFIX}-${USERNAME}"
COMPUTERNAME=`echo ${COMPUTERNAME:0:15}`
echo "Setting computer name to $COMPUTERNAME"
/usr/sbin/scutil --set ComputerName "$COMPUTERNAME"
/usr/sbin/scutil --set LocalHostName "$COMPUTERNAME"
/usr/sbin/scutil --set HostName "$COMPUTERNAME"
dscacheutil -flushcache

HNTIT
Contributor II

Here You Go

#!/bin/sh

## Grab The URL, Username and Password Values From the JAMF Script Variables
apiUser=$4
apiPass=$5
apiURL=$6

# Outputs a blank line for reporting purposes
echo

## This gets the Mac's current name
macName=$(scutil --get ComputerName)

# Outputs Current Computer Name
echo Current Computer Name = $macName

# Outputs a blank line for reporting purposes
echo

## This gets the Mac's Serial Number
serial=$(system_profiler SPHardwareDataType | grep "Serial Number" | awk '{print $4}')

# Outputs Computers Serial Number
echo Computer Serial Number = $serial

# Outputs a blank line for reporting purposes
echo

## This gets the Target Computer Name (Extension Attribute) 
## From The JAMF Object Matching the Serial Number of the Machine
TargetComputerName=$(/usr/bin/curl -s -u ${apiUser}:${apiPass} "${apiURL}${serial}" | /usr/bin/xpath '/computer/extension_attributes/extension_attribute[id = "3"]/value/text()' 2>/dev/null)

# Outputs Target Computer Name
echo Target Computer Name = $TargetComputerName

# Outputs a blank line for reporting purposes
echo

## Now compare the Extension Attribute value with the current computer name
if [ ! -z "$TargetComputerName" ]; then
    if [[ "$macName" != "$TargetComputerName" ]]; then
        ## Rename the Mac to the assigned name
        /usr/local/bin/jamf setComputerName -name "$TargetComputerName"
        # Outputs a blank line for reporting purposes
        echo
        echo Renaming Machine to $TargetComputerName
        # Outputs a blank line for reporting purposes
        echo
        sleep 10s
        echo Forcing Re-Inventory
        # Outputs a blank line for reporting purposes
        echo
        /usr/local/bin/jamf recon
        exit 0
    else
        echo MATCH > /var/JAMF/Name+TargetName-Match.txt
        echo "Mac name already matches assigned name. Writing Marker File"
        echo "/var/JAMF/Name+TargetName-Match.txt"
        # Outputs a blank line for reporting purposes
        echo
        echo Forcing Re-Inventory
        # Outputs a blank line for reporting purposes
        echo
        /usr/local/bin/jamf recon
        # Outputs a blank line for reporting purposes
        echo
        exit 0
    fi
else
    echo "Could not get assigned name from computer record"
    exit 0
fi