-
Notifications
You must be signed in to change notification settings - Fork 10
/
Install-Configuration-Profiles.sh
248 lines (200 loc) · 9.17 KB
/
Install-Configuration-Profiles.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
#!/bin/bash
## Script Name: Install-Configuration-Profiles.sh
## Author: Mike Morales
## Last Modified: 2017-July-04
## Last Change: Modified process to obtain Config Profile data. Now gets the profile as xml in one line instead of two.
## Purpose:
## This script will download and install a macOS Configuration Profile(s) that exists in your JSS, using the API
## Special Note: This script is designed to be used on macOS versions 10.10.x and up, when installing a User Level mobileconfig profile.
## It will fail to install User Level profiles on any older OS versions, but will work with System Level profiles.
##
## I have no desire or time to work on making the script able to install User Level profiles on older OSes,
## but feel free to work on it if this is something you should need yourself.
## How it works:
## 1. The supplied API credentials and JSS URL are used to obtain a Config Profile (or multiples) using the JSS ID(s) passed to the script.
## 2. If successful, the profile is curl'ed down. The 'payloads' section is extracted from the data, then converted into proper xml format.
## 3. The xml formed Config Profile is saved into /private/tmp/ as a .mobileconfig, using the JSS ID as the name for the file.
## 4. The PayloadScope is determined from the profile, so it knows if it's User Level or System Level.
## 5. The profiles command is then used to install the Configuration Profile to the local machine, at the appropriate level, if possible.
## 6. Finally, the local .mobileconfig file is removed from /private/tmp/ as part of a cleanup process.
## Begin defined variables ##
## Set the first part of the new UUID string
## (This would typically be something like "com.organization." but can be anything you want. Avoid spaces)
IDStringStart="com.org."
## API User Name (Hardcode here, or leave blank to obtain from $4)
apiUser=""
## API Password (Hardcode here, or leave blank to obtain from $5)
apiPass=""
## JSS URL (Hardcode here, or leave blank to obtain from $6, or from the local machine)
jssURL=""
## Configuration Profile JSS ID (Hardcode here or leave blank to obtain from $7)
ProfileJSSID=""
## Flag to rename the Jamf generated identifier to a human readable identifier, based on the name of the profile
## Can be set to variations of yes, true, no, false. See the case statement below for all possible recognizable strings
renameID=""
## End defined variables ##
## Do not edit below this line ##
## Check for variable assignments
if [[ -z "$apiUser" ]] && [[ ! -z "$4" ]]; then
apiUser="$4"
elif [[ ! -z "$apiUser" ]]; then
apiUser="$apiUser"
elif [[ -z "$apiUser" ]] && [[ -z "$4" ]]; then
echo "Error! The API Username was not passed to the script in parameter 4, or hardcoded into the script. Exiting"
exit 1
fi
if [[ -z "$apiPass" ]] && [[ ! -z "$5" ]]; then
apiPass="$5"
elif [[ ! -z "$apiPass" ]]; then
apiPass="$apiPass"
elif [[ -z "$apiPass" ]] && [[ -z "$5" ]]; then
echo "Error! The API Password was not passed to the script in parameter 5, or hardcoded into the script. Exiting"
exit 1
fi
if [[ -z "$jssURL" ]] && [[ ! -z "$6" ]]; then
jssURL="${6%/}"
elif [[ ! -z "$jssURL" ]]; then
jssURL="${jssURL%/}"
elif [[ -z "$jssURL" ]] && [[ -z "$6" ]]; then
## Try to get the JSS URL from the local machine
jssURL=$(defaults read /Library/Preferences/com.jamfsoftware.jamf.plist jss_url 2>/dev/null | sed 's|/$||')
if [ -z "$jssURL" ]; then
echo "Error! The JSS URL was not entered in the script, passed as parameter 6, or located on this machine. Exiting"
exit 1
fi
fi
if [[ -z "$renameID" ]] && [[ ! -z "$8" ]]; then
renameID="${8}"
elif [[ ! -z "$renameID" ]] && [[ -z "$8" ]]; then
renameID="$renameID"
elif [[ ! -z "$renameID" ]] && [[ ! -z "$8" ]]; then
## Parameter 7 was supplied, but the local flag within the script was also filled in.
## In this case, we override the local script flag with the one supplied in the parameter.
renameID="${8}"
fi
if [ "$renameID" ]; then
case "$renameID" in
Y|y|Yes|yes|YES)
renameFlag="true"
;;
N|n|No|no|NO)
renameFlag="false"
;;
"true"|TRUE|True)
renameFlag="true"
;;
"false"|FALSE|False)
renameFlag="false"
;;
*)
renameFlag="false"
echo "The renameID flag was set to an unrecognizable string. Please supply one of the following:
Y/Yes/True to enable, N/No/False to disable"
;;
esac
else
## If no flag was supplied at all, we assume no rename is desired. The Profiles original UUID will be used
renameFlag="false"
fi
## Function to download and install the Configuration Profile
function download_install_profile ()
{
## Pull the profile down in raw URL encoded format
echo "Obtaining Configuration Profile as xml…"
FormattedProfile=$(curl -H "Accept: text/xml" -sfku "${apiUser}:${apiPass}" "${jssURL}/JSSResource/osxconfigurationprofiles/id/${ID}" -X GET | xpath '/os_x_configuration_profile/general/payloads/text()' | perl -MHTML::Entities -pe 'decode_entities($_);' | xmllint --format -)
## Obtain the old/original UUID string from the profile xml, store in variable
echo "Obtaining the old ID string from the xml…"
IDStringOld=$(echo "$FormattedProfile" | awk -F'>|<' '/PayloadUUID/{getline; print $3; exit}')
echo "renameFlag was set to: ${renameFlag}…"
if [ "$renameFlag" == "true" ]; then
## Generate a string based on the DisplayName string from the profile xml
echo "Obtaining the display name string from the xml…"
DisplayName=$(echo "$FormattedProfile" | awk -F'>|<' '/PayloadDisplayName/{getline; print $3; exit}' | sed 's/ - /-/g;s/ /-/g')
## Make a new full UUID string
echo "Creating a new ID string…"
IDStringNew=$(echo "${IDStringStart}${DisplayName}" | awk '{print tolower}')
## Create a new profile and replace the old UUID string with the new one defined above
echo "Creating final .mobileconfig file…"
echo "$FormattedProfile" | sed "s/$IDStringOld/$IDStringNew/g" > "/tmp/${ID}.mobileconfig"
## Set the new Profile name string based on the above obtained information
profileName="$IDStringNew"
else
## Create a new profile using the original UUID string within the profile
echo "Creating final .mobileconfig file…"
echo "$FormattedProfile" > "/tmp/${ID}.mobileconfig"
## Set the profile name to the existing ID string
profileName="$IDStringOld"
fi
## Output the new profile xml (used only for testing purposes. Is left uncommented out here)
# echo "$new_formatted_profile"
## Determine the Payload Scope for the Profile.
## "User" indicates it should be installed as a user level profile. "System" indicates system level profile
scopeLevel=$(awk -F'>|<' '/PayloadScope/{getline; print $3}' "/tmp/${ID}.mobileconfig")
if [ "$scopeLevel" == "User" ]; then
echo "Profile has a User Level scope"
## Attempt to install the profile as the current user
loggedInUser=$(stat -f%Su /dev/console)
loggedInUID=$(id -u "$loggedInUser")
echo "Installing Configuration Profile as current user…"
/bin/launchctl asuser "$loggedInUID" sudo -iu "$loggedInUser" /usr/bin/profiles -I -F "/tmp/${ID}.mobileconfig"
## Capture the exit result of the profile install command
res=$?
elif [ "$scopeLevel" == "System" ]; then
echo "Profile has a System Level scope"
## Attempt to install profile as a System level profile (from root)
echo "Installing Configuration Profile…"
/usr/bin/profiles -I -F "/tmp/${ID}.mobileconfig"
## Capture the exit result of the profile install command
res=$?
elif [ "$scopeLevel" == "" ]; then
echo "Profile does not have a specific scope. We will install it as a System level profile"
## Attempt to install profile as a System level profile (from root)
echo "Installing Configuration Profile…"
/usr/bin/profiles -I -F "/tmp/${ID}.mobileconfig"
## Capture the exit result of the profile install command
res=$?
fi
## Check the result and print out a result to stdout
if [ "$res" == "0" ]; then
echo "Installation result: Successful"
echo "Configuration Profile \"${profileName}\" installed. Cleaning up…"
rm -f "/tmp/${ID}.mobileconfig"
else
echo "Installation result: Failed"
echo "Configuration Profile \"${profileName}\" installation failed. Cleaning up…"
rm -f "/tmp/${ID}.mobileconfig"
fi
}
## This function may get called if more than one JSS Configuration Profile ID was supplied.
## If so, this loop function is called to loop over the values and install any it can download.
function install_multi_profiles ()
{
## Place the values into an array
for i in "$ProfileJSSID"; do
idArr+=($i)
done
## Loop over the array to run the download_install_profile function for each array index
for i in "${idArr[@]}"; do
ID="$i"
download_install_profile
done
}
## First check to make sure we have a profile ID(s) passed to parameter 7, or hardcoded into the script
if [[ -z "$ProfileJSSID" ]] && [[ ! -z "$7" ]]; then
ProfileJSSID="$7"
elif [[ ! -z "$ProfileJSSID" ]]; then
ProfileJSSID="$ProfileJSSID"
elif [[ -z "$ProfileJSSID" ]] && [[ -z "$7" ]]; then
echo "Error! The Configuration Profile ID was not passed to the script in parameter 7, or hardcoded into the script. Exiting"
exit 1
fi
## Now check to see if the ProfileJSSID string contains multiple items
regex=" | "
if [[ $ProfileJSSID =~ $regex ]]; then
echo "Multiple IDs passed. Running in loop mode"
install_multi_profiles
else
echo "Single ID was passed. Running in single mode"
ID="$ProfileJSSID"
download_install_profile
fi