API - Update Computer Building, Room, Department

casafrancisco
New Contributor III

Hi Everyone,

What is the best way to update a Computer's Building, Room, and Department?

I have some prompts that I used to select/enter in the information, so I have the variables ready. But I am not sure how to update those fields.

Is it the Computer endpoint being updated, or is it using the Building/Room/Department as the endpoint?

Thanks for any help you can provide!

2 ACCEPTED SOLUTIONS

boberito
Valued Contributor

You'd update the computer record.

So https://myjss.com:8443/JSSResource/computers/name/COMPUTERNAME maybe or computers/id/ or computers/serial/

Then something like <computer><location><building>$Building</building></location></computer> would be the XML you'd send via a PUT.

Or if you're saving the info to a CSV you could use MUT.

View solution in original post

stevewood
Honored Contributor II
Honored Contributor II

Even easier, just use the jamf binary and recon with the additional items.

Something like: jamf recon -department <department> -room <room>

You can find the verbs with jamf help recon.

You need to make sure for department that the department already exists in Jamf and that you spell it the same.

Not sure if you can set building this way.

View solution in original post

13 REPLIES 13

jared_f
Valued Contributor

I am assuming those prompts are entered and stored on the computer themselves in a file or are they imputed on the JSS? Once imputed into the JSS the computer's building/room/department is just attached the the computer record (not sure if it synced to the client). Basically it becomes searchable in smart groups and you can scope to it too.

If you have a master list, you could use the MUT to mass update that info to your computer/device records in the JSS. https://jssmut.weebly.com

casafrancisco
New Contributor III

@jared_f they are stored on the computer from within the script. I am making the script to avoid use of MUT for less inclined people that help with our deployments.

So basically I use a system event prompt using AppleScript and assign that to a variable. But now trying to figure out how I can use the API to update those fields.

boberito
Valued Contributor

You'd update the computer record.

So https://myjss.com:8443/JSSResource/computers/name/COMPUTERNAME maybe or computers/id/ or computers/serial/

Then something like <computer><location><building>$Building</building></location></computer> would be the XML you'd send via a PUT.

Or if you're saving the info to a CSV you could use MUT.

stevewood
Honored Contributor II
Honored Contributor II

Even easier, just use the jamf binary and recon with the additional items.

Something like: jamf recon -department <department> -room <room>

You can find the verbs with jamf help recon.

You need to make sure for department that the department already exists in Jamf and that you spell it the same.

Not sure if you can set building this way.

casafrancisco
New Contributor III

@boberito Thanks I was doing that and it didn't seem to work, need to look at it and see what I messed up with my API request.

@stevewood You are the man! that makes it even easier! I'll still see if I can get it to work via the API since I just started trying to learn the API, but glad I have an easy solution to my issue!

boberito
Valued Contributor

Here's a script of mine from my GitHub (www.github.com/boberito, so maybe that'll give you an idea with more info.

#!/bin/sh

OLDIFS="$IFS"
IFS=$','

#API login info
apiuser='APIUSERNAME'
apipass='APIPASSWORD'
jamfProURL="https://myjamfpro:8443"

#update via serial number
apiURL="JSSResource/computers/serialnumber"
MacSerial=`system_profiler SPHardwareDataType | grep 'Serial Number (system)' | awk '{print $NF}'`

#XML header stuff
xmlHeader="<?xml version="1.0" encoding="UTF-8" standalone="no"?>"

#get current user info from AD
getUser=`ls -l /dev/console | awk '{ print $3 }'`
getRealName=`dscl '/Active Directory/ACADEMIC/All Domains' -read /Users/$getUser RealName | grep -v ":" | tail -1`

#API data load
xmlresult=`curl -k "$jamfProURL/JSSResource/departments" --user "$apiuser:$apipass"  -H "Accept: application/xml" --silent | xmllint --format - | awk -F'>|<' '/<name>/{print $3","}'`


selectedDepartment=`/usr/local/saes/CocoaDialog.app/Contents/MacOS/CocoaDialog dropdown --title "Select Department" --text "Select the Department to assign your computer to:
" --items $xmlresult --button1 "Ok" --float --string-output | awk -F 'Ok' '{print $1}' | tail -1`


apiData="<computer><location><username>$getUser</username><real_name>$getRealName</real_name><department>$selectedDepartment</department></location></computer>"

curl -sSkiu ${apiuser}:${apipass} "${jamfProURL}/${apiURL}/${MacSerial}" 
    -H "Content-Type: text/xml" 
    -d "${xmlHeader}${apiData}" 
    -X PUT > /dev/null


 curl -k -H "Content-Type: text/json" "$jamfProURL/JSSResource/departments" --user "$apiuser:$apipass" | cut -c 18- | rev | cut -c 4- |  rev | awk -F "},{" '{ for (i=1;i<= NF; i++)print $i }' | awk -F ":" '{print $3}'

casafrancisco
New Contributor III

It seems like my API call was correct but I was getting an error based on the department. It doesn't like that the department name is "IS&T (information systems & technology)". It worked when i changed it to Financial Aid. But i wasn't able to figure out how to make it work.

mm2270
Legendary Contributor III

@casafrancisco Most likely the special characters in the name string (&,( & )) need to be escaped properly for the XML.

But frankly, you should really be able to use the method @stevewood mentioned with a recon. For Building, Room and Department there's no need for an API script. Recon verbs are able to add those into a computer record very easily. The only thing about this is, for both Building and Department, they must exist in your Jamf Pro server already for it to be set. You can't just pass anything to them. Room doesn't adhere to this, but the other two do.

casafrancisco
New Contributor III

@mm2270 Yeah, i ended up using that method. I'm just trying to learn more with the API. My script is live now using the recon method but I was just trying to see why my API call wasn't working. I tried escaping the special characters but it didn't seem to help.

mm2270
Legendary Contributor III

@casafrancisco Yeah, understood. Always good to learn new stuff, and the API is quite useful.

In case it helps, you could use some code to convert the XML illegal characters into encoded ones for the final XML, and that should allow it to work. I incorrectly called it "escaping" but it's really "encoding", since just placing a backslash or something in front of the characters won't help at all.
Here's an example of some code. And to be clear, I'm not a perl guy, so I'm just using some code I found online. There may be an easier way to accomplish this, but this does seem to do the job.

$ var="IS&T (information systems & technology)"
$ varCleaned=$(echo "$var" | perl -p -e 'BEGIN { use CGI qw(escapeHTML); } $_ = escapeHTML($_);')
$ echo "$varCleaned"
$ IS&amp;T (information systems &amp; technology)

You should be able to use something like the above to convert the capture selection of department or building or whatever into something that can be used as a variable to plug into the XML and then it should upload without an error. It was most likely the & characters and not the parens that was causing it to fail.
Something else that can help. You can check the validity of your XML in a few different ways. One way is like

xmllint --format /path/to/file.xml

If you get a nicely formatted/indented XML printout, then all should be good. If it spits back an error, it should show you what specific sections are causing a problem.

Hope all the above helps.

boberito
Valued Contributor

You could maybe also use ' instead of " around the department name.

joethedsa
Contributor II

@casafrancisco , how did you get the prompts to select the appropriate building, room, department, etc. Was this done through AppleScript? We are looking for a way to update the location of a device record without having to log into JSS so a person that doesn't have a way to access the console can still update it interactively.

BND10706
New Contributor

Did you ever figure this out with an API? Im looking to make a quick app to change buildings of some of our assets...API would be the best mehod.