Last active
June 8, 2019 21:20
-
-
Save talkingmoose/520c79d8d0f9bc49c9e07ca43122225c to your computer and use it in GitHub Desktop.
Creates Moble Device Configuration Profiles in Jamf Pro to pair one iOS device with the Apple TV Remote app to one Apple TV. Useful for hospital or school environments to simplify the device list when browsing and increase security by enforcing which devices can communicate.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| <<ABOUT_THIS_SCRIPT | |
| ----------------------------------------------------------------------- | |
| Written by:William Smith | |
| Professional Services Engineer | |
| Jamf | |
| bill@talkingmoose.net | |
| https://gist.github.com/talkingmoose/520c79d8d0f9bc49c9e07ca43122225c | |
| Originally posted: June 7, 2019 | |
| Purpose: Reads a CSV file for mass creation of Moble Device | |
| Configuration Profiles in Jamf Pro to pair one iPad running Apple | |
| TV Remote app to one Apple TV. Useful for hospital or school | |
| environments with multiple devices to reduce the device list | |
| when browsing in the same area and increase security by not | |
| allowing devices in one area to access devices in another area. | |
| Instructions: First, create a CSV file with Unix line-feed (LF) | |
| endings (use a plain text editor such as | |
| BBEdit from https://barebones.com) and three columns of | |
| information: | |
| room number,Apple TV name,iPad name | |
| Then, edit the script customizations below and run the script. | |
| This script creates a log file in the same location as the script. | |
| Possible HTTP result codes: | |
| 200 Request successful | |
| 201 Request to create or update object successful | |
| 400 Bad request | |
| 401 Authentication failed | |
| 403 Invalid permissions | |
| 404 Object/resource not found | |
| 409 Conflict | |
| 500 Internal server error | |
| Except where otherwise noted, this work is licensed under | |
| http://creativecommons.org/licenses/by/4.0/ | |
| "If you have built castles in the air, your work need not be lost; | |
| that is where they should be. Now put the foundations under them." | |
| ----------------------------------------------------------------------- | |
| ABOUT_THIS_SCRIPT | |
| <<INFO | |
| ----------------------------------------------------------------------- | |
| Script customizations | |
| ----------------------------------------------------------------------- | |
| INFO | |
| # Jamf Pro URL and credentials | |
| URL="https://jamfpro.talkingmoose.net:8443" | |
| userName="api-editor" | |
| password="P@55w0rd" | |
| # organization name that appears in the configuration profile | |
| organizationName="Talking Moose Industries" | |
| # path to the CSV file | |
| CSVFilePath="/Users/talkingmoose/Desktop/OneToOneConfigs.csv" | |
| # Jamf Pro site | |
| siteName="None" | |
| # Jamf Pro category | |
| category="Security" | |
| <<INFO | |
| ----------------------------------------------------------------------- | |
| File locations | |
| ----------------------------------------------------------------------- | |
| INFO | |
| # path to this script | |
| currentDirectory=$( /usr/bin/dirname "$0" ) | |
| # name of this script | |
| currentScript=$( /usr/bin/basename -s .sh "$0" ) | |
| # create log file in same directory as script | |
| logFile="$currentDirectory/$currentScript - $( /bin/date '+%y-%m-%d' ).log" | |
| <<INFO | |
| ----------------------------------------------------------------------- | |
| Functions | |
| ----------------------------------------------------------------------- | |
| INFO | |
| function logresult() { | |
| if [ $? = 0 ] ; then | |
| /bin/date "+%Y-%m-%d %H:%M:%S $1" >> "$logFile" | |
| else | |
| /bin/date "+%Y-%m-%d %H:%M:%S $2" >> "$logFile" | |
| fi | |
| } | |
| <<INFO | |
| ----------------------------------------------------------------------- | |
| Start the script | |
| ----------------------------------------------------------------------- | |
| INFO | |
| # read the CSV file | |
| assignmentsList=$( /bin/cat "$CSVFilePath" ) | |
| # process each line in the CSV file | |
| while IFS= read aLine | |
| do | |
| # read room number from assignments list | |
| roomNumber=$( /usr/bin/awk -F ',' '{ print $1 }' <<< $aLine ) | |
| logresult "Room number: $roomNumber." "Failed retrieving room number." | |
| # get MAC address of Apple TV by name | |
| TVDeviceName=$( /usr/bin/awk -F ',' '{ print $2 }' <<< $aLine ) | |
| logresult "Apple TV name: $TVDeviceName." "Failed retrieving Apple TV name." | |
| # create a URL encoded version of the device name | |
| TVDeviceNameEncoded=$( /usr/bin/sed 's/ /%20/g' <<< $TVDeviceName ) | |
| logresult "URL encoding Apple TV name: $TVDeviceNameEncoded." "Failed URL encoding Apple TV name." | |
| # read the device in Jamf Pro by name and return its MAC address for the profile | |
| TVDeviceID=$( /usr/bin/curl -s "$URL/JSSResource/mobiledevices/name/$TVDeviceNameEncoded" \ | |
| --user "$userName":"$password" \ | |
| --header "Accept: text/xml" \ | |
| --request GET \ | |
| | /usr/bin/xpath '/mobile_device/general/wifi_mac_address/text()' ) | |
| logresult "MAC address for Apple TV '$TVDeviceName': $TVDeviceID." "Failed retrieving MAC address for Apple TV $TVDeviceName." | |
| # get MAC address of iPad by name | |
| remoteDeviceName=$( /usr/bin/awk -F ',' '{ print $3 }' <<< $aLine ) | |
| logresult "iOS device name: $remoteDeviceName." "Failed retrieving iOS device name." | |
| # create a URL encoded version of the device name | |
| remoteDeviceNameEncoded=$( /usr/bin/sed 's/ /%20/g' <<< $remoteDeviceName ) | |
| logresult "URL encoding iOS device name: $remoteDeviceNameEncoded." "Failed URL encoding iOS device name." | |
| # read the device in Jamf Pro by name and return its MAC address for the profile | |
| remoteDeviceID=$( /usr/bin/curl -s "$URL/JSSResource/mobiledevices/name/$remoteDeviceNameEncoded" \ | |
| --user "$userName":"$password" \ | |
| --header "Accept: text/xml" \ | |
| --request GET \ | |
| | /usr/bin/xpath '/mobile_device/general/wifi_mac_address/text()' ) | |
| logresult "MAC address for iOS device '$remoteDeviceName': $remoteDeviceID." "Failed retrieving MAC address for iOS device $remoteDeviceName." | |
| # generate payload UUIDs | |
| payloadUUID1=$( /usr/bin/uuidgen ) | |
| logresult "Generating configuration profile UUID: $payloadUUID1." "Failed generating configuration profile UUID." | |
| payloadUUID2=$( /usr/bin/uuidgen ) | |
| logresult "Generating payload UUID: $payloadUUID2." "Failed generating payload UUID." | |
| # create the XML for the configuration profile | |
| profileXML="<configuration_profile> | |
| <general> | |
| <name>Apple TV Remote Patient - $roomNumber</name> | |
| <description/> | |
| <site> | |
| <name>$siteName</name> | |
| </site> | |
| <category> | |
| <name>$category</name> | |
| </category> | |
| <uuid>$payloadUUID1</uuid> | |
| <deployment_method>Install Automatically</deployment_method> | |
| <redeploy_on_update>Newly Assigned</redeploy_on_update> | |
| <redeploy_days_before_certificate_expires>0</redeploy_days_before_certificate_expires> | |
| <payloads><?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"><plist version=\"1\"><dict><key>PayloadUUID</key><string>$payloadUUID1</string><key>PayloadType</key><string>Configuration</string><key>PayloadOrganization</key><string>$organizationName</string><key>PayloadIdentifier</key><string>$payloadUUID1</string><key>PayloadDisplayName</key><string>Apple TV Remote Patient - $roomNumber</string><key>PayloadDescription</key><string/><key>PayloadVersion</key><integer>1</integer><key>PayloadEnabled</key><true/><key>PayloadRemovalDisallowed</key><true/><key>PayloadContent</key><array><dict><key>PayloadUUID</key><string>$payloadUUID2</string><key>PayloadType</key><string>com.apple.tvremote</string><key>PayloadOrganization</key><string>$organizationName</string><key>PayloadIdentifier</key><string>$payloadUUID2</string><key>PayloadDisplayName</key><string>com.apple.tvremote</string><key>PayloadDescription</key><string/><key>PayloadVersion</key><integer>1</integer><key>PayloadEnabled</key><true/><key>AllowedRemotes</key><array><dict><key>RemoteDeviceID</key><string>$remoteDeviceID</string></dict></array><key>AllowedTVs</key><array><dict><key>TVDeviceID</key><string>$TVDeviceID</string></dict></array></dict></array></dict></plist></payloads> | |
| </general> | |
| <scope> | |
| <all_mobile_devices>false</all_mobile_devices> | |
| <all_jss_users>false</all_jss_users> | |
| <mobile_devices> | |
| <mobile_device> | |
| <name>$TVDeviceName</name> | |
| </mobile_device> | |
| <mobile_device> | |
| <name>$remoteDeviceName</name> | |
| </mobile_device> | |
| </mobile_devices> | |
| </scope> | |
| </configuration_profile>" | |
| logresult "Generating profile XML." "Failed generating profile XML." | |
| # flatten the XML for the configuration profile to upload to Jamf Pro | |
| flatXML=$( /usr/bin/xmllint --noblanks - <<< "$profileXML" ) | |
| logresult "Flattening profile XML for upload." "Failed flattening profile XML for upload." | |
| # upload and create configuration profile | |
| result=$( /usr/bin/curl -s "$URL/JSSResource/mobiledeviceconfigurationprofiles/id/0" \ | |
| --write-out "%{http_code}" \ | |
| --user "$userName":"$password" \ | |
| --header "Content-Type: text/xml" \ | |
| --request POST \ | |
| --data "$flatXML" ) | |
| # evaluate HTTP status code | |
| resultStatus=${result: -3} | |
| [[ $resultStatus = 201 ]] # 201 is successful | |
| logresult "Successfully created configuration profile 'Apple TV Remote Patient - $roomNumber'." "Failed to create configuration profile 'Apple TV Remote Patient - $roomNumber'. HTTP error code: $resultStatus." | |
| done <<< "$assignmentsList" | |
| exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment