API pull Application list with Version and Computers

cholder
New Contributor II

I have been looking thought the API documentation on if there is a way to pull a list based on if they have an application installed.

For example want a list of all computers that have firefox.app installed. that list would have

Application Title
Application Version
Computer ID
Computer Name

13 REPLIES 13

thoule
Valued Contributor II

I think I needed something similar once and instead created an 'Advanced Search', then pull that in with the API.

kendalljjohnson
Contributor II

I created a script for an audit we had that lists all computers with their macOS version, all apps installed, and app versions. You could pull the information from it or use it as a launching point if you want.

#!/bin/bash

#fill in variables for your environment
jssurl=""
apiUser=""
apiPass=""

#create temp folder
mkdir /tmp/appinventory

#list all computer IDs 
allCompIDs=$(curl -k -u $apiUser:$apiPass $jssurl/JSSResource/computers | xmllint --format - | awk -F'>|<' '/<id>/,/</id>/{print $3}' | sort -n)

#get computer name for computer IDs
while read compID; do
  computerName=$(curl -k -u $apiUser:$apiPass $jssurl/JSSResource/computers/id/${compID} | xmllint --format - | awk -F'>|<' '/<name>/,/</name>/{print $3}' | head -n1)

#get macOS version for all computers
  osVersion=$(curl -k -u $apiUser:$apiPass $jssurl/JSSResource/computers/id/${compID} | xmllint --format - | awk -F'>|<' '/<os_version>/,/</os_version>/{print $3}')

#get list of applications installed on each computer name and exports to csv per computer with format compName,osVersion,appName,appVersion
  curl -k -u $apiUser:$apiPass $jssurl/JSSResource/computers/id/${compID} | xmllint --format - | awk -F'>|<' '/<applications>/,/</applications>/{print $3}' | tail -n+4 | tr '
' ',' | sed -e $'s/,,,/\
/g' | sed 's/,/.*,/,/g' | sed -e '$ d' | sed '1s;^;'"$computerName"','"$osVersion"',;' | sed 's/^/,,/g' | sed 's/,,'"$computerName"'/'"$computerName"'/g' | cut -f4 > /tmp/appinventory/$computerName.csv
done < <(echo "$allCompIDs")

