iOS total number of installed apps: Extension Attribute?

Sandy
Valued Contributor II

When we sync shared devices using Apple Configurator (1.7.2)
It randomly will skip over apps without error or any feedback.
If we look at the details of each device: total number of installed apps
we can locate the ones that have skipped apps, this view is not that helpful.
I know that there is a feature request for this, but is there any way to show this information as a display field using an extension attribute?

1 ACCEPTED SOLUTION

bumbletech
Contributor III

I had a moment to try a few things out with iPads with spaces in their names in my environment. Hopefully this will get you closer:

#!/bin/bash

#Set variables for for JSS access
apiPath="https://yourjssurl/JSSResource/mobiledevices/name/"
apiReadOnlyUser=user
apiReadOnlyPass='pass'

###############################################
### Don't edit past this line. Or whatever. ###
###############################################

#Asks for the base name of the iPad group you're wanting to check app counts on
echo ""
echo "Please enter the basename for the iPads you'd like to look up"
echo "(Make sure to include any separators between your basename and the device's number. If a space separates your basename from the device number use '%20' instead at the end of your basename.)"
read baseName

#ask how many ipads are in the cart so it knows where to stop because I didn't write this all that well
echo ""
echo "How many iPads are in the cart?"
echo "(Script assumes number sequences like 01, 02, 03... Enter at least '10' for double digits to work correctly)"
read END


echo ""
echo "Let me look those up for you..."

for i in $(seq -w 01 $END)
    do
    individualDeviceName="$baseName$i"
    curlDeviceName=${individualDeviceName// /%20}
    appcount=`curl -k -s -u $apiReadOnlyUser:"$apiReadOnlyPass" $apiPath$curlDeviceName/subset/applications | /usr/bin/awk -F'<size>|</size>' '{print $2}'`
    if [ "$appcount" == "" ]
        then
            echo "$baseName: I don't think this iPad exists, man."
        else
            echo "$baseName: $appcount apps"  
    fi

done

Other than that... Apparently, if you're on Java OpenJDK 6 your JSS will return JSON instead of XML, and we want XML. https://jamfnation.jamfsoftware.com/discussion.html?id=7673

View solution in original post

15 REPLIES 15

bumbletech
Contributor III

@Sandy

I just whipped up a quick script to let me get a birds-eye-view of app counts on shared carts the other day. You'll probably need to tweak what separates the base name from the device's number—and possibly the number of digits generated for the sequence since configurator doesn't do 01, 02, 03... for single digits.

#!/bin/bash

#Set variables for the JSS
apiPath="https://yourjss/JSSResource/mobiledevices/name/"
apiReadOnlyUser=user
apiReadOnlyPass=pass

### I'd say don't edit past this line, but you might need to change the naming scheme for your needs ###

#Asks for the base name of the iPad group you're wanting to check app counts on
echo ""
echo "Please enter the basename for the iPads you'd like to look up"
read baseName

#ask how many ipads are in the cart so it knows where to stop because I didn't write this all that well
echo ""
echo "How many iPads are in the cart?"
echo "(Never hurts to over-estimate)"
read END


echo ""
echo "Let me look those up for you..."

for i in $(seq -w 01 $END)
    do
    appcount=`curl -s -u $apiReadOnlyUser:'$apiReadOnlyPass' $apiPath$baseName-$i/subset/applications | /usr/bin/awk -F'<size>|</size>' '{print $2}'`
    if [ "$appcount" == "" ]
        then
            echo "$baseName-$i: I don't think this iPad exists."
        else
            echo "$baseName-$i: $appcount apps"   
    fi

done

Hopefully I didn't break something making it generic...

Sandy
Valued Contributor II

@jbourdon This is cool, and so close!
How would I get the hyphen out of the name search?
Our naming uses a space before the seat but does have leading zeroes so feedback comes back:
MR Cart 4-01: I don't think this iPad exists.
Actual name is MR Cart 4 01

I tried a few things but really am just guessing :)

Sandy
Valued Contributor II

@jbourdon, I found the correct places to remove the hyphen and now the feedback matches the device name but still says not found:
moCart 4 30: I don't think this iPad exists

Actual Device name: moCart 4 30

I also swapped in my full api admin user/password to be sure it was not a permissions thing.
no help

bumbletech
Contributor III

Spaces...

Try replacing the bottom part with this

for i in $(seq -w 01 $END)
    do
