-
Notifications
You must be signed in to change notification settings - Fork 0
/
Count_Software_Versions.sh
146 lines (121 loc) · 4.33 KB
/
Count_Software_Versions.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#!/bin/bash
#Matthew Prins 2022
#https://github.com/MatthewPrins/Jamf/
#Count number of computers or devices on a particular version of a given app
#Code for grabbing token from https://developer.jamf.com/jamf-pro/docs/jamf-pro-api-overview
#Jamf credentials
username="xxxxxx"
password="xxxxxx"
url="https://xxxxxx.jamfcloud.com"
#Group ID number -- found in URL on group's page
groupid="123"
#computers or mobile devices -- if computers is true then computers, if false then mobile devices
computers=true
#app that's version is being counted -- exact name in Jamf (INCLUDE .app extension for computers)
app="Google Chrome.app"
#Token variable declarations -- leave alone
bearerToken=""
tokenExpirationEpoch="0"
#Token functions
getBearerToken() {
response=$(curl -s -u "$username":"$password" "$url"/api/v1/auth/token -X POST)
bearerToken=$(echo "$response" | plutil -extract token raw -)
tokenExpiration=$(echo "$response" | plutil -extract expires raw - | awk -F . '{print $1}')
tokenExpirationEpoch=$(date -j -f "%Y-%m-%dT%T" "$tokenExpiration" +"%s")
}
checkTokenExpiration() {
nowEpochUTC=$(date -j -f "%Y-%m-%dT%T" "$(date -u +"%Y-%m-%dT%T")" +"%s")
if [[ tokenExpirationEpoch -gt nowEpochUTC ]]
then
echo "Token valid until the following epoch time: " "$tokenExpirationEpoch"
else
echo "No valid token available, getting new token"
getBearerToken
fi
}
#get token
checkTokenExpiration
#get path for computer or devices
if [[ $computers = true ]]; then
grouptype="computergroups"
pathtype="computer"
pathtypeapp="computer/software"
JSSpathtype="computers"
else
grouptype="mobiledevicegroups"
pathtype="mobile_device"
pathtypeapp="mobile_device"
JSSpathtype="mobiledevices"
fi
#pull XML data from Jamf, change it to a list
#curl: pull XML data based on group ID
#xmllint: keep only the mobile device IDs from the XML (e.g. <id>456</id>)
#1st sed: delete "<id>"s
#2nd sed: replace "</id>"s with spaces
#3rd sed: delete extra final space
devices=$(curl -s -H "Authorization: Bearer ${bearerToken}" "Accept: application/xml" \
$url/JSSResource/$grouptype/id/$groupid \
| xmllint --xpath "//$pathtype/id" - \
| sed 's/<id>//g' \
| sed 's/<\/id>/ /g' \
| sed 's/.$//')
#get total count of devices -- counting the number of "words" in $devices
numberDevices=$(echo -n "$devices" | wc -w)
echo $numberDevices Devices
echo
echo 0 /$numberDevices
#iterate over the IDs in this device group
versionlist=()
counter=0
for value in $devices
do
#curl: retrieve all device XML data from the current ID
#xmllint: from that XML, pull the Applications fields
deviceapps=$(curl -s -H "Authorization: Bearer ${bearerToken}" "Accept: application/xml" \
$url/JSSResource/$JSSpathtype/id/$value \
| xmllint --xpath "//$pathtypeapp/applications/application" 2>/dev/null - )
#if app is in the deviceapps list, then pull the version number
if [[ $computers = true ]]
then
#computer version
if [[ "$deviceapps" == *"<name>$app</name>"* ]]
then
#1st sed: delete everything up to and including the app name
#2nd sed: if no app version, delete all and replace with "unlisted"
#3rd sed: delete everything after the version number
#4th sed: delete everything before the version number
versionlist+=($(echo $deviceapps \
| sed "s/.*<name>$app<\/name>//" \
| sed "s/<version\/>.*/unlisted/" \
| sed "s/<\/version>.*//" \
| sed "s/.*<version>//"))
else
versionlist+=("app not present")
fi
else
#mobile app version
if [[ "$deviceapps" == *"<application_name>$app</application_name>"* ]]
then
#1st sed: delete everything up to and including the app name
#2nd sed: if no app version, delete all and replace with "unlisted"
#3rd sed: delete everything after the version number
#4th sed: delete everything before the version number
versionlist+=($(echo $deviceapps \
| sed "s/.*<application_name>$app<\/application_name>//" \
| sed "s/<application_version\/>.*/unlisted/" \
| sed "s/<\/application_short_version>.*//" \
| sed "s/.*<application_short_version>//"))
else
versionlist+=("app not present")
fi
fi
#print status every 10
let "counter+=1"
if [[ $(expr $counter % 10) = "0" ]]
then
echo $counter /$numberDevices
fi
done
echo
#count unique members and echo, from https://stackoverflow.com/questions/49263599/count-unique-values-in-a-bash-array
(IFS=$'\n'; sort <<< "${versionlist[*]}") | uniq -c