#combine individual inventories into one file
cat /tmp/appinventory/*.csv > AllMacAppInventory.csv

#remove temp folder
rm -rf /tmp/appinventory

Bernard_Huang
Contributor III

Hi @kendalljjohnson

Thanks for your efforts in creating this script.

I am trying to run your script, but am getting an error.
JamfMacInventory.sh: line 23: syntax error near unexpected token `<'
JamfMacInventory.sh: line 23: `done < <(echo "allCompIDs")'

JamfMacInventory.sh is where I saved your script as, and I am running it via sudo sh JamfMacInventory.sh

Where am I going wrong?

mm2270
Legendary Contributor III

@Bernard.Huang It's a bash script that uses some specific bash functionality that doesn't work in the regular Bourne shell, so you don't want to override that. Drop the sh from your command. Instead, make sure the script is executable - chmod +x /path/to/JamfMacInventory.sh and then run it like /path/to/JamfMacInventory.sh.
Also, it probably doesn't need the sudo since there's nothing I can see in his script that would require running as root.

Bernard_Huang
Contributor III

Hi @mm2270

Your comment does make a lot of sense. Giving it executable rights should do it.

I did as you instructed, but now got a newer, but still similar error.

Here's the full error message:

sh JamfMacInventory.sh 
mkdir: /tmp/appinventory: File exists
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 22006    0 22006    0     0  82160      0 --:--:-- --:--:-- --:--:-- 82419
JamfMacInventory.sh: line 23: syntax error near unexpected token `<'
JamfMacInventory.sh: line 23: `done  < <(echo "allCompIDs")'

So I'm getting the same error no matter what I try.
I have ls -al to check attributes. It is all executable.

-rwxrwxrwx@   1 <username>  PBSDomain Users  1499 18 Feb 16:14 JamfMacInventory.sh

I also tried JamfMacInventory.sh, sh JamfMacInventory.sh, sudo sh JamfMacInventory.sh, all the same.

Anyone else that can get this script working for them?

Bernard_Huang
Contributor III

Hi guys,

I asked very nicely to our resident UNIX gurus within our company, to look into the script for me. Within 10 minutes they have updated it so now it is working for me :)

Here's our version:

#!/bin/bash

#fill in variables for your environment
jssurl=""
apiUser=""
apiPass=""

#create temp folder
mkdir /tmp/appinventory

#list all computer IDs
allCompIDs=$(curl -k -u $apiUser:$apiPass $jssurl/JSSResource/computers | xmllint --format - | awk -F'>|<' '/<id>/,/</id>/{print $3}' | sort -n)

#get computer name for computer IDs
for compID in ${allCompIDs}; do
  computerName=$(curl -k -u $apiUser:$apiPass $jssurl/JSSResource/computers/id/${compID} | xmllint --format - | awk -F'>|<' '/<name>/,/</name>/{print $3}' | head -n1)

#get macOS version for all computers
  osVersion=$(curl -k -u $apiUser:$apiPass $jssurl/JSSResource/computers/id/${compID} | xmllint --format - | awk -F'>|<' '/<os_version>/,/</os_version>/{print $3}')

#get list of applications installed on each computer name and exports to csv per computer with format compName,osVersion,appName,appVersion
  curl -k -u $apiUser:$apiPass $jssurl/JSSResource/computers/id/${compID} | xmllint --format - | awk -F'>|<' '/<applications>/,/</applications>/{print $3}' | tail -n+4 | tr '
' ',' | sed -e $'s/,,,/\
/g' | sed 's/,/.*,/,/g' | sed -e '$ d' | sed '1s;^;'"$computerName"','"$osVersion"',;' | sed 's/^/,,/g' | sed 's/,,'"$computerName"'/'"$computerName"'/g' | cut -f4 > /tmp/appinventory/${computerName}.csv
done  # < (echo "${allCompIDs}")

#combine individual inventories into one file
cat /tmp/appinventory/*.csv >> AllMacAppInventory.csv

#remove temp folder
rm -rf /tmp/appinventory

Hopefully this version , or the version provided by @kendalljjohnson works for you :)

HackNBash
New Contributor

That bad boy has to be run with bash instead of sh.
So when you call it it's:
bash path/to/filename.sh

This is because running it with sh will override the #!/bin/bash portion and run the script with sh instead.

The other option is to make the file executable and open it with ./filename.sh

kvinny
New Contributor

Bernard.Huang, Is it possible to search for a specific application like any Adobe app with that script instead of pulling all of the Applications since the users have a ton of their own apps installed?

cbd4s
Contributor II

Just have a silly question. How exactly do we run this script? I'm trying to get the same report from our Jamf Pro server.

Thanks

jbosma
New Contributor II

I use Sublime Text, went to Tools, Build. Put the csv file on the desktop.
Script worked pretty slick. There should be an easier way in JAMF to do this, however. It would be nice to be able to just pull a report for all applications/usage.

dlondon
Valued Contributor

I tried the script @kendalljjohnson and it ran fine except that it outputs bundle_id instead of version for me for each application. I'll try and understand what you did in

curl -k -u $apiUser:$apiPass $jssurl/JSSResource/computers/id/${compID} | xmllint --format - | awk -F'>|<' '/<applications>/,/</applications>/{print $3}' | tail -n+4 | tr '
' ',' | sed -e $'s/,,,/\
/g' | sed 's/,/.*,/,/g' | sed -e '$ d' | sed '1s;^;'"$computerName"','"$osVersion"',;' | sed 's/^/,,/g' | sed 's/,,'"$computerName"'/'"$computerName"'/g' | cut -f4 > /tmp/appinventory/${computerName}.csv

and correct it

kendalljjohnson
Contributor II

@dlondon Interesting. Haven't used this script for a bit, my assumption is Jamf changed the order of displayed data when pulling info for a specific Computer ID but who knows when or why it stopped working. Easiest fix is just remove sed 's/,/.*,/,/g', the new output should just include more data like App path and bundle_id.

curl -k -u $apiUser:$apiPass $jssurl/JSSResource/computers/id/${compID} | xmllint --format - | awk -F'>|<' '/<applications>/,/</applications>/{print $3}' | tail -n+4 | tr '
' ',' | sed -e $'s/,,,/\
/g' | sed -e '$ d' | sed '1s;^;'"$computerName"','"$osVersion"',;' | sed 's/^/,,/g' | sed 's/,,'"$computerName"'/'"$computerName"'/g' | cut -f4 > /tmp/appinventory/$computerName.csv

dlondon
Valued Contributor

Thanks @kendalljjohnson

I actually had a go at this ... possibly some problems are caused because some of our machines have names like george's imac instead of the proper name. Here's what I came up with as a first go based off your line:

  curl -k -u $apiUser:$apiPass $jssurl/JSSResource/computers/id/${compID} | xmllint --format - | awk -F'>|<' '/<applications>/,/</applications>/{print $3}' | tail -n+4 | tr '
' ',' | sed -e $'s/,,,/\
/g' | sed 's/^,//g' | awk -F, '{ OFS=","; $2 = ""; print }' | sed 's/,,/,/g'  | cut -d , -f 1-2  | sed -e 's/^/'"$computerName"','"$osVersion"',/' > /tmp/appinventory/"$computerName.csv"