#changes start: this should change the spaces to "%20" and make it URL friendly
    deviceName="$baseName $i"
    curlDeviceName=${DeviceName// /%20}
    appcount=`curl -s -u $apiReadOnlyUser:'$apiReadOnlyPass' $apiPath$curlDeviceName/subset/applications | /usr/bin/awk -F'<size>|</size>' '{print $2}'`
#changes end
    if [ "$appcount" == "" ]
        then
            echo "$baseName $i: I don't think this iPad exists."
        else
            echo "$baseName $i: $appcount apps"   
    fi

done

I tried not to guess at the changes you made to fit your environment, so you might want to give it a once over.

Sandy
Valued Contributor II

shoot, no, the feedback that returns has the names exactly correct as they are in my jss, but says they don't exist.
both with my edits and the one you just sent.

bumbletech
Contributor III

My bad. Measure twice, post once.

I had "deviceName" and "DeviceName" which are not the same thing. Make sure that the "deviceName" on the line that sets "curlDeviceName" has a lower case d.

Sandy
Valued Contributor II

dang. I tried every combo of DeviceName, deviceName, all same result: "I don't think this iPad exists."

bumbletech
Contributor III

I had a moment to try a few things out with iPads with spaces in their names in my environment. Hopefully this will get you closer:

#!/bin/bash

#Set variables for for JSS access
apiPath="https://yourjssurl/JSSResource/mobiledevices/name/"
apiReadOnlyUser=user
apiReadOnlyPass='pass'

###############################################
### Don't edit past this line. Or whatever. ###
###############################################

#Asks for the base name of the iPad group you're wanting to check app counts on
echo ""
echo "Please enter the basename for the iPads you'd like to look up"
echo "(Make sure to include any separators between your basename and the device's number. If a space separates your basename from the device number use '%20' instead at the end of your basename.)"
read baseName

#ask how many ipads are in the cart so it knows where to stop because I didn't write this all that well
echo ""
echo "How many iPads are in the cart?"
echo "(Script assumes number sequences like 01, 02, 03... Enter at least '10' for double digits to work correctly)"
read END


echo ""
echo "Let me look those up for you..."

for i in $(seq -w 01 $END)
    do
    individualDeviceName="$baseName$i"
    curlDeviceName=${individualDeviceName// /%20}
    appcount=`curl -k -s -u $apiReadOnlyUser:"$apiReadOnlyPass" $apiPath$curlDeviceName/subset/applications | /usr/bin/awk -F'<size>|</size>' '{print $2}'`
    if [ "$appcount" == "" ]
        then
            echo "$baseName: I don't think this iPad exists, man."
        else
            echo "$baseName: $appcount apps"  
    fi

done

Other than that... Apparently, if you're on Java OpenJDK 6 your JSS will return JSON instead of XML, and we want XML. https://jamfnation.jamfsoftware.com/discussion.html?id=7673

Sandy
Valued Contributor II

@jbourdon!
I want to thank you and update you on my progress!
I have the script working, weirdly but working :)
Despite every single way I can think of to modify, the results come back looking like this:
moCart 4%20: 73 apps
moCart 4%20: 73 apps
moCart 4%20: 72 apps
moCart 4%20: 73 apps
moCart 4%20: 72 apps
moCart 4%20: 73 apps
etc.

But they come back in order and it is what my tech wanted so thanks much!!
He just pastes into excel.
The stupidest thing is that of the 30 devices, 4 are short 1 app, and it is a different app on each device....
Apple Configurator 1.7.2. grrrr. no errors when syncing, just randomly skipped 1 app on 4 devices

Sandy

austin_henderso
New Contributor

@jbourdon!
Thank you for posting this script. I am trying to run it against my JSS (9.99.0) and it is coming back that it cannot find the device every time. After inspecting all the calls, if I run

curl -k -s -u user:pass https://jssurl/JSSResource/mobiledevices/name/DEVICENAME/subset/applications

in Terminal, it returns everything but the line with <size>#</size>.

If I paste that URL directly into a browser, it has the line with size in it. I am not familiar with the APIs at all, so I'm at a complete loss. Any idea why it might be omitting that tag? Without it, I can't see the app count.

Thanks.

sdagley
Esteemed Contributor II

@austin_henderson Try adding -H "Accept: text/xml" to the curl command in your script. The JSS API now returns JSON responses by default, and that isn't going to make the awk part of your script happy

bumbletech
Contributor III

@austin_henderson Try this version and see if you're any better off.

austin_henderso
New Contributor

Awesome!!!

Thanks so much for your help jbourdon!!! The script now returns correct results.

cgalik
Contributor

Any way to modify this script to accept a CSV of serial numbers instead of device names? My carts don't always have sequential numbers because of failed devices being pulled out, etc.

bumbletech
Contributor III

This a basic workflow for parsing out and looping through a CSV with Unix line breaks.

#Get the path for CSV of names and attributes
echo "Please drag and drop your CSV into this window and press enter."
read csvfile

#Setup needed for parsing the CSV correctly
INPUT="$csvfile"
OLDIFS=$IFS
IFS=","
[ ! -f $INPUT ] && { echo "$INPUT file not found"; exit 99; }
#define the columns of the CSV (everthing after "while read" is a column and can be used as a variable)
while read username fullname email serialnumber
do


#do what you need to do with your script here

    #for example your curl request
    curl -s -u https://yourjssurl/JSSResource/whatever/you/need/to/do/$serialnumber

   #increase the index
    index=$[$index+1]

#end of the loop
done < $csvfile