/
api-macOSManagedSoftwareUpdates
219 lines (188 loc) · 6.81 KB
/
api-macOSManagedSoftwareUpdates
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
#!/bin/sh
# Use the Jamf Pro API to send macOS updates
# to computers listed in the deviceIds array
# identified by their id. maxDefferrals,
# version, and updateAction can be changed
# for your specific needs.
#
# Updated: 3.01.2022 @ Robjschroeder
#
# Updated: 05.03.2022 @robjschroeder
# Added a couple more parameters as Jamf added
# some additional functionality
#
# Updated: 07.07.2022 @robjschroeder
##################################################
# Variables -- edit as needed
# Jamf Pro API Credentials
jamfProAPIUsername=""
jamfProAPIPassword=""
jamfProURL=""
# Token declarations
token=""
tokenExpirationEpoch="0"
# Update settings
# Allow users to defer the update the provided number of
# times before macOS forces the update. If a value is
# provided, the Software Update will use the InstallLater install action.
maxDeferrals=""
# If no value is provided, the version will default to latest version based
# on device eligibility.
version=""
# If no value is provided, the skipVersionVerification will default to false.
# If a value is provided, the specified version will be forced to complete
# DownloadAndInstall install action.
skipVersionVerification=""
# ApplyMajorUpdate setting is available only when updating to the latest version
# based on device eligibility. If no value is provided, the calculated latest version
# will only include minor version updates. If a value is provided, the calculated latest
# version will include minor and major version updates.
applyMajorUpdate=""
# If not set, forceRestart will default to false. Can only be true if using
# the DownloadAndInstall install action and the devices the command is sent
# to are on macOs 11 or higher. If true, the DownloadAndInstall action is performed,
# a restart will be forced. MaxDeferral will be ignored if defined.
forceRestart=""
# MaxDeferral is ignored if using the DownloadOnly install action.
# Options: DOWNLOAD_ONLY or DOWNLOAD_AND_INSTALL
updateAction=""
# The Jamf Pro Computer ID you would like to send this command to
compID=""
#
##################################################
# Functions -- do not edit below here
# Get a bearer token for Jamf Pro API Authentication
getBearerToken(){
# Encode credentials
encodedCredentials=$( printf "${jamfProAPIUsername}:${jamfProAPIPassword}" | /usr/bin/iconv -t ISO-8859-1 | /usr/bin/base64 -i - )
authToken=$(/usr/bin/curl -s -H "Authorization: Basic ${encodedCredentials}" "${jamfProURL}"/api/v1/auth/token -X POST)
token=$(/bin/echo "${authToken}" | /usr/bin/plutil -extract token raw -)
tokenExpiration=$(/bin/echo "${authToken}" | /usr/bin/plutil -extract expires raw - | /usr/bin/awk -F . '{print $1}')
tokenExpirationEpoch=$(/bin/date -j -f "%Y-%m-%dT%T" "${tokenExpiration}" +"%s")
}
checkVariables(){
# Checking for Jamf Pro API variables
if [ -z $jamfProAPIUsername ]; then
echo "Please enter your Jamf Pro Username: "
read -r jamfProAPIUsername
fi
if [ -z $jamfProAPIPassword ]; then
echo "Please enter your Jamf Pro password for $jamfProAPIUsername: "
read -r -s jamfProAPIPassword
fi
if [ -z $jamfProURL ]; then
echo "Please enter your Jamf Pro URL (with no slash at the end): "
read -r jamfProURL
fi
# Checking for additional variables
# Update settings
if [[ $maxDeferrals = "" ]]; then
read -p "Do you need to add a value to the maxDeferrals variable? [Y/N]" ans
if [[ ${ans} = Y || ${ans} = y ]]; then
read -p "Enter the number of deferrals you would like to assign: " maxDefferals
else
echo "Keeping maxDefferals empty"
fi
fi
if [[ $version = "" ]]; then
read -p "Do you need to add a value to the version variable? [Y/N]" ans
if [[ ${ans} = Y || ${ans} = y ]]; then
read -p "Enter the version you would like to assign: " version
else
echo "Keeping version empty"
fi
fi
if [[ $skipVersionVerification = "" ]]; then
read -p "Do you need to add a value to the skipVersionVerification variable? [Y/N]" ans
if [[ ${ans} = Y || ${ans} = y ]]; then
read -p "Enter true or false: " skipVersionVerification
else
echo "Keeping skipVersionVerification empty"
fi
fi
if [[ $applyMajorUpdate = "" ]]; then
read -p "Do you need to add a value to the applyMajorUpdate variable? [Y/N]" ans
if [[ ${ans} = Y || ${ans} = y ]]; then
read -p "Enter true or false: " applyMajorUpdate
else
echo "Keeping applyMajorUpdate empty"
fi
fi
if [[ $forceRestart = "" ]]; then
read -p "Do you need to add a value to the forceRestart variable? [Y/N]" ans
if [[ ${ans} = Y || ${ans} = y ]]; then
read -p "Enter true or false: " forceRestart
else
echo "Keeping forceRestart empty"
fi
fi
# MaxDeferral is ignored if using the DownloadOnly install action.
# Options: DOWNLOAD_ONLY or DOWNLOAD_AND_INSTALL
if [[ $updateAction = "" ]]; then
read -p "Do you need to add a value to the updateAction variable? [Y/N]" ans
if [[ ${ans} = Y || ${ans} = y ]]; then
read -p "Enter the number of deferrals you would like to assign: " updateAction
else
echo "Keeping updateAction empty"
fi
fi
if [ $compID = "" ]; then
read -p "Please enter the computer id that you would like to send this command to: " compID
fi
}
checkTokenExpiration() {
nowEpochUTC=$(/bin/date -j -f "%Y-%m-%dT%T" "$(/bin/date -u +"%Y-%m-%dT%T")" +"%s")
if [[ tokenExpirationEpoch -gt nowEpochUTC ]]
then
/bin/echo "Token valid until the following epoch time: " "${tokenExpirationEpoch}"
else
/bin/echo "No valid token available, getting new token"
getBearerToken
fi
}
# Invalidate the token when done
invalidateToken(){
responseCode=$(/usr/bin/curl -w "%{http_code}" -H "Authorization: Bearer ${token}" ${jamfProURL}/api/v1/auth/invalidate-token -X POST -s -o /dev/null)
if [[ ${responseCode} == 204 ]]
then
/bin/echo "Token successfully invalidated"
token=""
tokenExpirationEpoch="0"
elif [[ ${responseCode} == 401 ]]
then
/bin/echo "Token already invalid"
else
/bin/echo "An unknown error occurred invalidating the token"
fi
}
sendOSUpdateMDMCommand(){
curl --request POST \
--url ${jamfProURL}/api/v1/macos-managed-software-updates/send-updates \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer ${token}" \
--data "
{
"deviceIds": [
"${compID}"
],
"maxDeferrals": ${maxDeferrals},
"version": "${version}",
"skipVersionVerification": "${skipVersionVerification}",
"applyMajorUpdate": "${applyMajorUpdate}",
"forceRestart": "${forceRestart}",
"updateAction": "${updateAction}"
}
"
}
#
##################################################
# Script Work
#
#
# Calling all functions
checkVariables
checkTokenExpiration
sendOSUpdateMDMCommand
invalidateToken
exit 0