-
Notifications
You must be signed in to change notification settings - Fork 8
/
installPKGfromDMG.sh
383 lines (339 loc) · 15.1 KB
/
installPKGfromDMG.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
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
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
#!/bin/sh
####################################################################################################
#
# Copyright (c) 2011, JAMF Software, LLC. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the JAMF Software, LLC nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY JAMF SOFTWARE, LLC "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL JAMF SOFTWARE, LLC BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#####################################################################################################
#
# SUPPORT FOR THIS PROGRAM
#
# This program is distributed "as is" by JAMF Software, LLC's Resource Kit team. For more
# information or support for the Resource Kit, please utilize the following resources:
#
# http://list.jamfsoftware.com/mailman/listinfo/resourcekit
#
# http://www.jamfsoftware.com/support/resource-kit
#
# Please reference our SLA for information regarding support of this application:
#
# http://www.jamfsoftware.com/support/resource-kit-sla
#
#####################################################################################################
#
# ABOUT THIS PROGRAM
#
# NAME
# installPKGfromDMG.sh -- Install a PKG wrapped inside a DMG
#
# SYNOPSIS
# sudo installPKGfromDMG.sh
#
# DESCRIPTION
# This script will mount a DMG and install a PKG file wrapped inside. The script assumes that
# the DMG has been previously cached to the machine to:
#
# /Library/Application Support/JAMF/Waiting Room/
#
# This is the default location that a package will be cached to when selecting the "Cache"
# option within a policy or Casper Remote.
#
# To use this script, please follow the following workflow:
#
# Step 1: Wrap a PKG inside a DMG
# 1. Open Disk Utility.
# 2. Navigate to File > New > Disk Image from Folder.
# 3. Select the PKG and click the Image button.
# 4. Name the package after the original PKG.
# 5. Choose a location for the package and then click Save.
#
# Step 2: Upload the DMG and installPKGfromDMG.sh script to Casper Admin:
# 1. Open Casper Admin and authenticate.
# 2. Drag the DMG you created in the previous procedure to the Package pane in Casper Admin.
# 3. Drag the installPKGfromDMG.sh script to the Package pane in Casper Admin.
# 4. Save your changes and quit the application.
#
# Step 3: Create a policy to install the DMG:
# 1. Log in to the JSS with a web browser.
# 2. Click the Management tab.
# 3. Click the Policies link.
# 4. Click the Create Policy button.
# 5. Select the Create policy manually option and click Continue.
# 6. Configure the options on the General and Scope panes as needed.
# 7. Click the Packages button, and then click the Add Package link.
# 8. Across from DMG, choose “Cache” from the Action pop-up menu and then click the
# "Add Packages" button.
# 9. Click the Scripts button, and then click the Add Script link.
# 10. Across from the installPKGfromDMG.sh script, choose “Run After” from the Action pop-up menu.
# 11. Enter the name of the original DMG in the Parameter 4 field.
# 12. Click Save.
#
####################################################################################################
#
# HISTORY
#
# Version: 1.0
#
# - Created by Nick Amundsen on July 22, 2011
#
# Version: 1.1
#
# - Updated by Dr. Emily Kausalik (May 1, 2017) to include the following modifications
# * use "which jamf" to determine jamf version in line 127
# * call jamf variable rather than specific path in line 200
#
# Version: 1.2
# - Updated by Joe Selway (Oct 7, 2019) to include
# * the optional parameters added by Blake Suggett on October 24, 2018.
# > https://www.jamf.com/jamf-nation/third-party-products/files/1008/installpkgfromdmg-updated-with-additional-optional-parameters
# * quoting to handle spaces in .pkg name
#
####################################################################################################
#
# DEFINE VARIABLES & READ IN PARAMETERS
#
#####################################################################################################
#
# HARDCODED VALUES SET HERE
#
# Variables set by Casper - To manually override, remove the comment for the given variable
# targetDrive="" # Casper will pass this parameter as "Target Drive" if left commented out
# computerName="" # Casper will pass this parameter as "Computer Name" if left commented out
# userName="" # Casper will pass this parameter as "User Name" if left commented out. Usernames
# can only be passed if the script is triggered at login, logout, or by Self Service
# Variables used for logging
logFile="/private/var/log/installPKGfromDMG.log"
# Variables used by this script.
dmgName=""
forcesuccessflag="" # Optional
useinstallerapp="" # Optional
allowUntrusted="" # Optional
applyChoiceChangesXMLFile="" # Optional
# Figure out the correct jamf agent
jamf=$(which jamf)
# CHECK TO SEE IF A VALUE WERE PASSED IN FOR PARAMETERS AND ASSIGN THEM
if [ "$1" != "" ] && [ "$targetDrive" == "" ]; then
targetDrive="$1"
fi
if [ "$2" != "" ] && [ "$computerName" == "" ]; then
computerName="$2"
fi
if [ "$3" != "" ] && [ "$userName" == "" ]; then
userName="$3"
fi
if [ "$4" != "" ] && [ "$dmgName" == "" ]; then
dmgName="$4"
fi
if [ "$5" != "" ] && [ "$forcesuccessflag" == "" ]; then
forcesuccessflag="$5"
fi
if [ "$6" != "" ] && [ "$useinstallerapp" == "" ]; then
useinstallerapp="$6"
fi
if [ "$7" != "" ] && [ "$allowUntrusted" == "" ]; then
allowUntrusted="$7"
fi
if [ "$8" != "" ] && [ "$applyChoiceChangesXMLFile" == "" ]; then
applyChoiceChangesXMLFile="$8"
fi
####################################################################################################
#
# LOGGING FUNCTION
#
####################################################################################################
log () {
echo $1
echo $(date "+%Y-%m-%d %H:%M:%S: ") $1 >> $logFile
}
####################################################################################################
#
# VARIABLE VERIFICATION FUNCTION
#
####################################################################################################
verifyVariable () {
eval variableValue=\$$1
if [ "$variableValue" != "" ]; then
echo "Variable \"$1\" value is set to: $variableValue"
else
echo "Variable \"$1\" is blank. Please assign a value to the variable."
exit 1
fi
}
####################################################################################################
#
# SCRIPT CONTENTS - DO NOT MODIFY BELOW THIS LINE
#
####################################################################################################
# Verify Variables
verifyVariable dmgName
if [[ "$forcesuccessflag" = "YES" ]]; then
log "Variable \"forcesuccessflag\" to JSS explicitly declared...: $forcesuccessflag"
elif [[ "$forcesuccessflag" != "YES" ]]; then
log "Variable \"forcesuccessflag\" to JSS not explicitly declared, defaulting to No..."
fi
if [[ "$useinstallerapp" = "YES" ]]; then
log "Variable \"useinstallerapp\" explicitly declared...: $useinstallerapp"
elif [[ "$useinstallerapp" != "YES" ]]; then
log "Variable \"useinstallerapp\" not explicitly declared, defaulting to jamf binary"
fi
if [[ "$useinstallerapp" = "YES" && "$allowUntrusted" = "YES" ]]; then
log "Variable \"allowUntrusted\" explicitly declared...: $allowUntrusted"
elif [[ "$useinstallerapp" = "YES" && "$allowUntrusted" != "YES" ]]; then
log "Variable \"allowUntrusted\" not explicitly declared, expired certificates within the installer will prevent installation..."
fi
if [[ "$useinstallerapp" = "YES" && ! -z "$applyChoiceChangesXMLFile" ]]; then
log "Variable \"applyChoiceChangesXMLFile\" declared...: $applyChoiceChangesXMLFile"
elif [[ "$useinstallerapp" = "YES" && -z "$applyChoiceChangesXMLFile" ]]; then
log "Variable \"applyChoiceChangesXMLFile\" not declared, No answer file will be provided to the pkg..."
fi
# Attempt to remove any existing mounts
UnmountDMGNameOnly=`echo $dmgName | sed 's/.dmg*//'`
if [[ -d /Volumes/$UnmountDMGNameOnly ]] ; then
log "Found an exiting mounted DMG, unmounting..."
hdiutil detach /Volumes/$UnmountDMGNameOnly -force
fi
if [[ -f /Library/Application\ Support/JAMF/Waiting\ Room/$dmgName.shadow ]] ; then
log "Found an exiting shadow file, removing..."
rm -f /Library/Application\ Support/JAMF/Waiting\ Room/$dmgName.shadow
fi
# Mount the DMG
log "Mounting the DMG $dmgName..."
# mountResult
mountResult=`/usr/bin/hdiutil mount -private -noautoopen -noverify /Library/Application\ Support/JAMF/Waiting\ Room/$dmgName -shadow`
mountResultExitCode=($?)
# mountVolume
mountVolume=`echo "$mountResult" | grep Volumes | awk '{print $3}'`
mountVolumeExitCode=($?)
# mountDevice
mountDevice=`echo "$mountResult" | grep disk | head -1 | awk '{print $1}'`
mountDeviceExitCode=($?)
# Check DMG mount parameters are ok
if [[ $mountResultExitCode == 0 ]] && [[ $mountVolumeExitCode == 0 ]] && [[ $mountDeviceExitCode == 0 ]] ; then
log "DMG mounted successfully as volume $mountVolume on device $mountDevice."
elif [[ $mountResultExitCode != 0 ]] ; then
log "$mountResult"
log "There was an error mounting the DMG. mountResult hdiutil exit code: $mountResultExitCode"
exit 1
elif [[ $mountVolumeExitCode != 0 ]] ; then
log "$mountVolume"
log "There was an error mounting the DMG. mountVolume grep volume exit code: $mountVolumeExitCode"
exit 1
elif [[ $mountDeviceExitCode != 0 ]] ; then
log "$mountDevice"
log "There was an error mounting the DMG. mountDevice grep disk exit code: $mountDeviceExitCode"
exit 1
fi
# Find the PKG in the DMG
packageName=`ls $mountVolume | grep "pkg"`
if [[ -z "$packageName" ]] ; then
packageName=`ls $mountVolume | grep "mpkg"`
fi
# Install the PKG wrapped inside the DMG
if [[ "$useinstallerapp" = "YES" && "$allowUntrusted" = "YES" && ! -z "$applyChoiceChangesXMLFile" ]]; then
log "Installing Package $packageName from mount path $mountVolume..."
log "Script install string...: installer -pkg $mountVolume/"$packageName" -target / -allowUntrusted -applyChoiceChangesXML $mountVolume/$applyChoiceChangesXMLFile"
installer -pkg $mountVolume/"$packageName" -target / -allowUntrusted -applyChoiceChangesXML $mountVolume/$applyChoiceChangesXMLFile
PKGExitCode=($?)
elif [[ "$useinstallerapp" = "YES" && "$allowUntrusted" = "YES" && -z "$applyChoiceChangesXMLFile" ]]; then
log "Installing Package $packageName from mount path $mountVolume..."
log "Script install string...: installer -pkg $mountVolume/"$packageName" -target / -allowUntrusted"
installer -pkg $mountVolume/"$packageName" -target / -allowUntrusted
PKGExitCode=($?)
elif [[ "$useinstallerapp" = "YES" && "$allowUntrusted" != "YES" && ! -z "$applyChoiceChangesXMLFile" ]]; then
log "Installing Package $packageName from mount path $mountVolume..."
log "Script install string...: installer -pkg $mountVolume/"$packageName" -target / -applyChoiceChangesXML $mountVolume/$applyChoiceChangesXMLFile"
installer -pkg $mountVolume/"$packageName" -target / -applyChoiceChangesXML $mountVolume/$applyChoiceChangesXMLFile
PKGExitCode=($?)
elif [[ "$useinstallerapp" = "YES" ]]; then
log "Installing Package $packageName from mount path $mountVolume..."
log "Script install string...: installer -pkg $mountVolume/"$packageName" -target /"
installer -pkg $mountVolume/"$packageName" -target /
PKGExitCode=($?)
elif [[ "$useinstallerapp" != "YES" ]]; then
log "Installing Package $packageName from mount path $mountVolume..."
log "Script install string...: jamf install -path $mountVolume -package $packageName"
/usr/local/jamf/bin/jamf install -path $mountVolume -package $packageName
PKGExitCode=($?)
fi
if [ "$5" == "YES" ]; then
log "PKG exit code was: $PKGExitCode"
log "Exit code 0 was passed to JSS"
log "Successfully installed"
# Unmount the DMG
log "Unmounting disk $mountDevice..."
hdiutil detach "$mountDevice" -force
UnmountDMGExitCode=($?)
# If unmount failed attempt unmount using the volumes directory path
if [ $UnmountDMGExitCode != 0 ] ; then
log "Unable to unmount using native mountDevice... Attempting volumes unmount..."
hdiutil detach /Volumes/$UnmountDMGNameOnly -force
UnmountDMGExitCode=($?)
fi
if [ $UnmountDMGExitCode == 0 ] ; then
log "Successfully unmounted"
fi
# Delete the DMG
/bin/rm /Library/Application\ Support/JAMF/Waiting\ Room/$dmgName
exit 0
elif [ "$PKGExitCode" == 0 ]; then
log "PKG exit code was: $PKGExitCode"
log "Exit code $PKGExitCode was passed to JSS"
log "Successfully installed"
# Unmount the DMG
log "Unmounting disk $mountDevice..."
hdiutil detach "$mountDevice" -force
UnmountDMGExitCode=($?)
# If unmount failed attempt unmount using the volumes directory path
if [ $UnmountDMGExitCode != 0 ] ; then
log "Unable to unmount using native mountDevice... Attempting volumes unmount..."
hdiutil detach /Volumes/$UnmountDMGNameOnly -force
UnmountDMGExitCode=($?)
fi
if [ $UnmountDMGExitCode == 0 ] ; then
log "Successfully unmounted"
fi
# Delete the DMG
/bin/rm /Library/Application\ Support/JAMF/Waiting\ Room/$dmgName
exit 0
else
log "PKG exit code was...: $PKGExitCode"
log "Exit code $PKGExitCode was passed to JSS"
log "Failed installation"
# Unmount the DMG
log "Unmounting disk $mountDevice..."
hdiutil detach "$mountDevice" -force
UnmountDMGExitCode=($?)
# If unmount failed attempt unmount using the volumes directory path
if [ $UnmountDMGExitCode != 0 ] ; then
log "Unable to unmount using native mountDevice... Attempting volumes unmount..."
hdiutil detach /Volumes/$UnmountDMGNameOnly -force
UnmountDMGExitCode=($?)
fi
if [ $UnmountDMGExitCode == 0 ] ; then
log "Successfully unmounted"
fi
# Delete the DMG
/bin/rm /Library/Application\ Support/JAMF/Waiting\ Room/$dmgName
exit 1
fi