├── .gitignore ├── LICENSE ├── README.md ├── Scripts └── munki_enroll.sh ├── manifests ├── desktop_template └── laptop_template └── munki-enroll └── enroll.php /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2012 Cody Eding 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Munki Serial Enroll 2 | 3 | A set of scripts to automatically enroll clients in Munki, allowing for a very flexible manifest structure. 4 | 5 | ## Essential reading 6 | Before you even think about using Munki Serial Enroll, Munki Enroll, or anything like these projects, please read [An opinionated guide to Munki manifests](https://groob.io/posts/manifest-guide/) and [Another opinionated guide to Munki manifests](http://technology.siprep.org/another-opinionated-guide-to-munki-manifests/) first. 7 | 8 | ## Why Munki Serial Enroll? 9 | 10 | Using serial number manifests with human-readable display names and included group manifests allows for maximum flexibility. You can deploy software to a single machine or a group of machines. 11 | 12 | ### Wait, Doesn't Munki Do This Already? 13 | 14 | Munki can target systems based on hostnames or serial numbers. However, each manifest must be created by hand. Munki Serial Enroll allows us to create specific manifests automatically, and to allow them to contain a more generic manifest for large-scale software management. 15 | 16 | ## How does this differ from regular Munki Enroll? 17 | It has a few logistical tweaks for my organization that others may find immediately helpful or may find ideas in that they can tweak for their own organizations, but it's also different in approach. 18 | 19 | The original Munki Enroll creates individual manifests based on hostname and writes the hostname back as a ClientIdentifier on the client itself. Munki Serial Enroll goes based off of serial number, copies a template manifest (instead of creating one from scratch), and actually deletes the ClientIdentifier entirely. 20 | 21 | ## Server Configuration 22 | 23 | Munki Serial Enroll requires PHP to be working on the webserver hosting your Munki repository. 24 | 25 | Copy the **munki-enroll** folder to the root of your Munki repository (the same directory as pkgs, pkginfo, manifests and catalogs). 26 | 27 | Also copy the **desktop_template** and **laptop_template** files to your manifests folder and modify them appropriately. Leave in the 28 | ``` 29 | display_name 30 | DISPLAYNAMETOREPLACE 31 | ``` 32 | bit, though, because that's what gets replaced later after the template is copied. 33 | 34 | Make sure the Apache or other _www user has write access to the manifests folder. 35 | 36 | That's it on the server side! Be sure to make note of the full URL path to the enroll.php file. 37 | 38 | ## Client Configuration 39 | 40 | On the client side, tweak (for your organization) the two user-defined variables and run the munki_enroll.sh script, which will then communicate with the server about what manifest to create. 41 | 42 | The included munki_enroll.sh script can be executed in any number of ways (Terminal, ARD, DeployStudio workflow, LaunchAgent, etc.). 43 | 44 | ## What if this workflow doesn't fit my organization's? 45 | 46 | It actually very likely _won't_ fit your organizations. Every organization has its own workflow. Vanilla Munki Serial Enroll assumes https with basic authentication. You might be using SSL client certificates. It also assumes you have different manifest display names in desktops than you do in laptops. All your display names may follow the same pattern, or you may differentiate on MacBook Airs vs. MacBook Pros. It's really impossible to write an enrollment script that will exactly match every organization's needs, even if some arguments were added in. I don't know what your server address is. I don't know what types of things you want to put in the display name (maybe you don't want a specific user or the name of the computer—maybe you want something else entirely). 47 | 48 | The idea isn't that you just use this set of scripts out of the box. The idea is more "This has been helpful to me and my organization, and it may be helpful to you and your organization, too. The workflows in here may give you ideas of how you want to create your own workflows." Chances are, if you're a Mac admin using Munki, you have at least a little bit of scripting chops and can tweak these scripts to suit your organization's needs. 49 | 50 | ## Acknowledgements 51 | I've done a hefty bit of work on this, but a lot of credit for this concept must go to [Cody Eding](https://github.com/edingc), the creator of Munki Enroll, which I forked this from. 52 | 53 | ## License 54 | 55 | Munki Serial Enroll is published under the [MIT License](http://www.opensource.org/licenses/mit-license.php). 56 | -------------------------------------------------------------------------------- /Scripts/munki_enroll.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ##### Tweak on the original Munki-Enroll 4 | ##### This has different logic based on whether the computer is a desktop or a laptop 5 | ##### If it's a laptop, the script grabs the user's full name 6 | ##### If it's a desktop, the script just grabs the computer's name 7 | ##### This version of the script also assumes you have an https-enabled Munki server with basic authentication 8 | ##### Change SUBMITURL's variable value to your actual URL 9 | ##### Also change YOURLOCALADMINACCOUNT if you have one 10 | 11 | ####################### 12 | ## User-set variables 13 | # Change this URL to the location fo your Munki Enroll install 14 | SUBMITURL="https://your.companyname.com/path/to/enroll.php" 15 | # Change this to a local admin account you have if you have one 16 | ADMINACCOUNT="YOURLOCALADMINACCOUNT" 17 | ####################### 18 | 19 | # Make sure there is an active Internet connection 20 | SHORTURL=$(/bin/echo "$SUBMITURL" | /usr/bin/awk -F/ '{print $3}') 21 | PINGTEST=$(/sbin/ping -o -t 4 "$SHORTURL" | /usr/bin/grep "64 bytes") 22 | 23 | if [ ! -z "$PINGTEST" ]; then 24 | 25 | # Always get the serial number 26 | SERIAL=$(/usr/sbin/system_profiler SPHardwareDataType | /usr/bin/awk '/Serial Number/ { print $4; }') 27 | 28 | # Determine if it's a laptop or a desktop 29 | LAPTOPMODEL=$(/usr/sbin/system_profiler SPHardwareDataType | /usr/bin/grep "Model Identifier" | /usr/bin/grep "Book" | /usr/bin/awk -F ": " '{print $2}') 30 | 31 | # If it's a desktop... 32 | if [ -z "$LAPTOPMODEL" ]; then 33 | 34 | # Make the manifest template desktop 35 | TEMPLATE="desktop" 36 | 37 | # Make the "display name" into the actual computer name 38 | DISPLAYNAME=$(/usr/sbin/scutil --get ComputerName | /usr/bin/sed 's/ /-/g') 39 | 40 | # If it's a laptop... 41 | else 42 | 43 | # Make the manifest template laptop 44 | TEMPLATE="laptop" 45 | 46 | # Get the primary user 47 | PRIMARYUSER='' 48 | # This is a little imprecise, because it's basically going by process of elimination, but that will pretty much work for the setup we have 49 | /usr/bin/cd /Users 50 | for u in *; do 51 | if [ "$u" != "Guest" ] && [ "$u" != "Shared" ] && [ "$u" != "root" ] && [ "$u" != "$ADMINACCOUNT" ]; then 52 | PRIMARYUSER="$u" 53 | fi 54 | done 55 | 56 | if [ "$PRIMARYUSER" != "" ]; then 57 | 58 | # Add real name (not just username) of user 59 | DISPLAYNAME=$(/usr/bin/dscl . -read /Users/"$PRIMARYUSER" dsAttrTypeStandard:RealName | /usr/bin/sed 's/RealName://g' | /usr/bin/tr '\n' ' ' | /usr/bin/sed 's/^ *//;s/ *$//' | /usr/bin/sed 's/ /%20/g') 60 | # Add laptop model 61 | DISPLAYNAME+="%20($LAPTOPMODEL)" 62 | 63 | else 64 | 65 | DISPLAYNAME="Undefined%20-%20Fix%20Later" 66 | fi 67 | 68 | # End checking for desktop v. laptop 69 | fi 70 | 71 | # Get the authorization information 72 | AUTH=$( /usr/bin/defaults read /var/root/Library/Preferences/ManagedInstalls.plist AdditionalHttpHeaders | /usr/bin/awk -F 'Basic ' '{print $2}' | /usr/bin/sed 's/.$//' | /usr/bin/base64 --decode ) 73 | 74 | # Send information to the server to make the manifest 75 | /usr/bin/curl --max-time 5 --silent --get \ 76 | -d displayname="$DISPLAYNAME" \ 77 | -d serial="$SERIAL" \ 78 | -d template="$TEMPLATE" \ 79 | -u "$AUTH" "$SUBMITURL" 80 | # If not basic authentication, then just "$SUBMITURL" for the last line 81 | 82 | # Delete the ClientIdentifier, since we'll be using the serial number 83 | function deleteClientIdentifier { 84 | clientIdentifier=$(/usr/bin/defaults read "$1" | /usr/bin/grep "ClientIdentifier") 85 | if [ ! -z "$clientIdentifier" ]; then 86 | /usr/bin/defaults delete "$1" ClientIdentifier 87 | fi 88 | } 89 | 90 | deleteClientIdentifier "/Library/Preferences/ManagedInstalls" 91 | deleteClientIdentifier "/var/root/Library/Preferences/ManagedInstalls" 92 | 93 | else 94 | # No good connection to the server 95 | exit 1 96 | fi 97 | -------------------------------------------------------------------------------- /manifests/desktop_template: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | catalogs 6 | 7 | NAMEOFCATALOG 8 | 9 | display_name 10 | DISPLAYNAMETOREPLACE 11 | included_manifests 12 | 13 | INCLUDEDMANIFEST 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /manifests/laptop_template: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | catalogs 6 | 7 | NAMEOFCATALOG 8 | 9 | display_name 10 | DISPLAYNAMETOREPLACE 11 | included_manifests 12 | 13 | INCLUDEDMANIFEST 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /munki-enroll/enroll.php: -------------------------------------------------------------------------------- 1 | 68 | --------------------------------------------------------------------------------