API not updating XML for users Extension Attributes

cnelson
Contributor

This is for iOS devices. I have a script that I use to update user’s extension attributes based on the classes they are in. Well after the semester ends, I wanted to clear out this information as I have classes setup based on these extension attributes and and the use of smart user groups. When trying to use a bash script to read a csv file and delete all of those attributes, the script itself says that it was successful but it does not update the user. I’ve looked at both the JSS and the API and the info is not updated. It used to work and I was hoping with the new 9.99.2 update that it would be fixed but alas nothing. Please let me know if I’m missing something.

I know the script can read the cvs file because I get the correct username from each row. My jss user is an administrator and has full access. I can update mobile device xml's with no problem.

727b2e1b354447a5b2b11a8ec7e61e0f
b90d43b79808477cbaf5a4840aa9af42
37fbdbf402354f33bbb8b4e989818bf0

Here is my script:

#!/bin/sh

#Variables
jssAPIUsername="<jssusername>"
jssAPIPassword="<jsspassword>"
jssAddress="https://company.jamfcloud.com/"

#Finding which CSV to use
read -p "S, F, W or Input? (S, F, W, input)" location
shopt -s nocasematch
case "$location" in
    s)
        file="./S_Student_Update.csv"
    ;;
    f)
        file="./F_Student_Update.csv"
    ;;
    w)
        file="./W_Student_Update.csv"
    ;;
    input) 
        read -p "Please input the location of your csv file: " file
    ;;
    *)
        echo "Invalid Location. Please try again."
        exit 1
    ;;
esac

#Option to read in the path from Terminal
if [[ "$file" == "" ]]; then
    echo "There was not a vaild path to the CSV."
    echo "Please enter a path to the CSV"
    read file
fi

#Verify we can read the file
data=`cat $file`
if [[ "$data" == "" ]]; then
    echo "Unable to read the file path specified."
    echo "Ensure there are no spaces and that the path is correct."
    echo "Please try again."
    exit 1
fi

#Find how many users to import
userqty=`awk -F, 'END {printf "%s
", NR}' $file`

#Set a counter for the loop (Start at 1 because of the head in the CSV)
counter="1"

#Clears the logfile or creates it
echo "" > "./jss_logfile-delete.txt"

#Loop through the CSV and submit data to the API
while [ $counter -lt $userqty ]
do
    counter=$[$counter+1]
    line=`echo "$data" | head -n $counter | tail -n 1`
    username=`echo "$line" | awk -F , '{print $1}'`
    delete=""

    echo "Attempting to update: $username"
    echo -n "."

    # Prepare XML for update
    apiData="<user><extension_attributes><extension_attribute><name>Class ID #1</name><value>${delete}</value></extension_attribute><extension_attribute><name>Class ID #2</name><value>${delete}</value></extension_attribute><extension_attribute><name>Class ID #3</name><value>${delete}</value></extension_attribute><extension_attribute><name>Class ID #4</name><value>${delete}</value></extension_attribute><extension_attribute><name>Class ID #5</name><value>${delete}</value></extension_attribute></extension_attributes></user>"
    echo -n "."   

    #Run the User update
    Uoutput=`curl -sSkiu "${jssAPIUsername}":"${jssAPIPassword}" -H "Content-Type: text/xml" -d "<?xml version="1.0" encoding="ISO-8859-1"?>$apiData" -X PUT ${jssAddress}/JSSResource/users/name/${username}`
    echo -n "."

    echo "******************************" >> "./jss_logfile-delete.txt"
    echo "Update Log for $username" >> "./jss_logfile-delete.txt"
    echo "******************************" >> "./jss_logfile-delete.txt"
    echo "" >> "./jss_logfile-delete.txt"
    echo $Uoutput >> "./jss_logfile-delete.txt"
    echo "" >> "./jss_logfile-delete.txt"

    #Check if password needs to be updated in script
    Login=""
    Login=`echo $Uoutput | grep "HTTP/1.1 401 Unauthorized"`
    if [ "$Login" != "" ]; then
        echo " ERROR"
        echo ""
        echo "***AUTHORIZATION ISSUE!***"
        echo ""
        echo "***Please update your password!***"
        echo ""
        exit 1
    fi

    #Error Checking
    Uerror=""
    Uerror=`echo $Uoutput | grep "HTTP/1.1 404 Not Found"`
    if [[ "$Uerror" != "" ]]; then
        echo " ERROR..."
        sleep .5
        echo "$username Not Found."
        echo ""
    else
        echo " OK"
        sleep .5
        echo "$username Updated Successfully."
        echo ""
    fi

