Posted on 06-17-2015 08:16 AM
I have an Excel spreadsheet (that can be easily put into CSV or tab-delimited text form), that contains the device serial numbers and asset tag information of 1,100 iPads that are present in the JSS. This spreadsheet unfortunately was NOT exported from Casper. It came from a building tech contact who was responsible for assigning iPads to each child. I wish to have the asset tag information in Casper properly.
I want to somehow import the asset tag information "as is" from the spreadsheet into each iPad. What types of calls to the REST API or SQL commands if necessary would I use?
I'll be honest, while I am fairly well knowledged in working with Casper itself, I'm really lousy as a programmer or scripter. Right now what I do when I need scripts is look at other people's original work and tweak as needed with my knowledge. Exact syntax and mechanisms used would be very helpful.
I want to thank anyone who responds in advance and hope the share knowledge here. I can also answer any questions about the situation that someone might have.
Thank you,
blackholemac
Solved! Go to Solution.
Posted on 06-17-2015 09:17 AM
I just modified the script I used for lease data updates to update the asset tag of a mobile device and tested with a device in my JSS. This worked to update the asset tag with the data I specified in the CSV file. The CSV file had only the serial number in the first column and the asset tag info in the second column with no headers at all.
#!/bin/sh
# Name: updateAssetTags.sh
# Date: 17 June 2015
# Author: Steve Wood (swood@integer.com)
# Purpose: used to read in asset tag data from a CSV file and update the record in the JSS
# This script is written for updating a mobile device in the JSS but can be altered for a computer
# by simply changing the <mobile_device> and </mobile_device> tags to <computer> and </computer>
#
# The CSV file needs to be saved as a UNIX file with LF, not CR
# Version: 1.0
#
# A good portion of this script is re-purposed from the script posted in the following JAMF Nation article:
#
# https://jamfnation.jamfsoftware.com/discussion.html?id=13118#respond
#
jssAPIUsername="<apiuser>"
jssAPIPassword="<apipassword>"
jssAddress="https://your.jss.com:8443"
file="<path-to-csv-file>"
#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"
exit 1
fi
#Find how many computers to import
computerqty=`awk -F, 'END {printf "%s
", NR}' $file`
echo "Computerqty= " $computerqty
#Set a counter for the loop
counter="0"
duplicates=[]
id=$((id+1))
#Loop through the CSV and submit data to the API
while [ $counter -lt $computerqty ]
do
counter=$[$counter+1]
line=`echo "$data" | head -n $counter | tail -n 1`
serialNumber=`echo "$line" | awk -F , '{print $1}'`
assetTag=`echo "$line" | awk -F , '{print $2}'`
echo "Attempting to update lease data for $serialNumber"
echo $serialNumber " " $myID " " $assetTag
apiData="<mobile_device><general><asset_tag>$assetTag</asset_tag></general></mobile_device>"
output=`curl -sS -k -i -u ${jssAPIUsername}:${jssAPIPassword} -X PUT -H "Content-Type: text/xml" -d "<?xml version="1.0" encoding="ISO-8859-1"?>$apiData" ${jssAddress}/JSSResource/mobiledevices/serialnumber/$serialNumber`
#Error Checking
error=""
error=`echo $output | grep "Conflict"`
if [[ $error != "" ]]; then
duplicates+=($serialnumber)
fi
#Increment the ID variable for the next user
id=$((id+1))
done
echo "The following mobile devices could not be updated:"
printf -- '%s
' "${duplicates[@]}"
exit 0
I also posted this to my GitHub: UpdateAssetTags
Test this out before using wide spread. The script needs to be modified to include your API user/pass, your JSS URL, and the path to the CSV file. The next version of this needs to be able to take the CSV file as an argument on the command line.
Good luck!
Posted on 06-17-2015 09:25 AM
@stevewood Nice work on that!
So, to have this script take the csv filee as an argument on the command line, simply replace the "file" variable with "$1"
When you run the script, you would do it like:
/path/to/script/updateAssetTags.sh /path/to/assetsfile.csv
This will use the item "/path/to/assetfile.csv" and use it as $1 and then use that in the script as the file to iterate over.
The $1 thing will only work correctly when its just run from Terminal and not when run out of Casper since $1 already get assigned by Casper of course.
Posted on 06-17-2015 08:26 AM
Hi @blackholemac Does the spreadsheet only have the iOS device serial # and the asset tag, in that order? Nothing else in any given row?
I'm not certain what exact data might be need to do an update to existing mobile device records. I'm guessing certain pieces of information are going to be required, but I don't know exactly what that is. Its possible a MAC address may also be needed.
its possible to iterate over a spreadsheet, or more specifically a tab or comma delimited file and generate the necessary API data and do a PUT to each record to update them. We might just need to do some digging on exactly what the API expects when doing a PUT.
Posted on 06-17-2015 08:45 AM
Before re-inventing the wheel, @mm2270 & @blackholemac you might pick through this post and see if any of it will work:
You should be able to update the mobile device just based on s/n. The CSV just needs to have the two columns in it with no headers.
Posted on 06-17-2015 08:47 AM
@mm2270 I appreciate the prompt and thoughtful reply.
In answer, my spreadsheet contains three column fields actually, figured the first field was irrelevant and could be stripped from the CSV that we script with.. Column one is our AD username for the user who has the device (we are using VPP 2.0), column two is the asset tag (which takes the form of a 5 digit number) and column three is the device serial. If this is a two part process, I am open to suggestions. I can also shift the columns to a different order if need be.
Blackholemac
Posted on 06-17-2015 08:53 AM
I think @stevewood is onto something here. It sounds like you already have the data needed. You can parse the spreadsheet data you already have, find the computer ID based on serial number and PUT whatever data you want. The script he put into that post is almost drag and drop for your purposes you would just need to change the "lease expires" variable to the asset information. I may be missing something so please correct me If I am, thanks!
Posted on 06-17-2015 09:17 AM
I just modified the script I used for lease data updates to update the asset tag of a mobile device and tested with a device in my JSS. This worked to update the asset tag with the data I specified in the CSV file. The CSV file had only the serial number in the first column and the asset tag info in the second column with no headers at all.
#!/bin/sh
# Name: updateAssetTags.sh
# Date: 17 June 2015
# Author: Steve Wood (swood@integer.com)
# Purpose: used to read in asset tag data from a CSV file and update the record in the JSS
# This script is written for updating a mobile device in the JSS but can be altered for a computer
# by simply changing the <mobile_device> and </mobile_device> tags to <computer> and </computer>
#
# The CSV file needs to be saved as a UNIX file with LF, not CR
# Version: 1.0
#
# A good portion of this script is re-purposed from the script posted in the following JAMF Nation article:
#
# https://jamfnation.jamfsoftware.com/discussion.html?id=13118#respond
#
jssAPIUsername="<apiuser>"
jssAPIPassword="<apipassword>"
jssAddress="https://your.jss.com:8443"
file="<path-to-csv-file>"
#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"
exit 1
fi
#Find how many computers to import
computerqty=`awk -F, 'END {printf "%s
", NR}' $file`
echo "Computerqty= " $computerqty
#Set a counter for the loop
counter="0"
duplicates=[]
id=$((id+1))
#Loop through the CSV and submit data to the API
while [ $counter -lt $computerqty ]
do
counter=$[$counter+1]
line=`echo "$data" | head -n $counter | tail -n 1`
serialNumber=`echo "$line" | awk -F , '{print $1}'`
assetTag=`echo "$line" | awk -F , '{print $2}'`
echo "Attempting to update lease data for $serialNumber"
echo $serialNumber " " $myID " " $assetTag
apiData="<mobile_device><general><asset_tag>$assetTag</asset_tag></general></mobile_device>"
output=`curl -sS -k -i -u ${jssAPIUsername}:${jssAPIPassword} -X PUT -H "Content-Type: text/xml" -d "<?xml version="1.0" encoding="ISO-8859-1"?>$apiData" ${jssAddress}/JSSResource/mobiledevices/serialnumber/$serialNumber`
#Error Checking
error=""
error=`echo $output | grep "Conflict"`
if [[ $error != "" ]]; then
duplicates+=($serialnumber)
fi
#Increment the ID variable for the next user
id=$((id+1))
done
echo "The following mobile devices could not be updated:"
printf -- '%s
' "${duplicates[@]}"
exit 0
I also posted this to my GitHub: UpdateAssetTags
Test this out before using wide spread. The script needs to be modified to include your API user/pass, your JSS URL, and the path to the CSV file. The next version of this needs to be able to take the CSV file as an argument on the command line.
Good luck!
Posted on 06-17-2015 09:25 AM
@stevewood Nice work on that!
So, to have this script take the csv filee as an argument on the command line, simply replace the "file" variable with "$1"
When you run the script, you would do it like:
/path/to/script/updateAssetTags.sh /path/to/assetsfile.csv
This will use the item "/path/to/assetfile.csv" and use it as $1 and then use that in the script as the file to iterate over.
The $1 thing will only work correctly when its just run from Terminal and not when run out of Casper since $1 already get assigned by Casper of course.
Posted on 06-17-2015 09:49 AM
@mm2270 and @stevewood
I want to thank you and am marking your posts as answers. You two hit the nail on the head for us here. I love that about JAMFNation! Now, if you two have just a hair more patience with me, I want to take this even a step further:
This is where you need more background info...when our 1 to 1 students enroll new iPads we have the buildings mark who is getting which asset and we have records of which asset is tied to which serial. Here's where the "step further" comes in. Right now our users will enroll an iPad and get their apps and such using DEP/VPP 2.0/Apple ID for Students. A typical iPad is named "jschmoe's iPad" as that sort of name comes by default. It has ALWAYS been this district's practice to computers and electronic devices by the asset tag number. (I won't debate the merits of that as I can see that both being good and bad personally, but that has historically been our practice). As you also know, our students can be pretty creative in changing the names of their iPads to things like "F* Off" or other similar niceties. We essentially gave up trying to stop people changing iPad names early on last year. Since then we have received iOS 8.x and new builds of Casper. There is specifically a checkbox in the device naming record that prevents the name from being changed now.
Here's my next idea based on this info: After we succeed in appending the numbers into the asset tag field in Casper using your VERY HELPFUL scripts and verify that all worked well. Is it possible to do another step that would replace the device name (not the unique identifier, but the friendly name that users see) with the data that is now present in the asset tag field? Then to go out on a limb one last time...is it programmatically possible then to activate the checkbox to lock down the device name for all of the iPads?
Sorry to take this a step further, but you folks' great ideas have caused all kinds of lights to go off in my head.
Thank you in advance,
blackholemac
Posted on 06-17-2015 10:15 AM
@blackholemac glad to be of assistance!
Now, for your full scenario, changing the name of the mobile device in the JSS to the asset tag is relatively simple. Just update the "apiData" line (line 52) in the script above to this:
apiData="<mobile_device><general><asset_tag>$assetTag</asset_tag><display_name>$assetTag</display_name><device_name>$assetTag</device_name><name>$assetTag</name></general></mobile_device>"
That will update the asset tag info and change all of the names to the same as the asset tag.
I do not see (with a quick glance) in the API a way to enforce the name of the device. But I'll look again.
Posted on 06-17-2015 10:22 AM
@stevewood thank you...I would have understood if you blew me off. That addition is helpful and if I could give you credit twice I would.
I looked at the api by going to https://ourserver:8443/api and didn't see a way to mass enforce no name changes. There is a way to do it at the prestage level right before you assign tags but these already have tags on them. If you find a way let me know...maybe it can be done on the SQL side??
Thank you again,
Brian
Posted on 06-17-2015 10:28 AM
Hey @brysontyrrell do you know of a way to check that box via the API? The "Enforce Mobile Device Name" checkbox that is present when you edit the general tab of a mobile device.
Posted on 06-17-2015 10:39 AM
I haven't used the command personally yet, so the xml structure would need to be researched a bit, but the command is in the api under mobile device commands. Its titled DeviceName.
One thing to note though, is this is not a permanent change, it will force the iPad name to the desired name, but students are still able to change the iPad name to anything else they want after the name change takes place. Everytime the iPad checks back in the name will be forced back to the desired name, but the name itself is not locked, the feature to lock the name and prevent changed was announced at WWDC as part of iOS 9.