API Computername creation before dep enrollment

arnokenis
New Contributor III

Hi.

As a lot of others out there getting the correct name for a computer is not always easy with dep. We use WS123456 for our computers where 123456 is a randomized number (ws stands for workstation).

Now the computer joins AD with $Serialnumber using the prestage enrollement. I want to create a computerobject with a serial number using the API before enrollment. And then using $Computername (if that is an existing variable in jamf).

Is that possible?

Binding using $Serialnumber and unbinding to bind with the correct name is hardly effecient.

4 REPLIES 4

ryan_ball
Valued Contributor

How do you determine the random number? Are you wanting to have the computer name somewhere, then when dep enrolls the device it names it this name you have pre-determined then binds? If that is the case I wouldn't consider it a random number as far as the Mac is concerned.

Or can it just actually be a random number, generated on the fly from the Mac in a script then named that and bound?

arnokenis
New Contributor III

@ryan.ball the random number is generated at our logistics departement where they tag the devices and put them in our assetmanagement database. I can access that database with an API too. So I want field services to enter the computername of the machine they want to install in a web page we host full of tools. It would then pull the serial from the assetman database and post it in the jamf api together with the computername. (other things happening is creating a AD computer object and adding that computer object to the 802.1X computers group).

boberito
Valued Contributor

In a previous job...we did some naming off of an inventory tag so kind of similar situation.

The command jamf setComputerName -name $NewComputerName will allow you to rename the computer.

You could script getting the name from your other database, set the name with that, then join AD. This could/would hold up the user from being able to login because it has to do all of that first.

If you want to get a user logged in immediately, you could join AD with the serial number name, let them login, do all the naming, then do an authenticated unbind and rebind the computer with the correct name.

You can't pre-populate the computer name into Jamf unfortunately. You need the UDID of the machine, otherwise it'll create a new record when the computer enrolls. That's the unique field it uses for a computer record.

ryan_ball
Valued Contributor

@arnokenis You can probably work with something like this below.

You would need to code out the portion where you leverage the asset database's API to gather the next available name in the "get_name" function.

You would also need to create a policy in Jamf Pro, using the Directory Bindings payload, and use a custom trigger so that this script can bind the Mac after renaming it. Obviously you'd skip binding it in the prestage.

You would also supply the Jamf Pro API username in the parameter 4 field, and the username in the parameter 5 field.

#!/bin/bash

# https://www.jamf.com/jamf-nation/discussions/30879/api-computername-creation-before-dep-enrollment

log="/Library/Logs/YourCorp/DEP_Mac_Naming.log"
scriptName=$(basename "$0")
jamfProURL=$(defaults read /Library/Preferences/com.jamfsoftware.jamf.plist jss_url)
apiUser="$4"
apiPass="$5"

# Create a policy with the Directory Binding payload and trigger could be custom and custom event would be "bindAD"
# Or change the custom event here
bindTrigger="bindAD"

function writelog () {
    DATE=$(date +%Y-%m-%d %H:%M:%S)
    /bin/echo "${1}"
    /bin/echo "$DATE" " $1" >> $log
}

function finish () {
    writelog "======== Finished $scriptName ========"
    exit "$1"
}

function get_name () {
    writelog "Determining the Mac's name..."
    # Waterver you are going to do to get the name of the computer goes here
    computerName="ThisIsTheName"
    writelog "Computer name will be set to $computerName."
}

function name_mac () {
    writelog "Setting computer name..."
    /usr/local/bin/jamf setComputerName -name "$computerName" | while read -r LINE; do writelog "$LINE"; done;
}

function api_post () {
    writelog "Updating the Asset field in JAMF Pro..."
    serial=$(/usr/sbin/system_profiler SPHardwareDataType 2> /dev/null | grep Serial |  awk '{print $NF}')
    writelog "Updating the Computer Name and Asset Tag in JAMF Pro..."
    jamfProId=$(/usr/bin/curl -s -u "${apiUser}:${apiPass}" -H "Accept: application/xml" "${jamfProURL%/}/JSSResource/computers/serialnumber/${serial}/subset/general" | perl -lne 'BEGIN{undef $/} while (/<id>(.*?)</id>/sg){print $1}' | head -1)
    result=$(/usr/bin/curl -sfku "${apiUser}:${apiPass}" -X PUT -H "Content-Type: text/xml" -d "<?xml version="1.0" encoding="ISO-8859-1"?> <computer> <general> <asset_tag>$(echo "$computerName" | cut -c9-13)</asset_tag> <name>$computerName</name> </general> </computer>" "${jamfProURL%/}/JSSResource/computers/id/${jamfProId}")
    # Check for errors in the PUT result
    if [[ -z "$jamfProId" ]] || [[ -z "$result" ]] || [[ "$result" =~ (Error|Conflict|Unauthorized|mismatch) ]]; then
        writelog "There was an error PUTing the Computer Name and Asset Tag field to the Jamf Pro Server."
        writelog "Failing over to recon."
        /usr/local/bin/jamf recon -assetTag "$(echo "$computerName" | cut -c9-13)" | while read -r LINE; do writelog "$LINE"; done;
    else
        writelog "Successfully updated the Computer Name and Asset Tag field in the Jamf Pro Server."
    fi
}

function bind_mac () {
    writelog "Binding the Mac to Active Directory..."
    /usr/local/bin/jamf policy -event "$bindTrigger" | while read -r LINE; do writelog "$LINE"; done;
}

# Create log first
/bin/mkdir -p /Library/Logs/YourCorp

writelog " "
writelog "======== Starting $scriptName ========"

get_name
name_mac
api_post
bind_mac

finish 0