done < $file

exit 0
12 REPLIES 12

m_donovan
Contributor III

It would be easier to read your script if you put it in a script block using the >_ icon above the comment window. Just click that icon and copy your script over the pre-populated shebang.

#!/bin/bash

echo something

this="that"

exit 0

cnelson
Contributor

Thanks @m.donovan . I did not know that. This better?

dhom
New Contributor II

I only looked at your script briefly, but it looks like you're only counting 404 and 401 as errors. Anything else would print "updated successfully". Have you verified that you're getting a 201 response?

cnelson
Contributor

Yes, I have the output of this command going to a txt file. It has a 201 response but the jss or api doesn't get changed.

Uoutput=`curl -sSkiu "${jssAPIUsername}":"${jssAPIPassword}" -H "Content-Type: text/xml" -d "<?xml version="1.0" encoding="ISO-8859-1"?>$apiData" -X PUT ${jssAddress}/JSSResource/users/name/${username}`
    echo -n "."

    echo "******************************" >> "./jss_logfile-delete.txt"
    echo "Update Log for $username" >> "./jss_logfile-delete.txt"
    echo "******************************" >> "./jss_logfile-delete.txt"
    echo "" >> "./jss_logfile-delete.txt"
    echo $Uoutput >> "./jss_logfile-delete.txt"
    echo "" >> "./jss_logfile-delete.txt"

cnelson
Contributor

Here is the output.

HTTP/1.1 201 Created
 Accept-Ranges: bytes
 Cache-Control: no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0
 Content-Type: text/xml;charset=UTF-8
 Date: Mon, 26 Jun 2017 13:38:08 GMT
 Server: Restlet-Framework/2.1.7
 Set-Cookie: APBALANCEID=aws.jamfcloud-tc-p27; path=/;HttpOnly;Secure;
 Vary: Accept-Charset,Accept-Encoding,Accept-Language,Accept
 X-FRAME-OPTIONS: SAMEORIGIN
 Content-Length: 63
 Connection: keep-alive

 <?xml version="1.0" encoding="UTF-8"?><user><id>186</id></user>n201

BradB
New Contributor III
New Contributor III

@cnelson I think you're running into an open Product Issue (PI-004025) where the API ignores updates to user extension attribute values. Could you open a support ticket and reference this thread and the aforementioned PI number so that we can link the ticket to the product issue?

cnelson
Contributor

Thanks @beckerbm . I have put in a support ticket with the PI and a link to the thread. We shall see.

luke_reagor
Contributor II

We're watching for a solution to this too as we need to add EA's to about 6000 users.

glee_edin
New Contributor

We are being bitten by this issue too. Using sheagcraig's python module to modify user extension attributes.

https://github.com/sheagcraig/python-jss

The operation appears to succeed, but the attribute isn't modified. We see the problem on our jamfcloud instance, running 9.100.0-t1499435238 but not on a local dev server running 9.96.

We have a middleware to allow JSS policies to require approval, which relies on User EAs, which we are almost ready to move into live but which we obviously can't while this issue is live.

cnelson
Contributor

FYI, this should be fixed with JAMF Pro 10.1.0 Release.

f15b5edf40f545c1ba2f809df4a2f329

http://docs.jamf.com/10.1.0/jamf-pro/release-notes/Bug_Fixes_and_Enhancements.htm

WhippsT
Contributor

Can anyone here verify that this has been fixed in 10.1?

glee_edin
New Contributor

Yes, I tested 10.1 and it was fixed.