When setting up software for deployment, it’s usually a good idea to first send it out to a small percentage of the Macs in your environment. That way, if there’s a problem that wasn’t caught in testing, the amount of cleanup required is also small. If that initial deployment works, the software can then be sent out to greater percentages of the Mac population until all of them are eventually covered by the deployment.
This can be a pain to track manually though. New Macs come in, older ones are retired and keeping all Macs covered can turn into a significant investment of time. Fortunately, this is a task which can be automated and enable the Macs to assign themselves to deployment groups based on their machine UUID identifier. For more details, please see below the jump.
This method uses a Jamf Pro Extension Attribute, which is designed to calculate and set a numerical identifier for individual Macs based on the Mac’s machine UUID. This numerical identifier in turn is designed to be used to determine deployment groups.
Once identified, the value will be written to a plist file located in /Library/Preferences. By default, this file is named as follows:
/Library/Preferences/com.companyname.deploymentgroup.plist
You can change the companyname part by setting a different value for the organizationName variable in the Extension Attribute.
If the plist file is present in /Library/Preferences, the Extension Attribute will read the correct value from the plist file.
If the plist file is not present in /Library/Preferences, the Extension Attribute will calculate the correct value and store in the plist as the value of the deploymentGroupAssignmentValue key.
By default, this Extension Attribute is designed to assign Macs to seven deployment groups, with the following percentage of Macs assigned to each group.
Deployment Group | Percentage of Macs | |
---|---|---|
1 | 1 | |
2 | 5 | |
3 | 10 | |
4 | 20 | |
5 | 20 | |
6 | 20 | |
7 | 24 |
When all is working correctly, the Extension Attribute will display one of the following values for each Mac:
When not working properly, the Extension Attribute will display the following value:
The Extension Attribute’s values can then be used as Jamf Pro smart group criteria to create smart groups for software deployment.
This script is available below and also from GitHub at the following location:
#!/bin/bash | |
# This Jamf Pro Extension Attribute is designed to calculate and set a | |
# numerical identifier for individual Macs based on the Mac's machine UUID. | |
# This numerical identifier in turn is designed to be used to determine deployment | |
# groups. | |
# | |
# By default, this script is designed to set up and assign Macs to seven | |
# deployment groups, with the following percentage of Macs assigned to | |
# each group. | |
# | |
# Group % of Macs | |
# ————————- | |
# 1 1 | |
# 2 5 | |
# 3 10 | |
# 4 20 | |
# 5 20 | |
# 6 20 | |
# 7 24 | |
# | |
# Put in the name of your company, school, or institution. | |
# Must all be one word without spaces | |
# | |
# Examples: | |
# | |
# MyGreatCompany | |
# TheNewSchool | |
# BankofGreaterNewtown | |
# MikesSurfShop | |
organizationName="companyname" | |
# Do not edit variables below this line | |
deploymentGroupFile="/Library/Preferences/com.${organizationName}.deploymentgroup.plist" | |
exitCode=0 | |
log() { | |
local errorMsg="$1" | |
echo "$errorMsg" | |
/usr/bin/logger "$errorMsg" | |
} | |
deploymentGroupAssignment() { | |
deploymentGroup=7 | |
# Get the machine's uuid | |
machineUUID=$(/usr/sbin/ioreg -rd1 -c IOPlatformExpertDevice | /usr/bin/awk '/IOPlatformUUID/ { gsub(/"/,"",$3); print $3; }') | |
# If the UUID is available, generate a hash of the UUID | |
# then use that hash to assign an index number. | |
if [[ -n "$machineUUID" ]]; then | |
uuidHash=$(echo "$machineUUID" | /usr/bin/shasum -a 512 | /usr/bin/sed 's/[^0-9]*//g') | |
indexNumber=$(echo "${uuidHash:0:12}" | /usr/bin/awk '{ print $1 % 100 }') | |
if [[ -n "$indexNumber" ]]; then | |
# Once the index number is assigned, match the index number | |
# to a deployment group's numerical identifier. | |
case "$indexNumber" in | |
1) deploymentGroup=1 | |
;; | |
2|3|4|5|6) deploymentGroup=2 | |
;; | |
7|8|9|10|11|12|13|14|15|16) deploymentGroup=3 | |
;; | |
17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|32|33|34|35|36) deploymentGroup=4 | |
;; | |
37|38|39|40|41|42|43|44|45|46|47|48|49|50|51|52|53|54|55|56) deploymentGroup=5 | |
;; | |
57|58|59|60|61|62|63|64|65|66|67|68|69|70|71|72|73|74|75|76) deploymentGroup=6 | |
;; | |
*) deploymentGroup=7 | |
;; | |
esac | |
fi | |
else | |
log "ERROR! Unable to get machine's machine UUID" | |
exitCode=1 | |
fi | |
} | |
reportExtensionAttributeValue() { | |
deploymentGroupAssignmentCheck=$(/usr/bin/defaults read ${deploymentGroupFile} deploymentGroupAssignmentValue) | |
# The extension attribute should have a numeric value greater than zero. | |
# If the value is blank or a non-number, the following value is reported: | |
# | |
# 0 | |
# | |
# The 0 value indicates that there was a problem determining the deployment group. | |
if [[ "$deploymentGroupAssignmentCheck" =~ ^[0-9]+$ ]]; then | |
echo "<result>$deploymentGroupAssignmentCheck</result>" | |
else | |
echo "<result>0</result>" | |
fi | |
} | |
# Check to see if there's an existing plist file in /Library/Preferences which has the | |
# deployment group's numerical identifier assigned as an integer value to the plist file's | |
# deploymentGroupAssignmentValue key. | |
# | |
# If there is not a plist file, or there is not a deploymentGroupAssignmentValue key with a numerical | |
# value inside the plist file, the extension attribute generates the deployment group's numerical identifier. | |
# Once the deployment group's numerical identifier is generated, the identifier is stored as an integer value | |
# to the plist file's deploymentGroupAssignmentValue key. | |
if [[ -r ${deploymentGroupFile} ]]; then | |
reportExtensionAttributeValue | |
else | |
/usr/bin/defaults delete ${deploymentGroupFile} | |
deploymentGroupAssignment | |
/usr/bin/defaults write ${deploymentGroupFile} deploymentGroupAssignmentValue -int "$deploymentGroup" | |
reportExtensionAttributeValue | |
fi | |
exit $exitCode |