I think I needed something similar once and instead created an 'Advanced Search', then pull that in with the API.
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
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?
@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.
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?
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 :)
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
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?
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
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.
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
@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
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"