-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathMDMInstallAndDeploy.sh
More file actions
198 lines (166 loc) · 7.81 KB
/
MDMInstallAndDeploy.sh
File metadata and controls
198 lines (166 loc) · 7.81 KB
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
#!/bin/bash
#
# Complete script meant for running via MDM on device enrollment. This will download
# and install Dialog on the fly before opening Dialog. Tested with Mosyle MDM.
#
# The logging to /var/tmp/deploy.log is useful when getting started but
# arguably is not needed.
#
# The progress bar manipulation could use some improvement.
#
# Display a Dialog with a list of applications and indicate when they've been installed
# Useful when apps are deployed at random, perhaps without local logging.
# Applies to Mosyle App Catalog installs, VPP app installs, etc.
#
# Requires swiftDialog 1.11.2 or later https://github.com/bartreardon/swiftDialog/releases
# Original release of this script required swiftDialog v1.9.1 or later
#
# *** definable variables
# List of apps/installs to process
# Provide the display name as you prefer and the path to the app/file. ex: "Google Chrome,/Applications/Google Chrome.app"
# A comma separates the display name from the path. Do not use commas in your display name text.
# Tip: Check for something like print drivers using the pkg receipt, like "Konica-Minolta drivers,/var/db/receipts/jp.konicaminolta.print.package.C759.plist"
apps=(
"Google Chrome,/Applications/Google Chrome.app"
"Google Drive,/Applications/Google Drive.app"
"VLC,/Applications/VLC.app"
"zoom.us,/Applications/zoom.us.app"
)
dialogURL=$(curl --silent --fail "https://api.github.com/repos/bartreardon/swiftDialog/releases/latest" | awk -F '"' "/browser_download_url/ && /pkg\"/ { print \$4; exit }")
# Expected Team ID of the downloaded PKG
dialogExpectedTeamID="PWA5E9TQ59"
# Dialog display settings, change as desired
title="Installing Apps"
message="Please wait while we download and install apps"
# location of dialog and dialog command file
dialogApp="/usr/local/bin/dialog"
dialog_command_file="/var/tmp/dialog.log"
# *** end definable variables
# *** functions
function dialog_command(){
echo "$1"
echo "$1" >> $dialog_command_file
}
function finalise(){
dialog_command "overlayicon: SF=checkmark.circle.fill,palette=white,black,none,bgcolor=none"
dialog_command "progresstext: Install of apps complete"
dialog_command "progress: complete"
dialog_command "button1text: Done"
dialog_command "button1: enable"
exit 0
}
function appCheck(){
dialog_command "listitem: '$(echo "$app" | cut -d ',' -f1)': wait"
while [ ! -e "$(echo "$app" | cut -d ',' -f2)" ]
do
sleep 2
done
dialog_command "progresstext: Install of \"$(echo "$app" | cut -d ',' -f1)\" complete"
dialog_command "listitem: $(echo "$app" | cut -d ',' -f1): success"
progress_index=$(( progress_index + 1 ))
echo "at item number $progress_index"
}
function dialogCheck(){
if [ ! -e "/Library/Application Support/Dialog/Dialog.app" ]; then
echo "$(date "+%a %h %d %H:%M:%S"): Dialog not found. Installing." 2>&1 | tee -a /var/tmp/deploy.log
# Create temporary working directory
workDirectory=$( /usr/bin/basename "$0" )
tempDirectory=$( /usr/bin/mktemp -d "/private/tmp/$workDirectory.XXXXXX" )
echo "$(date "+%a %h %d %H:%M:%S"): Created working directory '$tempDirectory'" 2>&1 | tee -a /var/tmp/deploy.log
# Download the installer package
echo "$(date "+%a %h %d %H:%M:%S"): Downloading Dialog package" 2>&1 | tee -a /var/tmp/deploy.log
/usr/bin/curl --location --silent "$dialogURL" -o "$tempDirectory/Dialog.pkg"
# Verify the download
teamID=$(/usr/sbin/spctl -a -vv -t install "$tempDirectory/Dialog.pkg" 2>&1 | awk '/origin=/ {print $NF }' | tr -d '()')
echo "$(date "+%a %h %d %H:%M:%S"): Team ID for downloaded package: $teamID" 2>&1 | tee -a /var/tmp/deploy.log
# Install the package if Team ID validates
if [ "$dialogExpectedTeamID" = "$teamID" ] || [ "$dialogExpectedTeamID" = "" ]; then
echo "$(date "+%a %h %d %H:%M:%S"): Package verified. Installing package Dialog.pkg" 2>&1 | tee -a /var/tmp/deploy.log
/usr/sbin/installer -pkg "$tempDirectory/Dialog.pkg" -target /
exitCode=0
else
echo "$(date "+%a %h %d %H:%M:%S"): Package verification failed before package installation could start. Download link may be invalid. Aborting." 2>&1 | tee -a /var/tmp/deploy.log
displayDialog
exitCode=1
exit $exitCode
fi
# Remove the temporary working directory when done
echo "$(date "+%a %h %d %H:%M:%S"): Deleting working directory '$tempDirectory' and its contents" 2>&1 | tee -a /var/tmp/deploy.log
/bin/rm -Rf "$tempDirectory"
else echo "$(date "+%a %h %d %H:%M:%S"): Dialog already found. Proceeding..." 2>&1 | tee -a /var/tmp/deploy.log
fi
}
# If something goes wrong and Dialog isn't installed we want to notify the user using AppleScript and exit the script
# Line 117 must use tabs, do not replace with spaces
function displayDialog(){
message="A problem was encountered setting up this Mac. Please contact IT."
currentUser=$(scutil <<< "show State:/Users/ConsoleUser" | awk '/Name :/ { print $3 }')
if [[ "$currentUser" != "" ]]; then
currentUserID=$(id -u "$currentUser")
launchctl asuser "$currentUserID" /usr/bin/osascript <<-EndOfScript
button returned of ¬
(display dialog "$message" ¬
buttons {"OK"} ¬
default button "OK")
EndOfScript
fi
}
# *** end functions
# start
setupAssistantProcess=$(pgrep -l "Setup Assistant")
until [ "$setupAssistantProcess" = "" ]; do
echo "$(date "+%a %h %d %H:%M:%S"): Setup Assistant Still Running. PID $setupAssistantProcess." 2>&1 | tee -a /var/tmp/deploy.log
sleep 1
setupAssistantProcess=$(pgrep -l "Setup Assistant")
done
echo "$(date "+%a %h %d %H:%M:%S"): Out of Setup Assistant" 2>&1 | tee -a /var/tmp/deploy.log
echo "$(date "+%a %h %d %H:%M:%S"): Logged in user is $(scutil <<< "show State:/Users/ConsoleUser" | awk '/Name :/ { print $3 }')" 2>&1 | tee -a /var/tmp/deploy.log
finderProcess=$(pgrep -l "Finder")
until [ "$finderProcess" != "" ]; do
echo "$(date "+%a %h %d %H:%M:%S"): Finder process not found. Assuming device is at login screen. PID $finderProcess" 2>&1 | tee -a /var/tmp/deploy.log
sleep 1
finderProcess=$(pgrep -l "Finder")
done
echo "$(date "+%a %h %d %H:%M:%S"): Finder is running" 2>&1 | tee -a /var/tmp/deploy.log
echo "$(date "+%a %h %d %H:%M:%S"): Logged in user is $(scutil <<< "show State:/Users/ConsoleUser" | awk '/Name :/ { print $3 }')" 2>&1 | tee -a /var/tmp/deploy.log
dialogCheck
# set progress total to the number of apps in the list
progress_total=${#apps[@]}
# set icon based on whether computer is a desktop or laptop, we'll check to see if the computer has a battery
# We can't check model names anymore since Mac Studio, MacBook Air M2 and newer report their name as "Mac##,#"
if system_profiler SPPowerDataType | grep -q Battery; then
icon="SF=laptopcomputer"
else
icon="SF=desktopcomputer"
fi
echo "$(date "+%a %h %d %H:%M:%S"): Logged in user is $(scutil <<< "show State:/Users/ConsoleUser" | awk '/Name :/ { print $3 }')" 2>&1 | tee -a /var/tmp/deploy.log
dialogCMD="$dialogApp -p --title \"$title\" \
--message \"$message\" \
--icon \"$icon\" \
--overlayicon SF=arrow.down.circle.fill,palette=white,black,none,bgcolor=none \
--progress $progress_total \
--button1text \"Please Wait\" \
--button1disabled"
# create the list of apps
listitems=""
for app in "${apps[@]}"; do
listitems="$listitems --listitem '$(echo "$app" | cut -d ',' -f1)'"
done
# final command to execute
dialogCMD="$dialogCMD $listitems"
echo "$dialogCMD"
# Launch dialog and run it in the background sleep for a second to let thing initialise
echo "$(date "+%a %h %d %H:%M:%S"): About to launch Dialog." 2>&1 | tee -a /var/tmp/deploy.log
eval "$dialogCMD" &
sleep 2
progress_index=0
(for app in "${apps[@]}"; do
step_progress=$(( 1 + progress_index ))
dialog_command "progress: $step_progress"
appCheck &
done
wait)
# all done. close off processing and enable the "Done" button
echo "$(date "+%a %h %d %H:%M:%S"): Finalizing." 2>&1 | tee -a /var/tmp/deploy.log
finalise
echo "$(date "+%a %h %d %H:%M:%S"): Done." 2>&1 | tee -a /var/tmp/deploy.log