├── .gitignore ├── APNS Command Check ├── APNScleanup.sh └── README.md ├── Active Directory Migration └── ADAccountMigration.sh ├── Apple Software Update Script └── AppleSoftwareUpdateScript.sh ├── Apple Software Update Search ├── AppleSoftwareUpdateSearch_v2 ├── Archive │ └── AppleSoftwareUpdateScript_v1.sh └── README.md ├── AppleScript Prompt Template └── AppleScript_Prompt.sh ├── Bulk Lost Mode v2 ├── BulkLostMode-v2.py ├── DeviceList.csv └── README.md ├── Create Policy and Profile Scope Overview ├── CreateSummary.py ├── JamfPro_ConfigurationProfile_ScopeOverview-05122022.csv ├── JamfPro_ConfigurationProfile_ScopeOverview-06152022.csv ├── JamfPro_PolicyScope_Overview-05122022.csv ├── JamfPro_PolicyScope_Overview-06152022.csv └── README.md ├── Disable Smart Card Pairing ├── DisableSmartCardPairing.sh ├── EA_SmartCardPairing.sh └── README.md ├── Encrypt External Volume ├── EA_EncryptedVolumePassword.sh ├── EncryptExternalVolume.sh └── README.md ├── Filevault Setup Script ├── FilevaultSetup.sh └── README.md ├── Homebrew ├── Extension Attributes │ ├── Homebrew_EA.sh │ ├── README.md │ └── XcodeCLI_EA.sh ├── InstallHomebrew.sh ├── InstallHomebrewPackages.sh └── README.md ├── Install Python Packages ├── README.md └── installPythonPackages.py ├── LAPS for Mac ├── Display Local Admin Password - Self Service.sh ├── LAPSforMac.sh └── README.md ├── Microsoft Office Update Scripts ├── Office_2016_Updater.sh └── Office_2019-O365_Updater.sh ├── README.md ├── Remote Connection Project ├── README.md └── RemoteConnectionScript.sh ├── Rename Startup Volume ├── EA_StartupVolumeName.sh ├── README.md └── RenameStartupVolume.sh ├── Ruby Gems ├── InstallRubyGems.sh └── README.md ├── Scripting Tips and Examples ├── Temporary User Account Elevation ├── README.md ├── TempUserAccountElevation-NoSmartcard.sh └── TempUserAccountElevation.sh ├── macOS 10.14 Update Script └── macOS1014UpdateScript.sh ├── macOS 10.15 Update Script └── macOS1015Update.sh ├── macOS Health Check ├── README.md └── [Jamf Pro] Health Check Script.sh ├── macOS Installer Download Script ├── README.md └── macOSInstallerDownloadScript.sh └── macOS Update Ready Check ├── README.md └── macOSUpdatePrepScript.sh /.gitignore: -------------------------------------------------------------------------------- 1 | Bulk Lost Mode v2/DeviceList.csv 2 | Create Policy and Profile Scope Overview/.DS_Store 3 | .DS_Store 4 | 5 | -------------------------------------------------------------------------------- /APNS Command Check/APNScleanup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ################################################# 4 | # APNS Command Check 5 | # Joshua Harvey | February 2019 6 | # josh[at]macjeezy.com 7 | # GitHub - github.com/therealmacjeezy 8 | # JAMFnation - therealmacjeezy 9 | ################################################# 10 | 11 | # Database Name 12 | dbHost='' 13 | # Database Password 14 | dbPass='' 15 | # This array stores the names of your MySQL databases, if you only have one database for your setup, comment out the array on line 17 and uncomment the array on line 20 16 | # Array for Multiple Databases 17 | dbNames=( "" "" "" ) 18 | 19 | # Array for a Single Database 20 | #dbNames=( "" ) 21 | # Path for the script log 22 | logPath="/path/to/mdmcleanup.log" 23 | 24 | # Verify log exists and create if not 25 | if [[ ! -f "$logPath" ]]; then 26 | echo "No log found.. Creating log at $logPath" 27 | fi 28 | 29 | # Create log for start time and date 30 | echo "Starting APNS Check on `date`" >> $logPath 31 | echo "---" >> $logPath 32 | 33 | # Function to clear the failed MDM commands for APNS 34 | clearCommand() { 35 | # Variable to capture the number of failed APNS commands in the database. If you are running the database on the same computer as this script, you can remove the -h option below 36 | getNumber=$(mysql -u root -p$dbPass -h -Bse "use $dbName; select count(*) from mobile_device_management_commands where apns_result_status =\"Error\";") 37 | 38 | echo "[$dbName]: $getNumber found failed APNS Commands. Clearing now.." >> $logPath 39 | 40 | # This line will clear the failed APNS commands found. If you are running the database on the same computer as this script, you can remove the -h option below 41 | mysql -u root -p$dbPass -h -Bse "use $dbName; delete from mobile_device_management_commands where apns_result_status =\"Error\";" 42 | 43 | echo "[$dbName]: Cleared $getNumber failed APNS Commands." >> $logPath 44 | } 45 | 46 | # For loop to go through the database names stored in the dbNames array. It will check for any failed APNS commands and clear them if found 47 | for i in "${dbNames[@]}"; do 48 | dbName="$i" 49 | # If statement to check for any failed APNS commands. If you are running the database on the same computer as this script, you can remove the -h option below. 50 | if [[ `mysql -u root -p$dbPass -h -Bse "use $dbName; select count(*) from mobile_device_management_commands where apns_result_status =\"Error\";"` == "0" ]]; then 51 | echo "[$dbName]: No Failed APNS Commands found." >> $logPath 52 | else 53 | # Calls the function to clear the failed APNS commands 54 | clearCommand 55 | fi 56 | done 57 | 58 | echo "Goodbye" >> "$logPath" 59 | echo "---" >> "$logPath" 60 | 61 | exit 0 62 | -------------------------------------------------------------------------------- /APNS Command Check/README.md: -------------------------------------------------------------------------------- 1 | # APNS Command Check 2 | **Created: February 2019** 3 | 4 | The APNS Command Check script will check your MySQL database for any failed APNS Commands and clear them if found. 5 | 6 | ### Notes 7 | - This script was originally written for use with multiple databases, however it will also work for single databases. See the script comments for more details. 8 | - If your MySQL database is located on the computer that will be running this script, be sure to remove the -h option from all three mysql commands. See the script comments for more details. 9 | -------------------------------------------------------------------------------- /Active Directory Migration/ADAccountMigration.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ################################################# 4 | # AD Account Migration Script 5 | # Joshua Harvey | November 2018 6 | # Updated: December 2018 7 | # josh[at]macjeezy.com 8 | # GitHub - github.com/therealmacjeezy 9 | # JAMFnation - therealmacjeezy 10 | ################################################# 11 | 12 | # Variables for use later in the script 13 | currUser=$(scutil <<< "show State:/Users/ConsoleUser" | awk -F': ' '/[[:space:]]+Name[[:space:]]:/ { if ( $2 != "loginwindow" ) { print $2 }}') 14 | currUserUID=$(id -u "$currUser") 15 | checkBinding=$(/usr/bin/dscl localhost -list . | grep "Active Directory") 16 | 17 | removeAD(){ 18 | # This function force-unbinds the Mac from the existing Active Directory domain 19 | # and updates the search path settings to remove references to Active Directory 20 | 21 | searchPath=$(/usr/bin/dscl /Search -read . CSPSearchPath | grep Active\ Directory | sed 's/^ //') 22 | 23 | # Force unbind from Active Directory 24 | 25 | /usr/sbin/dsconfigad -remove -force -u none -p none 26 | 27 | # Deletes the Active Directory domain from the custom /Search 28 | # and /Search/Contacts paths 29 | 30 | /usr/bin/dscl /Search/Contacts -delete . CSPSearchPath "$searchPath" 31 | /usr/bin/dscl /Search -delete . CSPSearchPath "$searchPath" 32 | 33 | # Changes the /Search and /Search/Contacts path type from Custom to Automatic 34 | 35 | /usr/bin/dscl /Search -change . SearchPolicy dsAttrTypeStandard:CSPSearchPath dsAttrTypeStandard:NSPSearchPath 36 | /usr/bin/dscl /Search/Contacts -change . SearchPolicy dsAttrTypeStandard:CSPSearchPath dsAttrTypeStandard:NSPSearchPath 37 | } 38 | 39 | convertAccount() { 40 | # Preserving the account password by backing up the password hash 41 | shadowHash=$(/usr/bin/dscl -plist . -read /Users/"$i" AuthenticationAuthority | xmllint --xpath 'string(//string[contains(text(),"ShadowHash")])' -) 42 | 43 | # Remove account attributes that identify it as an Active Directory mobile account 44 | /usr/bin/dscl . -delete /users/"$i" cached_groups 45 | /usr/bin/dscl . -delete /users/"$i" cached_auth_policy 46 | /usr/bin/dscl . -delete /users/"$i" CopyTimestamp 47 | /usr/bin/dscl . -delete /users/"$i" SMBPrimaryGroupSID 48 | /usr/bin/dscl . -delete /users/"$i" OriginalAuthenticationAuthority 49 | /usr/bin/dscl . -delete /users/"$i" OriginalNodeName 50 | /usr/bin/dscl . -delete /users/"$i" AuthenticationAuthority 51 | /usr/bin/dscl . -create /users/"$i" AuthenticationAuthority "$shadowHash" 52 | /usr/bin/dscl . -delete /users/"$i" SMBSID 53 | /usr/bin/dscl . -delete /users/"$i" SMBScriptPath 54 | /usr/bin/dscl . -delete /users/"$i" SMBPasswordLastSet 55 | /usr/bin/dscl . -delete /users/"$i" SMBGroupRID 56 | /usr/bin/dscl . -delete /users/"$i" PrimaryNTDomain 57 | /usr/bin/dscl . -delete /users/"$i" AppleMetaRecordName 58 | /usr/bin/dscl . -delete /users/"$i" PrimaryNTDomain 59 | /usr/bin/dscl . -delete /users/"$i" MCXSettings 60 | /usr/bin/dscl . -delete /users/"$i" MCXFlags 61 | 62 | sleep 10 63 | 64 | # Verify the account was sucessfully converted 65 | accountVerify=$(/usr/bin/dscl . -read /Users/"$i" AuthenticationAuthority | head -2 | awk -F'/' '{print $2}' | tr -d '\n') 66 | 67 | if [[ "$accountVerify" == "Active Directory" ]]; then 68 | echo "The account for "$i" is still a mobile account. Conversion failed." 69 | exit 1 70 | else 71 | echo "The account for "$i" has been successfully converted to a local account" 72 | fi 73 | 74 | # Change home directory ownership 75 | homeDir=$(/usr/bin/dscl . -read /Users/"$i" NFSHomeDirectory | awk '{print $2}') 76 | 77 | # Add the user to the staff group locally 78 | /usr/sbin/dseditgroup -o edit -a "$i" -t user staff 79 | 80 | # Create log file in the user's home directory to reflect when the account was migrated 81 | cat > /Users/"$i"/migrationNotes.log << EOF 82 | This account was converted from a mobile account to a local account on: 83 | `date` 84 | 85 | User and Group Information: 86 | `/usr/bin/id $i` 87 | EOF 88 | 89 | leaveDomain="Yes" 90 | } 91 | 92 | if [[ -z "$checkBinding" ]]; then 93 | echo "Computer is not bound to Active Directory. Exiting." 94 | exit 0 95 | fi 96 | 97 | # Account Section 98 | 99 | userList=$(dscl /Local/Default -list /Users uid | awk '$2 >= 100 && $0 !~ /^_/ { print $1 }') 100 | 101 | for i in $userList; do 102 | echo $i 103 | accountType=$(/usr/bin/dscl . -read /Users/"$i" AuthenticationAuthority | head -2 | awk -F'/' '{print $2}' | tr -d '\n') 104 | if [[ "$accountType" = "Active Directory" ]]; then 105 | echo "Active Directory account found for "$i". Verifying account is a Mobile Account" 106 | mobileCheck=$(/usr/bin/dscl . -read /Users/"$i" AuthenticationAuthority | head -2 | awk -F'/' '{print $1}' | tr -d '\n' | sed 's/^[^:]*: //' | sed s/\;/""/g) 107 | if [[ "$mobileCheck" == "LocalCachedUser" ]]; then 108 | echo ""$i" is a mobile account, starting conversion to a local account" 109 | convertAccount 110 | else 111 | echo ""$i" is not a mobile account. Exiting" 112 | fi 113 | fi 114 | done 115 | 116 | if [[ "$leaveDomain" == "Yes" ]]; then 117 | removeAD 118 | # Performs a recon to the Jamf Pro server. Comment out if not needed 119 | /usr/local/bin/jamf recon 120 | /bin/launchctl asuser "$currUserUID" sudo -iu "$currUser" /usr/bin/osascript < /tmp/SoftwareUpdates 65 | countUpdates 66 | echo "------------------------------" 67 | echo "Select an update to install..." 68 | echo "---- Enter \"q\" to quit ----" 69 | read answer 70 | case "$answer" in 71 | 1) 72 | #updateItunes=`cat /tmp/SoftwareUpdates | sed 's/^[[:space:]]*//' | grep -e "iTunes"` 73 | doUpdate="`sudo softwareupdate --install "${update[1]}"`" 74 | ;; 75 | 2) 76 | #updateOS=`cat /tmp/SoftwareUpdates | sed 's/^[[:space:]]*//' | grep -e "macOS"` 77 | doUpdate="`sudo softwareupdate --install "${update[2]}"`" 78 | ;; 79 | 3) 80 | #updateOS=`cat /tmp/SoftwareUpdates | sed 's/^[[:space:]]*//' | grep -e "macOS"` 81 | doUpdate="`sudo softwareupdate --install "${update[3]}"`" 82 | ;; 83 | 4) 84 | #updateOS=`cat /tmp/SoftwareUpdates | sed 's/^[[:space:]]*//' | grep -e "macOS"` 85 | doUpdate="`sudo softwareupdate --install "${update[4]}"`" 86 | ;; 87 | q) 88 | echo "Exiting.." 89 | doUpdate=`exit 1` 90 | ;; 91 | esac 92 | fi 93 | 94 | # Runs the command 95 | echo "$doUpdate" 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /Apple Software Update Search/README.md: -------------------------------------------------------------------------------- 1 | # Apple Software Update Search 2 | 3 | This repo contains a script *[AppleSoftwareUpdateSearch.sh]* that can be used to install Apple Software Updates on computers that are enrolled in your Jamf Pro Server. 4 | 5 | ## Version 2.0 Update (Feb 2018) 6 | - Added support for multiple updates to used in the script parameters (current limit is 4, version 1.0 only supported one item at a time) 7 | - Rewrote the way updates are handled. Now any update that is found gets added to an array then is downloaded to the default location (/Library/Updates/). Once the update is finished downloading, it gets added to another array 8 | which is then used to install each update after they all have been downloaded. 9 | - Added a section that will check to see if the update requires a restart. If it's required, it will set the "restartRequired" variable to yes. Once all updates have been downloaded and installed, a if statement checks the restart variable and will trigger a policy setup for an delayed authenticated reboot. **NOTE: A policy will have to be created with a matching trigger in order for this feature to work.** This section currently only looks for the "security" label. 10 | 11 | - Added a manual inventory update before the restartRequired check to ensure any installed updates are succesfully reflected in the Jamf Pro Server. *(This was written in to work around an issue where inventory updates would fail if the update name exceeded a certain amount of characters.)* 12 | 13 | ### Script Parameters 14 | Parameter 4 - Update Selection **(Required)** 15 | 16 | Parameter 5 - Update Selection *(Optional)* 17 | 18 | Parameter 6 - Update Selection *(Optional)* 19 | 20 | Parameter 7 - Update Selection *(Optional)* 21 | 22 | - File List 23 | 1. AppleSoftwareUpdateSearch_v2.sh *[Requires SUDO privileges]* 24 | -------------------------------------------------------------------------------- /AppleScript Prompt Template/AppleScript_Prompt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ################################################# 4 | # AppleScript Prompt Template 5 | # Joshua Harvey | March 2019 6 | # josh[at]macjeezy.com 7 | # GitHub - github.com/therealmacjeezy 8 | # JAMFnation - therealmacjeezy 9 | ################################################# 10 | 11 | ############## Script Variables ################# 12 | PROMPT_TITLE="Sample Title" 13 | PROMPT_MESSAGE="Here is a Sample Message. Go Phillies" 14 | PROMPT_BUTTON_ONE="No" 15 | PROMPT_BUTTON_TWO="Go Phillies" 16 | # Must be a url that doesn't have authentication and is in the format of .png, .jpeg or .ico 17 | PROMPT_ICON_URL="https://upload.wikimedia.org/wikipedia/en/4/47/New_Phillies_logo.png" 18 | 19 | ## Output variables above to a temporary location for use in the AppleScript prompt 20 | if [[ ! -z "$PROMPT_TITLE" ]]; then 21 | echo "$PROMPT_TITLE" > /tmp/PROMPT_TITLE 22 | else 23 | echo "Missing Prompt Title Variable" 24 | exit 1 25 | fi 26 | 27 | if [[ ! -z "$PROMPT_MESSAGE" ]]; then 28 | echo "$PROMPT_MESSAGE" > /tmp/PROMPT_MESSAGE 29 | else 30 | echo "Missing Prompt Message Variable" 31 | exit 1 32 | fi 33 | 34 | if [[ ! -z "$PROMPT_BUTTON_ONE" ]]; then 35 | echo "$PROMPT_BUTTON_ONE" > /tmp/PROMPT_BUTTON_ONE 36 | else 37 | echo "No" > /tmp/PROMPT_BUTTON_ONE 38 | fi 39 | 40 | if [[ ! -z "$PROMPT_BUTTON_TWO" ]]; then 41 | echo "$PROMPT_BUTTON_TWO" > /tmp/PROMPT_BUTTON_TWO 42 | else 43 | echo "Continue" > /tmp/PROMPT_BUTTON_TWO 44 | fi 45 | 46 | if [[ ! -z "$PROMPT_BUTTON_TWO" ]]; then 47 | echo "$PROMPT_BUTTON_TWO" > /tmp/PROMPT_BUTTON_TWO 48 | else 49 | echo "Continue" > /tmp/PROMPT_BUTTON_TWO 50 | fi 51 | 52 | if [[ ! -z "$PROMPT_BUTTON_TWO" ]]; then 53 | curl "$PROMPT_ICON_URL" -o /tmp/PROMPT_ICON.png 54 | fi 55 | 56 | displayPrompt() { 57 | currUser=$(scutil <<< "show State:/Users/ConsoleUser" | awk -F': ' '/[[:space:]]+Name[[:space:]]:/ { if ( $2 != "loginwindow" ) { print $2 }}') 58 | currUserUID=$(id -u "$currUser") 59 | 60 | /bin/launchctl asuser "$currUserUID" sudo -iu "$currUser" /usr/bin/osascript < 97 | 98 | PlayLostModeSound 99 | 100 | 101 | 102 | {deviceID} 103 | 104 | 105 | ''' 106 | 107 | try: 108 | headers = {'Content-Type': 'application/xml', 'Authorization': f'Bearer {apiToken}'} 109 | apiURL = f"https://{jamfURL}/JSSResource/mobiledevicecommands/command/PlayLostModeSound/id/{deviceID}" 110 | r = requests.post(apiURL, headers=headers) 111 | if r.status_code == 200: 112 | print(f"\tLost Mode Sound Command Successfully Sent to {displayName}") 113 | elif r.status_code == 201: 114 | print(f"\tLost Mode Sound Command Successfully Sent to {displayName}") 115 | except Exception as errorMessage: 116 | print(f"\tplay_lost_mode_sound ERROR:\n {errorMessage}") 117 | 118 | def set_lost_mode(apiToken, jamfURL, deviceID, displayName): 119 | xmlData = f''' 120 | 121 | EnableLostMode 122 | {lostModeMsg} 123 | {lostModePhone} 124 | {lostModeFootnote} 125 | 126 | 127 | 128 | {deviceID} 129 | 130 | 131 | ''' 132 | 133 | try: 134 | headers = {'Content-Type': 'application/xml', 'Authorization': f'Bearer {apiToken}'} 135 | apiURL = f"https://{jamfURL}/JSSResource/mobiledevicecommands/command/EnableLostMode/id/{deviceID}" 136 | r = requests.post(apiURL, data=xmlData, headers=headers) 137 | if r.status_code == 200: 138 | # print(f"Lost Mode Command Successfully Sent to {displayName}.") 139 | if lostModeSound == 'true': 140 | play_lost_mode_sound(apiToken, jamfURL, deviceID, displayName) 141 | elif r.status_code == 201: 142 | print(f"Lost Mode Command Successfully Sent to {displayName}.") 143 | if lostModeSound == 'true': 144 | play_lost_mode_sound(apiToken, jamfURL, deviceID, displayName) 145 | elif r.status_code == 401: 146 | print("Your account is unauthorized to perform this action.") 147 | else: 148 | print(f"Lost Mode Command Failed for {displayName}\n") 149 | except Exception as errorMessage: 150 | print(f"\tset_lost_mode ERROR:\n{errorMessage}") 151 | 152 | def disable_lost_mode(apiToken, jamfURL, deviceID, displayName): 153 | xmlData = f''' 154 | 155 | DisableLostMode 156 | 157 | 158 | 159 | {deviceID} 160 | 161 | 162 | ''' 163 | 164 | try: 165 | headers = {'Content-Type': 'application/xml', 'Authorization': f'Bearer {apiToken}'} 166 | apiURL = f"https://{jamfURL}/JSSResource/mobiledevicecommands/command/EnableLostMode/id/{deviceID}" 167 | r = requests.post(apiURL, data=xmlData, headers=headers) 168 | if r.status_code == 200: 169 | print(f"Disable Lost Mode Command Successfully Sent to {displayName}.") 170 | if lostModeSound == 'true': 171 | play_lost_mode_sound(apiToken, jamfURL, deviceID, displayName) 172 | elif r.status_code == 201: 173 | print(f"Disable Lost Mode Command Successfully Sent to {displayName}.") 174 | if lostModeSound == 'true': 175 | play_lost_mode_sound(apiToken, jamfURL, deviceID, displayName) 176 | elif r.status_code == 401: 177 | print("Your account is unauthorized to perform this action.") 178 | else: 179 | print(f"Disable Lost Mode Command Failed for {displayName}\n") 180 | except Exception as errorMessage: 181 | print(f"\tdisable_lost_mode ERROR:\n{errorMessage}") 182 | 183 | if __name__ == '__main__': 184 | ### Config Section 185 | jamfAuthPath = os.path.dirname(jamfAuth.__file__) 186 | jamfAuthConfig = f"{jamfAuthPath}/support/.jamfauth.json" 187 | 188 | f = open(jamfAuthConfig) 189 | 190 | jamfAuthJSON = json.load(f) 191 | 192 | jamfURL = jamfAuthJSON['jamfHostName'] 193 | 194 | ### Get API Token with jamfAuth 195 | apiToken = startAuth() 196 | 197 | if len(sys.argv) > 1: 198 | print(sys.argv[1]) 199 | if sys.argv[1] == 'enable': 200 | lostModeDisable = 'false' 201 | if sys.argv[1] == 'disable': 202 | lostModeDisable = 'true' 203 | if sys.argv[1] == 'config': 204 | print(f">> jamfAuth config:\n\t{jamfAuthJSON}") 205 | print(f">> bulkLostMode settings:\n\tDevice List: {deviceList}\n\tLost Mode Message: {lostModeMsg}\n\tLost Mode Number:{lostModePhone}\n\tPlay Lost Mode Sound: {lostModeSound}\n\tLost Mode Footnote: {lostModeFootnote}") 206 | sys.exit() 207 | if sys.argv[1] == 'help': 208 | print(f">> BulkLostMode-v2.py Usage:\n\tpython3 BulkLostMode-v2.py\n>> Options:\n\t- enable: enables lost mode\n\t- disable: disables lost mode\n\t- config: shows the current authentication and BulkLostMode-v2 variables\n\t- help: usage and available options") 209 | sys.exit() 210 | 211 | read_device_list(deviceList) 212 | get_device_id(apiToken, jamfURL, devices) 213 | -------------------------------------------------------------------------------- /Bulk Lost Mode v2/DeviceList.csv: -------------------------------------------------------------------------------- 1 | DNQXFK4DKXKW 2 | GG7ZTDSDMF3R -------------------------------------------------------------------------------- /Bulk Lost Mode v2/README.md: -------------------------------------------------------------------------------- 1 | # Bulk Lost Mode v2 Overview 2 | 3 | > This script uses [jamfAuth](https://github.com/therealmacjeezy/JamfAuth) to perform the API authentication. Looking to setup **jamfAuth**? [Click here..](https://github.com/therealmacjeezy/JamfAuth#installation) 4 | 5 | Looking for an easy way to enable or disable Lost Mode on your Mobile Devices? Look no further.. The `BulkLostMode-v2.py` does just that. 6 | 7 | This script will pull a list of serial numbers from `DeviceList.csv` and for each serial number found, it will get the device ID for that device and then either enable or disable Lost Mode for that device based on the **lostModeDisable** variable. 8 | 9 | By default, this script will **enable** Lost Mode **without** sound. 10 | 11 | ---- 12 | ## Usage 13 | Before running `BulkLostMode-v2.py` you will need to paste the Serial Numbers into `DeviceList.csv` and save it. 14 | 15 | Once you have saved the list of Serial Numbers, you can use the following command to start the script: `python3 BulkLostMode-v2.py` 16 | 17 | ### Options 18 | There are four options built into `BulkLostMode-v2.py`: 19 | - `enable`: This will enable Lost Mode on the devices **(Default Action)** 20 | - **Usage:** `python3 BulkLostMode-v2.py enable` 21 | - `disable`: This will **disable** Lost Mode on the devices 22 | - **Usage:** `python3 BulkLostMode-v2.py disable` 23 | - `config`: This will display the current authentication and BulkLostMode-v2 variables 24 | - **Usage:** `python3 BulkLostMode-v2.py config` 25 | - `help`: This will display how to use this script and the available options 26 | - **Usage:** `python3 BulkLostMode-v2.py help` 27 | 28 | ---- 29 | ## Requirements 30 | 31 | #### Python Version 32 | - 3.8.x 33 | - Tested with 3.8.13 34 | 35 | #### Python Packages 36 | - requests 37 | - `pip3 install requests` 38 | - jamfAuth 39 | - `pip3 install jamfAuth` 40 | - json 41 | - `pip3 install json` 42 | - csv 43 | - `pip3 install csv` 44 | 45 | ---- 46 | ## Examples 47 | **BulkLostMode-v2.py** 48 | 49 | This command will enable Lost Mode on the serial numbers entered in the csv. 50 | ```shell 51 | 12:11:29 ➜ Scripts/BulkLostMode-v2 git:(master?) python:(3.8.13) python3 bulkLostMode-v2.py 52 | _ __ _ _ _ 53 | (_) __ _ _ __ ___ / _| /_\ _ _| |_| |__ 54 | | |/ _` | '_ ` _ \| |_ //_\\| | | | __| '_ \ 55 | | | (_| | | | | | | _/ _ \ |_| | |_| | | | 56 | _/ |\__,_|_| |_| |_|_| \_/ \_/\__,_|\__|_| |_| 57 | |__/ ------ jamfAuth.py (v0.3.2)[pip] 58 | ----------- josh.harvey@jamf.com 59 | ----------- Created: 04/25/22 60 | ----------- Modified: 04/28/22 61 | 62 | > jamfAuth Config Path: /Users/josh.harvey/Library/Python/3.8/lib/python/site-packages/jamfAuth/support/.jamfauth.json 63 | [Jamf Pro Host Name]: bender.jamfcloud.com 64 | [Jamf Pro API URL]: https://bender.jamfcloud.com/api/v1/ 65 | [Jamf Pro API Username]: mcbender 66 | [>jamfAuth] Loaded API Token 67 | [Jamf Pro API Token Status]: Valid 68 | [>jamfAuth] Loaded API Token 69 | Lost Mode Command Successfully Sent to Bender-DNQXDS5ZWD5W 70 | Lost Mode Command Successfully Sent to TEST-DMPDDWD9Q1GC. 71 | Lost Mode Command Successfully Sent to TEST-DLXSDW8YGHKF. 72 | Lost Mode Command Successfully Sent to TEST-DLXQN7YDFK9. 73 | Lost Mode Command Successfully Sent to iPad. 74 | ``` 75 | 76 | **BulkLostMode-v2.py config** 77 | 78 | This example shows the `config` option being used to display the current settings being used. 79 | 80 | ```shell 81 | 12:10:20 ➜ Scripts/BulkLostMode-v2 git:(master?) python3 bulkLostMode-v2.py config 82 | _ __ _ _ _ 83 | (_) __ _ _ __ ___ / _| /_\ _ _| |_| |__ 84 | | |/ _` | '_ ` _ \| |_ //_\\| | | | __| '_ \ 85 | | | (_| | | | | | | _/ _ \ |_| | |_| | | | 86 | _/ |\__,_|_| |_| |_|_| \_/ \_/\__,_|\__|_| |_| 87 | |__/ ------ jamfAuth.py (v0.3.2)[pip] 88 | ----------- josh.harvey@jamf.com 89 | ----------- Created: 04/25/22 90 | ----------- Modified: 04/28/22 91 | 92 | > jamfAuth Config Path: /Users/josh.harvey/Library/Python/3.8/lib/python/site-packages/jamfAuth/support/.jamfauth.json 93 | [Jamf Pro Host Name]: bender.jamfcloud.com 94 | [Jamf Pro API URL]: https://bender.jamfcloud.com/api/v1/ 95 | [Jamf Pro API Username]: mcbender 96 | [>jamfAuth] Loaded API Token 97 | [Jamf Pro API Token Status]: Valid 98 | [>jamfAuth] Loaded API Token 99 | config 100 | >> jamfAuth config: 101 | {'apiUserName': 'mcbender', 'jamfHostName': 'bender.jamfcloud.com', 'jamfAPIURL': 'https://bender.jamfcloud.com/api/v1/'} 102 | >> bulkLostMode settings: 103 | Device List: /Users/josh.harvey/Github/Scripts/BulkLostMode-v2/DeviceList.csv 104 | Lost Mode Message: This device has been reported lost or stolen. Please call the owner at the number below. 105 | Lost Mode Number:281-330-8004 106 | Play Lost Mode Sound: false 107 | Lost Mode Footnote: Thank you! 108 | ``` 109 | 110 | **BulkLostMode-v2.py disable** 111 | 112 | This example shows the `disable` option being used. 113 | ```shell 114 | 12:14:10 ➜ Scripts/BulkLostMode-v2 git:(master?) python:(3.8.13) python3 bulkLostMode-v2.py disable 115 | _ __ _ _ _ 116 | (_) __ _ _ __ ___ / _| /_\ _ _| |_| |__ 117 | | |/ _` | '_ ` _ \| |_ //_\\| | | | __| '_ \ 118 | | | (_| | | | | | | _/ _ \ |_| | |_| | | | 119 | _/ |\__,_|_| |_| |_|_| \_/ \_/\__,_|\__|_| |_| 120 | |__/ ------ jamfAuth.py (v0.3.2)[pip] 121 | ----------- josh.harvey@jamf.com 122 | ----------- Created: 04/25/22 123 | ----------- Modified: 04/28/22 124 | 125 | > jamfAuth Config Path: /Users/josh.harvey/Library/Python/3.8/lib/python/site-packages/jamfAuth/support/.jamfauth.json 126 | [Jamf Pro Host Name]: bender.jamfcloud.com 127 | [Jamf Pro API URL]: https://bender.jamfcloud.com/api/v1/ 128 | [Jamf Pro API Username]: mcbender 129 | [>jamfAuth] Loaded API Token 130 | [Jamf Pro API Token Status]: Valid 131 | [>jamfAuth] Loaded API Token 132 | disable 133 | Disable Lost Mode Command Successfully Sent to Bender-DNQXDS5ZWD5W. 134 | ``` -------------------------------------------------------------------------------- /Create Policy and Profile Scope Overview/JamfPro_ConfigurationProfile_ScopeOverview-05122022.csv: -------------------------------------------------------------------------------- 1 | Configuration Profile Name,Configuration Profile ID,Configuration Profile Scope,Scope: Computers,Scope: Computer Groups,Scope: Excluded Computers,Scope: Excluded Computer Groups 2 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/OSXConfigurationProfiles.html?id=1&o=r"", ""Default Plan - Jamf Protect Configuration"")",1,All Computers,N/A,N/A,N/A,N/A 3 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/OSXConfigurationProfiles.html?id=3&o=r"", ""Jamf Connect - Login"")",3,All Computers,N/A,N/A,N/A,Remove Jamf Connect (ID: 3) 4 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/OSXConfigurationProfiles.html?id=4&o=r"", ""Jamf Connect - Menu"")",4,All Computers,N/A,N/A,N/A,Remove Jamf Connect (ID: 3) 5 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/OSXConfigurationProfiles.html?id=5&o=r"", ""Jamf Connect License"")",5,All Computers,N/A,N/A,N/A,Remove Jamf Connect (ID: 3) 6 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/OSXConfigurationProfiles.html?id=8&o=r"", ""Loading... Network Profile"")",8,All Computers,N/A,N/A,N/A,N/A 7 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/OSXConfigurationProfiles.html?id=10&o=r"", ""Jamf Connect Login Window (Self Service)"")",10,Custom,N/A,Remove Jamf Connect (ID: 3),N/A,N/A 8 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/OSXConfigurationProfiles.html?id=11&o=r"", ""Jamf Connect Menu (Self Service)"")",11,Custom,N/A,"macOS Update Ready (ID: 4), Remove Jamf Connect (ID: 3)",N/A,N/A 9 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/OSXConfigurationProfiles.html?id=12&o=r"", ""Jamf Connect License (Self Service)"")",12,Custom,N/A,Remove Jamf Connect (ID: 3),N/A,N/A 10 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/OSXConfigurationProfiles.html?id=13&o=r"", ""Disable Displays Prefrence Pane"")",13,All Computers,N/A,N/A,N/A,N/A 11 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/OSXConfigurationProfiles.html?id=14&o=r"", ""Jamf Connect - Menu Keychain Test"")",14,All Computers,N/A,N/A,N/A,N/A 12 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/OSXConfigurationProfiles.html?id=15&o=r"", ""Keychain Test"")",15,All Computers,N/A,N/A,ladmin’s MacBook Pro (ID: 1),Bound Systems (ID: 5) 13 | -------------------------------------------------------------------------------- /Create Policy and Profile Scope Overview/JamfPro_ConfigurationProfile_ScopeOverview-06152022.csv: -------------------------------------------------------------------------------- 1 | Configuration Profile Name,Configuration Profile ID,Configuration Profile Scope,Scope: Computers,Scope: Computer Groups,Scope: Excluded Computers,Scope: Excluded Computer Groups 2 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/OSXConfigurationProfiles.html?id=1&o=r"", ""Default Plan - Jamf Protect Configuration"")",1,All Computers,N/A,N/A,N/A,N/A 3 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/OSXConfigurationProfiles.html?id=3&o=r"", ""Jamf Connect - Login"")",3,All Computers,N/A,N/A,N/A,Remove Jamf Connect (ID: 3) 4 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/OSXConfigurationProfiles.html?id=4&o=r"", ""Jamf Connect - Menu"")",4,All Computers,N/A,N/A,N/A,Remove Jamf Connect (ID: 3) 5 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/OSXConfigurationProfiles.html?id=5&o=r"", ""Jamf Connect License"")",5,All Computers,N/A,N/A,N/A,Remove Jamf Connect (ID: 3) 6 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/OSXConfigurationProfiles.html?id=8&o=r"", ""Loading... Network Profile"")",8,Custom,N/A,N/A,N/A,N/A 7 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/OSXConfigurationProfiles.html?id=10&o=r"", ""Jamf Connect Login Window (Self Service)"")",10,Custom,N/A,Remove Jamf Connect (ID: 3),N/A,N/A 8 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/OSXConfigurationProfiles.html?id=11&o=r"", ""Jamf Connect Menu (Self Service)"")",11,Custom,N/A,"macOS Update Ready (12.3.1) (ID: 4), Remove Jamf Connect (ID: 3)",N/A,N/A 9 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/OSXConfigurationProfiles.html?id=12&o=r"", ""Jamf Connect License (Self Service)"")",12,Custom,N/A,Remove Jamf Connect (ID: 3),N/A,N/A 10 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/OSXConfigurationProfiles.html?id=13&o=r"", ""Disable Displays Prefrence Pane"")",13,All Computers,N/A,N/A,N/A,N/A 11 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/OSXConfigurationProfiles.html?id=14&o=r"", ""Jamf Connect - Menu Keychain Test"")",14,All Computers,N/A,N/A,N/A,N/A 12 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/OSXConfigurationProfiles.html?id=15&o=r"", ""Keychain Test"")",15,All Computers,N/A,N/A,ladmin’s MacBook Pro (ID: 1),Bound Systems (ID: 5) 13 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/OSXConfigurationProfiles.html?id=20&o=r"", ""Test NDES 3"")",20,Custom,N/A,N/A,N/A,N/A 14 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/OSXConfigurationProfiles.html?id=21&o=r"", ""Test NDES 4"")",21,Custom,"ladmin’s MacBook Pro (ID: 1), macOSvm-ColdBeer (ID: 2), apitest (ID: 3)",N/A,N/A,N/A 15 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/OSXConfigurationProfiles.html?id=22&o=r"", ""Test NDES 5"")",22,Custom,apitest (ID: 3),N/A,N/A,N/A 16 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/OSXConfigurationProfiles.html?id=23&o=r"", ""Test NDES 6"")",23,Custom,apitest (ID: 3),N/A,N/A,N/A 17 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/OSXConfigurationProfiles.html?id=24&o=r"", ""Jamf Connect Debug Logging"")",24,Custom,test’s Virtual Machine (ID: 8),N/A,N/A,N/A 18 | -------------------------------------------------------------------------------- /Create Policy and Profile Scope Overview/JamfPro_PolicyScope_Overview-05122022.csv: -------------------------------------------------------------------------------- 1 | Policy Name,Policy ID,Policy Enabled?,Policy Scope,Scope: Computers,Scope: Computer Groups,Scope: Excluded Computers,Scope: Excluded Computer Groups 2 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/policies.html?id=8&o=r"", ""Elevate Account"")",8,True,All Computers,N/A,N/A,N/A,"Bound Systems (ID: 5), Software Updates Available (ID: 7)" 3 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/policies.html?id=6&o=r"", ""Install Jamf Connect"")",6,True,All Computers,N/A,N/A,N/A,N/A 4 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/policies.html?id=4&o=r"", ""Install jamfAuth"")",4,True,All Computers,N/A,N/A,N/A,N/A 5 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/policies.html?id=5&o=r"", ""Install Mooncheese Resources"")",5,True,All Computers,N/A,N/A,N/A,N/A 6 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/policies.html?id=2&o=r"", ""Setup Jamf Connect"")",2,False,All Computers,N/A,N/A,N/A,N/A 7 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/policies.html?id=7&o=r"", ""Submit Computer Inventory"")",7,True,All Computers,N/A,N/A,N/A,N/A 8 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/policies.html?id=3&o=r"", ""Test Sound"")",3,True,Custom,ladmin’s MacBook Pro (ID: 1),N/A,N/A,N/A 9 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/policies.html?id=1&o=r"", ""Update Inventory"")",1,True,All Computers,N/A,N/A,N/A,N/A 10 | -------------------------------------------------------------------------------- /Create Policy and Profile Scope Overview/JamfPro_PolicyScope_Overview-06152022.csv: -------------------------------------------------------------------------------- 1 | Policy Name,Policy ID,Policy Enabled?,Packages,Scripts,Policy Scope,Scope: Computers,Scope: Computer Groups,Scope: Excluded Computers,Scope: Excluded Computer Groups 2 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/policies.html?id=13&o=r"", ""Cache Xcode Package"")",13,True,Xcode_13.4.xip.pkg (ID: 7),,All Computers,N/A,N/A,N/A,N/A 3 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/policies.html?id=8&o=r"", ""Elevate Account"")",8,True,,Temporary User Account Elevation (ID: 2),All Computers,N/A,N/A,N/A,"Bound Systems (ID: 5), Software Updates Available (ID: 7)" 4 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/policies.html?id=10&o=r"", ""Install Homebrew"")",10,True,,InstallHomebrew.sh (ID: 3),All Computers,N/A,N/A,N/A,N/A 5 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/policies.html?id=16&o=r"", ""Install Homebrew Packages"")",16,True,,Install Homebrew Packages (ID: 6),All Computers,N/A,N/A,N/A,N/A 6 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/policies.html?id=6&o=r"", ""Install Jamf Connect"")",6,True,Jamf Connect [2.11] (ID: 1),,All Computers,N/A,N/A,N/A,N/A 7 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/policies.html?id=4&o=r"", ""Install jamfAuth"")",4,True,,Install jamfAuth (ID: 1),All Computers,N/A,N/A,N/A,N/A 8 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/policies.html?id=5&o=r"", ""Install Mooncheese Resources"")",5,True,"Install Mooncheese Items.pkg (ID: 3), Tux.pkg (ID: 9)",,All Computers,N/A,N/A,N/A,N/A 9 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/policies.html?id=18&o=r"", ""Install Python3 Packages"")",18,True,,Install Python3 Packages (ID: 8),All Computers,N/A,N/A,N/A,N/A 10 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/policies.html?id=17&o=r"", ""Install Ruby Gems"")",17,True,,Install Ruby Gems (ID: 7),All Computers,N/A,N/A,N/A,N/A 11 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/policies.html?id=11&o=r"", ""Install swiftDialog"")",11,True,dialog-1.10.4-2602.pkg (ID: 5),Add swiftDialog To Path (ID: 4),All Computers,N/A,N/A,N/A,N/A 12 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/policies.html?id=12&o=r"", ""Install unxip"")",12,True,Install unxip.pkg (ID: 6),,All Computers,N/A,N/A,N/A,N/A 13 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/policies.html?id=14&o=r"", ""Install Xcode"")",14,True,,Install Xcode (ID: 5),All Computers,N/A,N/A,N/A,N/A 14 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/policies.html?id=9&o=r"", ""Install Xcode CLI"")",9,True,Command Line Tools.pkg (ID: 4),,All Computers,N/A,N/A,N/A,N/A 15 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/policies.html?id=2&o=r"", ""Setup Jamf Connect"")",2,False,Jamf Connect [2.11] (ID: 1),,All Computers,N/A,N/A,N/A,N/A 16 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/policies.html?id=19&o=r"", ""Setup Xcode, Homebrew, Ruby Gems and Python3"")",19,True,,"Setup Xcode, Homebrew, Ruby Gems and Python (ID: 9)",All Computers,N/A,N/A,N/A,N/A 17 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/policies.html?id=7&o=r"", ""Submit Computer Inventory"")",7,True,,,All Computers,N/A,N/A,N/A,N/A 18 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/policies.html?id=3&o=r"", ""Test Sound"")",3,True,,,Custom,ladmin’s MacBook Pro (ID: 1),N/A,N/A,N/A 19 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/policies.html?id=15&o=r"", ""Test Update"")",15,True,,,Custom,N/A,N/A,N/A,N/A 20 | "=HYPERLINK(""https://mooncheese.jamfcloud.com/policies.html?id=1&o=r"", ""Update Inventory"")",1,True,,,All Computers,N/A,N/A,N/A,N/A 21 | -------------------------------------------------------------------------------- /Create Policy and Profile Scope Overview/README.md: -------------------------------------------------------------------------------- 1 | # Create Policy and Profile Scope Overview 2 | 3 | > This script uses [jamfAuth](https://github.com/therealmacjeezy/JamfAuth) to perform the API authentication. Looking to setup **jamfAuth**? [Click here..](https://github.com/therealmacjeezy/JamfAuth#installation) 4 | 5 | **Last Updated:** 06/15/2022 - Added Policy Packages and Policy Scripts functions. 6 | 7 | Looking for an easy way to get the scopes for all of your Policies and Configuration Profiles? Look no further.. The `CreateScopeSummary.py` does just that. 8 | 9 | This script reaches out to your Jamf Pro Server and gets a list of the Policies and Configuration Profiles you are using within your Jamf Pro Server. It then loops through each of the Policies and Configuration Profiles to get the following information: 10 | 11 | - Policy / Configuration Profile Name 12 | - When this gets saved to the `.csv`, a hyperlink gets created to take you to that policy within Jamf Pro when clicked on. 13 | - Policy / Configuration Profile ID 14 | - Policy Status *(Is it enabled?)* 15 | - Policy Packages 16 | - Policy Scripts 17 | - Policy / Configuration Profile Scope 18 | - Policy / Configuration Profile Exclusions 19 | 20 | Once it's done, it will then create two `.csv` files containing the above information and display the path to each file inside the Terminal window. There are two sample `.csv` files in this repository to give you an example of what you should expect these files to contain. I've also included markdown table versions of both files in the **Examples** section *(#2 and #3)*. 21 | 22 | 23 | Below are the categories the script **currently checks for** within `scope` and `exclusions`: 24 | - Computers 25 | - Computer Groups 26 | 27 | 28 | ---- 29 | ### To-Do 30 | - [x] Add Exclusions to the Policy section 31 | - [x] Add Policy Status (enabled/disabled) 32 | - [x] Add Policy Packages (if any are added) 33 | - [x] Add Policy Scripts (if any are added) 34 | - [ ] Add the following categories to the scoped targets and exclusions search: 35 | - [ ] Users 36 | - [ ] LDAP User Groups 37 | 38 | ---- 39 | ## Requirements 40 | 41 | #### Python Version 42 | - 3.8.x 43 | - Tested with 3.8.13 44 | 45 | #### Python Packages 46 | - requests 47 | - `pip3 install requests` 48 | - pandas 49 | - `pip3 install pandas` 50 | - jamfAuth 51 | - `pip3 install jamfAuth` 52 | - json 53 | - `pip3 install json` 54 | 55 | ---- 56 | ## Usage 57 | ```shell 58 | python3 /path/to/CreateScopeSummary.py 59 | ``` 60 | ---- 61 | ## Examples 62 | #### Example 1: CreateScopeSummary.py Output 63 | ```shell 64 | 09:43:12 [took 4s] ➜ python:(3.8.13) python3 CreateScopeSummary.py 65 | _ __ _ _ _ 66 | (_) __ _ _ __ ___ / _| /_\ _ _| |_| |__ 67 | | |/ _` | '_ ` _ \| |_ //_\\| | | | __| '_ \ 68 | | | (_| | | | | | | _/ _ \ |_| | |_| | | | 69 | _/ |\__,_|_| |_| |_|_| \_/ \_/\__,_|\__|_| |_| 70 | |__/ ------ jamfAuth.py (v0.3.2)[pip] 71 | ----------- josh.harvey@jamf.com 72 | ----------- Created: 04/25/22 73 | ----------- Modified: 04/28/22 74 | 75 | > jamfAuth Config Path: /Users/josh.harvey/Library/Python/3.8/lib/python/site-packages/jamfAuth/support/.jamfauth.json 76 | [Jamf Pro Host Name]: mooncheese.jamfcloud.com 77 | [Jamf Pro API URL]: https://mooncheese.jamfcloud.com/api/v1/ 78 | [Jamf Pro API Username]: mcapi 79 | [>jamfAuth] Loaded API Token 80 | [Jamf Pro API Token Status]: Valid 81 | [>jamfAuth] Loaded API Token 82 | 83 | ==== Jamf Pro Policies ==== 84 | 85 | >> Total Policies: 10 86 | ---------------------------- 87 | Cache Xcode Package (ID: 13) 88 | Packages: Xcode_13.4.xip.pkg (ID: 7) 89 | Elevate Account (ID: 8) 90 | Scripts: Temporary User Account Elevation (ID: 2) 91 | Install Homebrew (ID: 10) 92 | Scripts: InstallHomebrew.sh (ID: 3) 93 | Install Homebrew Packages (ID: 16) 94 | Scripts: Install Homebrew Packages (ID: 6) 95 | Install Jamf Connect (ID: 6) 96 | Packages: Jamf Connect [2.11] (ID: 1) 97 | Install jamfAuth (ID: 4) 98 | Scripts: Install jamfAuth (ID: 1) 99 | Install Mooncheese Resources (ID: 5) 100 | Packages: Install Mooncheese Items.pkg (ID: 3), Tux.pkg (ID: 9) 101 | Install Python3 Packages (ID: 18) 102 | Scripts: Install Python3 Packages (ID: 8) 103 | Install Ruby Gems (ID: 17) 104 | Scripts: Install Ruby Gems (ID: 7) 105 | Install swiftDialog (ID: 11) 106 | Packages: dialog-1.10.4-2602.pkg (ID: 5) 107 | Scripts: Add swiftDialog To Path (ID: 4) 108 | 109 | The Profile Scope Overview has been saved at: 110 | => /Users/josh.harvey/Github/Scripts/Create Policy and Profile Scope Overview/JamfPro_PolicyScope_Overview-05122022.csv 111 | 112 | ==== Jamf Pro Configuration Profiles ==== 113 | 114 | >> Total Configuration Profiles: 11 115 | ---------------------------- 116 | Default Plan - Jamf Protect Configuration (ID: 1) 117 | Jamf Connect - Login (ID: 3) 118 | Jamf Connect - Menu (ID: 4) 119 | Jamf Connect License (ID: 5) 120 | Loading... Network Profile (ID: 8) 121 | Jamf Connect Login Window (Self Service) (ID: 10) 122 | Jamf Connect Menu (Self Service) (ID: 11) 123 | Jamf Connect License (Self Service) (ID: 12) 124 | Disable Displays Prefrence Pane (ID: 13) 125 | Jamf Connect - Menu Keychain Test (ID: 14) 126 | Keychain Test (ID: 15) 127 | 128 | The Configuration Profile Scope Overview has been saved at: 129 | => /Users/josh.harvey/Github/Scripts/Create Policy and Profile Scope Overview/JamfPro_ConfigurationProfile_ScopeOverview-05122022.csv 130 | ``` 131 | 132 | 133 | #### Example 2: `JamfPro_ConfigurationProfile_ScopeOverview-06152022.csv` 134 | |**Policy Name** | **Policy ID** | **Policy Enabled?** | **Packages** | **Scripts** | **Policy Scope** | **Scope: Computers** | **Scope: Computer Groups** | **Scope: Excluded Computers** | **Scope: Excluded Computer Groups** | 135 | |--------------------------------------------|---------|---------------|-----------------------------------------------------|---------------------------------------------------|-------------|------------------------------|----------------------|-------------------------|---------------------------------------------------------| 136 | |Cache Xcode Package |13 |TRUE |Xcode_13.4.xip.pkg (ID: 7) | |All Computers|N/A |N/A |N/A |N/A | 137 | |Elevate Account |8 |TRUE | |Temporary User Account Elevation (ID: 2) |All Computers|N/A |N/A |N/A |Bound Systems (ID: 5), Software Updates Available (ID: 7)| 138 | |Install Homebrew |10 |TRUE | |InstallHomebrew.sh (ID: 3) |All Computers|N/A |N/A |N/A |N/A | 139 | |Install Homebrew Packages |16 |TRUE | |Install Homebrew Packages (ID: 6) |All Computers|N/A |N/A |N/A |N/A | 140 | |Install Jamf Connect |6 |TRUE |Jamf Connect [2.11] (ID: 1) | |All Computers|N/A |N/A |N/A |N/A | 141 | |Install jamfAuth |4 |TRUE | |Install jamfAuth (ID: 1) |All Computers|N/A |N/A |N/A |N/A | 142 | |Install Mooncheese Resources |5 |TRUE |Install Mooncheese Items.pkg (ID: 3), Tux.pkg (ID: 9)| |All Computers|N/A |N/A |N/A |N/A | 143 | |Install Python3 Packages |18 |TRUE | |Install Python3 Packages (ID: 8) |All Computers|N/A |N/A |N/A |N/A | 144 | |Install Ruby Gems |17 |TRUE | |Install Ruby Gems (ID: 7) |All Computers|N/A |N/A |N/A |N/A | 145 | |Install swiftDialog |11 |TRUE |dialog-1.10.4-2602.pkg (ID: 5) |Add swiftDialog To Path (ID: 4) |All Computers|N/A |N/A |N/A |N/A | 146 | |Install unxip |12 |TRUE |Install unxip.pkg (ID: 6) | |All Computers|N/A |N/A |N/A |N/A | 147 | |Install Xcode |14 |TRUE | |Install Xcode (ID: 5) |All Computers|N/A |N/A |N/A |N/A | 148 | |Install Xcode CLI |9 |TRUE |Command Line Tools.pkg (ID: 4) | |All Computers|N/A |N/A |N/A |N/A | 149 | |Setup Jamf Connect |2 |FALSE |Jamf Connect [2.11] (ID: 1) | |All Computers|N/A |N/A |N/A |N/A | 150 | |Setup Xcode, Homebrew, Ruby Gems and Python3|19 |TRUE | |Setup Xcode, Homebrew, Ruby Gems and Python (ID: 9)|All Computers|N/A |N/A |N/A |N/A | 151 | |Submit Computer Inventory |7 |TRUE | | |All Computers|N/A |N/A |N/A |N/A | 152 | |Test Sound |3 |TRUE | | |Custom |ladmin‚Äôs MacBook Pro (ID: 1)|N/A |N/A |N/A | 153 | |Test Update |15 |TRUE | | |Custom |N/A |N/A |N/A |N/A | 154 | |Update Inventory |1 |TRUE | | |All Computers|N/A |N/A |N/A |N/A | 155 | 156 | 157 | 158 | #### Example 3: `JamfPro_PolicyScope_Overview-05122022.csv` 159 | | **Policy Name** | **Policy ID** | **Policy Enabled?** | **Policy Scope** | **Scope: Computers** | **Scope: Computer Groups** | **Scope: Excluded Computers** | **Scope: Excluded Computer Groups** | 160 | |------------------------------|---------------|---------------------|------------------|--------------------------------|----------------------------|-------------------------------|-----------------------------------------------------------| 161 | | Elevate Account | 8 | TRUE | All Computers | N/A | N/A | N/A | Bound Systems (ID: 5), Software Updates Available (ID: 7) | 162 | | Install Jamf Connect | 6 | TRUE | All Computers | N/A | N/A | N/A | N/A | 163 | | Install jamfAuth | 4 | TRUE | All Computers | N/A | N/A | N/A | N/A | 164 | | Install Mooncheese Resources | 5 | TRUE | All Computers | N/A | N/A | N/A | N/A | 165 | | Setup Jamf Connect | 2 | FALSE | All Computers | N/A | N/A | N/A | N/A | 166 | | Submit Computer Inventory | 7 | TRUE | All Computers | N/A | N/A | N/A | N/A | 167 | | Test Sound | 3 | TRUE | Custom | ladmin‚Äôs MacBook Pro (ID: 1) | N/A | N/A | N/A | 168 | | Update Inventory | 1 | TRUE | All Computers | N/A | N/A | N/A | N/A | 169 | -------------------------------------------------------------------------------- /Disable Smart Card Pairing/DisableSmartCardPairing.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ########################################## 4 | # Disable Smart Card Pairing 5 | # Josh Harvey | Jul 2017 6 | # josh[at]macjeezy.com 7 | # GitHub - github.com/therealmacjeezy 8 | # JAMFnation - therealmacjeezy 9 | ########################################## 10 | 11 | ############################### Notes ################################## 12 | # This script will find the current logged in user and run the command 13 | # that will disable (turn off) the Smart Card pairing UI. This command 14 | # can only be ran as the current logged in user and will fail if it is 15 | # ran as SUDO. 16 | # 17 | ########### ISSUES / USAGE ############################################# 18 | # If you have any issues or questions please feel free to contact 19 | # using the information in the header of this script. 20 | # 21 | # Also, Please give me credit and let me know if you are going to use 22 | # this script. I would love to know how it works out and if you find 23 | # it helpful. 24 | ######################################################################## 25 | 26 | 27 | # Finds the current logged in user and sets it as a variable to be used later in the script 28 | currentUser=`who | grep "console" | cut -d" " -f1` 29 | 30 | 31 | # Disables the Smart Card UI (Turns off the option for the user to pair their SmartCard in macOS 10.12 by turning off the Pairing UI) 32 | sudo su - "$currentUser" -c "/usr/sbin/sc_auth pairing_ui -s disable" 33 | -------------------------------------------------------------------------------- /Disable Smart Card Pairing/EA_SmartCardPairing.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ########################################## 4 | # Start Card Pairing Status 5 | # Extension Attribute 6 | # Josh Harvey | Jul 2017 7 | # josh[at]macjeezy.com 8 | # GitHub - github.com/therealmacjeezy 9 | # JAMFnation - therealmacjeezy 10 | ########################################## 11 | 12 | ############################### Notes ################################## 13 | # This Extension Attribute can be used to pull the Smart Card pairing 14 | # status 15 | # 16 | ########### ISSUES / USAGE ############################################# 17 | # If you have any issues or questions please feel free to contact 18 | # using the information in the header of this attribute 19 | # 20 | # Also, Please give me credit and let me know if you are going to use 21 | # this script. I would love to know how it works out and if you find 22 | # it helpful. 23 | ######################################################################## 24 | 25 | # Finds the current logged in user and sets it as a variable to be used later in the script 26 | currentUser=`who | grep "console" | cut -d" " -f1` 27 | 28 | # Finds the status of the Smart Card pairing UI. If the computer is running macOS 10.11 it will pull back a status of N/A 29 | uiStatus=`sudo su - "$currentUser" -c "/usr/sbin/sc_auth pairing_ui -s status"` 30 | 31 | osVersion=`sw_vers -productVersion | grep -e "10.12"` 32 | 33 | if [[ -z "$osVersion" ]]; 34 | then 35 | echo "N/A (macOS 10.12 Required)" 36 | elif [[ "$uiStatus" == "SmartCard Pairing dialog is disabled." ]]; 37 | then 38 | echo "Disabled" 39 | else 40 | echo "Enabled" 41 | fi -------------------------------------------------------------------------------- /Disable Smart Card Pairing/README.md: -------------------------------------------------------------------------------- 1 | # Disable Smart Card Pairing 2 | 3 | - File List 4 | 1. DisableSmartCardPairing.sh 5 | 2. EA_SmartCardPairing.sh 6 | 7 | This repo contains a script *[DisableSmartCardPairing.sh]* that can be used to disable the UI for Smart Card Pairing. This script will pull the current logged in user, 8 | since the sc_auth commands cannot be ran as root. There is also an Extension Attribute script *[EA_SmartCardPairing.sh]* that can be uploaded or created in your JSS to pull the Smart Card Pairing Status and use it for 9 | Smart Groups or Computer Searches. 10 | -------------------------------------------------------------------------------- /Encrypt External Volume/EA_EncryptedVolumePassword.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ########################################## 4 | # Encrypted Volume Password 5 | # Extension Attribute 6 | # Josh Harvey | Jul 2017 7 | # josh[at]macjeezy.com 8 | # GitHub - github.com/therealmacjeezy 9 | # JAMFnation - therealmacjeezy 10 | ########################################## 11 | 12 | ############################### Notes ################################## 13 | # This Extension Attribute can be used to pull the encoded password for 14 | # the external volume. The password is encoded with base64 and will 15 | # require you to use the command below to decode it: 16 | # echo "encoded password" | base64 -D 17 | # 18 | # Before using this EA, you must replace the path to the log file with 19 | # the one used in the Encrypted Volume Password script 20 | # 21 | ########### ISSUES / USAGE ############################################# 22 | # If you have any issues or questions please feel free to contact 23 | # using the information in the header of this attribute 24 | # 25 | # Also, Please give me credit and let me know if you are going to use 26 | # this script. I would love to know how it works out and if you find 27 | # it helpful. 28 | ######################################################################## 29 | 30 | # Pulls the passphrase from the log created during encryption 31 | getPassphrase=`cat /path/to/log.file` 32 | 33 | if [[ -z "$getPassphrase" ]]; 34 | then 35 | echo "N/A" 36 | else 37 | echo "$getPassphrase" 38 | fi -------------------------------------------------------------------------------- /Encrypt External Volume/README.md: -------------------------------------------------------------------------------- 1 | # Encrypt External Volume 2 | 3 | - File List 4 | 1. EncryptExternalVolume.sh 5 | 2. EA_EncryptExternalVolume.sh 6 | 7 | This repo contains a script *[EncryptExternalVolume.sh]* that can be used to encrypt an external volume. The script will make any changes 8 | that are needed to the partition map and then prompt the user to create a password for the external volume *(Current requirements for the 9 | password is 7 characters or longer, this can be changed and uses AppleScript to capture the input)*. The script will also allow the user 10 | to rename the external volume, erase it and re-encrypt it again, or change the password *(NOTE: The user must know the current volume 11 | password in order for this function to work)*. 12 | 13 | The script also has a section that will encode the passcode and upload it to the JSS to be used in the future if the user forgets their 14 | password or access to the external volume is needed. **Note: This feature requires an Extension Attribute to be created in the JSS in order 15 | for the password to be accessible inside the JSS** 16 | -------------------------------------------------------------------------------- /Filevault Setup Script/README.md: -------------------------------------------------------------------------------- 1 | This script was created for computers bound to Active Directory using the Centrify Client. It is based off various jamf pro policies that will be explained more in the script notes. 2 | -------------------------------------------------------------------------------- /Homebrew/Extension Attributes/Homebrew_EA.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #################################################################################################### 4 | # 5 | # Copyright (c) 2022, JAMF Software, LLC. All rights reserved. 6 | # 7 | # Redistribution and use in source and binary forms, with or without 8 | # modification, are permitted provided that the following conditions are met: 9 | # * Redistributions of source code must retain the above copyright 10 | # notice, this list of conditions and the following disclaimer. 11 | # * Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # * Neither the name of the JAMF Software, LLC nor the 15 | # names of its contributors may be used to endorse or promote products 16 | # derived from this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY JAMF SOFTWARE, LLC "AS IS" AND ANY 19 | # EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL JAMF SOFTWARE, LLC BE LIABLE FOR ANY 22 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Author: Josh Harvey 30 | # Last Modified: 06/01/2022 31 | # Version: 0.1 32 | # 33 | # Description: This is an Extension Attribute that will display the version of Homebrew 34 | # if it's installed. If not, it will return "Not Installed". 35 | # 36 | # Usage: Extension Attribute in Jamf Pro 37 | # 38 | #################################################################################################### 39 | 40 | ################# VARIABLES ###################### 41 | ## currentUser: Grabs the username of the current logged in user **DO NOT CHANGE** 42 | currentUser=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ && ! /loginwindow/ { print $3 }') 43 | ################################################### 44 | 45 | ## Lets see what architecture the system is.. 46 | macOSArch=$(/usr/bin/uname -m) 47 | 48 | if [[ "$macOSArch" == "x86_64" ]]; then 49 | homebrewPath="/usr/local/bin/brew" 50 | elif [[ "$macOSArch" == "arm64" ]]; then 51 | homebrewPath="/opt/homebrew/bin/brew" 52 | fi 53 | 54 | homebrewVersion=$(su -l $currentUser -c "$homebrewPath -v") 55 | 56 | if [[ ! -z "$homebrewVersion" ]]; then 57 | echo "$homebrewVersion" 58 | else 59 | ## If Homebrew is not installed, this file will be empty, so lets change it to "Not Installed" so it's clear when looking at the EA 60 | echo "Not Installed" 61 | fi -------------------------------------------------------------------------------- /Homebrew/Extension Attributes/README.md: -------------------------------------------------------------------------------- 1 | # Extension Attributes 2 | 3 | - `Homebrew_EA.sh` 4 | - Displays the Homebrew version installed 5 | - `XcodeCLI_CA.sh` 6 | - Displays the Xcode Command Line Tools version installed -------------------------------------------------------------------------------- /Homebrew/Extension Attributes/XcodeCLI_EA.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #################################################################################################### 4 | # 5 | # Copyright (c) 2022, JAMF Software, LLC. All rights reserved. 6 | # 7 | # Redistribution and use in source and binary forms, with or without 8 | # modification, are permitted provided that the following conditions are met: 9 | # * Redistributions of source code must retain the above copyright 10 | # notice, this list of conditions and the following disclaimer. 11 | # * Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # * Neither the name of the JAMF Software, LLC nor the 15 | # names of its contributors may be used to endorse or promote products 16 | # derived from this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY JAMF SOFTWARE, LLC "AS IS" AND ANY 19 | # EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL JAMF SOFTWARE, LLC BE LIABLE FOR ANY 22 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Author: Josh Harvey 30 | # Last Modified: 06/01/2022 31 | # Version: 0.1 32 | # 33 | # Description: This is an Extension Attribute that will display the version of Xcode Command Line Tools 34 | # if it's installed. If not, it will return "Not Installed". 35 | # 36 | # Usage: Extension Attribute in Jamf Pro 37 | # 38 | #################################################################################################### 39 | 40 | xcodeCLIVersion=$(cat /Users/Shared/xcodecliversion) 41 | 42 | if [[ ! -z "$xcodeCLIVersion" ]]; then 43 | echo "$xcodeCLIVersion" 44 | else 45 | ## If Xcode CLI is not installed, this file will be empty, so lets change it to "Not Installed" so it's clear when looking at the EA 46 | echo "Not Installed" 47 | fi -------------------------------------------------------------------------------- /Homebrew/InstallHomebrew.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #################################################################################################### 4 | # 5 | # Copyright (c) 2022, JAMF Software, LLC. All rights reserved. 6 | # 7 | # Redistribution and use in source and binary forms, with or without 8 | # modification, are permitted provided that the following conditions are met: 9 | # * Redistributions of source code must retain the above copyright 10 | # notice, this list of conditions and the following disclaimer. 11 | # * Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # * Neither the name of the JAMF Software, LLC nor the 15 | # names of its contributors may be used to endorse or promote products 16 | # derived from this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY JAMF SOFTWARE, LLC "AS IS" AND ANY 19 | # EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL JAMF SOFTWARE, LLC BE LIABLE FOR ANY 22 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Author: Josh Harvey 30 | # Last Modified: 06/01/2022 31 | # Version: 0.1 32 | # 33 | # Description: This script will check to see if you have Xcode Command Line Tools installed 34 | # (it will install it if not found) then attempt to install Homebrew on your system. 35 | # 36 | #################################################################################################### 37 | 38 | ################# VARIABLES ###################### 39 | ## xcodeCLITrigger: The name of the trigger on the policy that installs Xcode Command Line Tools **REQUIRED** 40 | xcodeCLITrigger="$4" 41 | ## currentUser: Grabs the username of the current logged in user **DO NOT CHANGE** 42 | currentUser=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ && ! /loginwindow/ { print $3 }') 43 | ## installHomebrewLog: Location of the installHomebrew script log **DO NOT CHANGE** 44 | installHomebrewLog="/private/var/log/InstallHomebrew.log" 45 | ## homebrewLog: Location of the Homebrew log **DO NOT CHANGE** 46 | homebrewLog="/private/var/log/Homebrew.log" 47 | ## currentTime: Gets the time for the log **DO NOT CHANGE** 48 | currentTime=$(date +%H:%M) 49 | 50 | ### swiftDialog Variables 51 | dialogLogFile="/var/tmp/dialog.log" 52 | dialogPath="/usr/local/bin/dialog" 53 | dialogTitle="Homebrew Setup" 54 | dialogIcon="https://upload.wikimedia.org/wikipedia/commons/3/34/Homebrew_logo.png" 55 | theSteps=( 56 | "\"Install Xcode Command Line Tools\"" 57 | "\"Install Homebrew\"" 58 | "\"Install md5sha1sum (Homebrew)\"" 59 | "\"Apply Permissions\"" 60 | "\"Check for Updates\"" 61 | ) 62 | theStepsLength="${#theSteps[@]}" 63 | currentStep=0 64 | dialogConfig=( 65 | "--title \"$dialogTitle\"" 66 | "--icon \"$dialogIcon\"" 67 | "--position topleft" 68 | "--message \" \"" 69 | "--messagefont \"size=16\"" 70 | # "--small" 71 | "--ontop" 72 | "--moveable" 73 | # "--position centre" 74 | "${theSteps[@]/#/--listitem }" 75 | ) 76 | ################################################### 77 | 78 | ## Logging Function 79 | log_it () { 80 | if [[ ! -z "$1" && -z "$2" ]]; then 81 | logEvent="INFO" 82 | logMessage="$1" 83 | elif [[ "$1" == "warning" ]]; then 84 | logEvent="WARN" 85 | logMessage="$2" 86 | elif [[ "$1" == "success" ]]; then 87 | logEvent="SUCCESS" 88 | logMessage="$2" 89 | elif [[ "$1" == "error" ]]; then 90 | logEvent="ERROR" 91 | logMessage="$2" 92 | fi 93 | 94 | if [[ ! -z "$logEvent" ]]; then 95 | echo ">>[InstallHomebrew.sh] :: $logEvent [$(date +%H:%M)] :: $logMessage" 96 | echo ">>[InstallHomebrew.sh] :: $logEvent [$(date +%H:%M)] :: $logMessage" >> "$installHomebrewLog" 97 | fi 98 | } 99 | 100 | update_dialog () { 101 | log_it "DIALOG: $1" 102 | echo "$1" >> "$dialogLogFile" 103 | } 104 | 105 | finish_dialog () { 106 | update_dialog "progresstext: Homebrew Setup Complete" 107 | sleep 1 108 | update_dialog "quit:" 109 | exit 0 110 | } 111 | 112 | if [[ -z "$xcodeCLITrigger" ]]; then 113 | log_it "error" "Missing Xcode Command Line Tools Trigger in Script Parameter #4." 114 | exit 1 115 | fi 116 | 117 | rm "$dialogLogFile" 118 | eval "$dialogPath" "${dialogConfig[*]}" & sleep 1 119 | 120 | for (( i=0; i "/Users/Shared/xcodecliversion" 143 | fi 144 | else 145 | log_it "Xcode Command Line Tools are not installed.. Lets install them now!" 146 | update_dialog "listitem: index: $((currentStep)), status: wait" 147 | /usr/local/bin/jamf policy -event $xcodeCLITrigger 148 | xcodeCLIVersion=$(pkgutil --pkg-info=com.apple.pkg.CLTools_Executables | grep "version:" | sed 's/[version: ]//g') 149 | if [[ ! -z "$xcodeCLIVersion" ]]; then 150 | log_it "success" "Xcode Command Line Tools (Version: $xcodeCLIVersion) was successfully installed." 151 | update_dialog "listitem: index: $((currentStep++)), status: success" 152 | echo "$xcodeCLIVersion" > "/Users/Shared/xcodecliversion" 153 | xcodeCLI="Installed" 154 | else 155 | xcodeCLI="Missing" 156 | fi 157 | fi 158 | 159 | ## User Group Check 160 | devGroupCheck=$(groups "$currentUser" | grep -o '_developer') 161 | if [[ -z "$devGroupCheck" ]]; then 162 | /usr/sbin/dseditgroup -o edit -a "$currentUser" -t user _developer 163 | log_it "success" "Added $currentUser to the _developer group." 164 | else 165 | log_it "$currentUser is already a member of the _developer group." 166 | fi 167 | } 168 | 169 | 170 | install_homebrew () { 171 | update_dialog "listitem: index: $((currentStep)), status: wait" 172 | ## Lets see what architecture the system is.. 173 | macOSArch=$(/usr/bin/uname -m) 174 | 175 | if [[ "$macOSArch" == "x86_64" ]]; then 176 | log_it "System Architecture: Intel (64-Bit)" 177 | homebrewPath="/usr/local/bin/brew" 178 | homebrewDir="/usr/local/Homebrew" 179 | # log_it "Setting Homebrew Directory to: $homebrewDir" 180 | elif [[ "$macOSArch" == "arm64" ]]; then 181 | log_it "System Architecture: Apple Silicon 64-Bit" 182 | homebrewPath="/opt/homebrew/bin/brew" 183 | homebrewDir="/opt/homebrew" 184 | # log_it "Setting Homebrew Directory to: $homebrewDir" 185 | fi 186 | 187 | 188 | if [[ ! -e "$homebrewPath" ]]; then 189 | log_it "Starting Homebrew installation.." 190 | 191 | mkdir -p "$homebrewDir" 192 | ## Curl down the latest tarball and install to "$homebrewDir" 193 | curl -L https://github.com/Homebrew/brew/tarball/master | tar xz --strip 1 -C $homebrewDir && log_it "Homebrew downloaded successfully." 194 | 195 | if [[ ! -e $homebrewDir ]]; then 196 | log_it "error" "Homebrew failed to download." 197 | exit 1 198 | fi 199 | 200 | ## Manually make all the appropriate directories and set permissions 201 | log_it "Creating Homebrew directories and setting permissions for user $currentUser" 202 | 203 | if [[ "$macOSArch" == "x86_64" ]]; then 204 | log_it "System Architecture: Intel (64-Bit)" 205 | mkdir -p /usr/local/Cellar /usr/local/Homebrew mkdir /usr/local/Caskroom /usr/local/Frameworks /usr/local/bin 206 | mkdir -p /usr/local/include /usr/local/lib /usr/local/opt /usr/local/etc /usr/local/sbin 207 | mkdir -p /usr/local/share/zsh/site-functions /usr/local/var 208 | mkdir -p /usr/local/share/doc /usr/local/man/man1 /usr/local/share/man/man1 209 | chown -R "$currentUser:_developer" /usr/local/* 210 | chmod -R g+rwx /usr/local/* 211 | chmod 755 /usr/local/share/zsh /usr/local/share/zsh/site-functions 212 | ln -s /usr/local/Homebrew/bin/brew /usr/local/bin/brew 213 | elif [[ "$macOSArch" == "arm64" ]]; then 214 | log_it "System Architecture: Apple Silicon 64-Bit" 215 | mkdir -p /opt/homebrew/Cellar mkdir /opt/homebrew/Caskroom /opt/homebrew/Frameworks /opt/homebrew/bin 216 | mkdir -p /opt/homebrew/include /opt/homebrew/lib /opt/homebrew/opt /opt/homebrew/etc /opt/homebrew/sbin 217 | mkdir -p /opt/homebrew/share/zsh/site-functions /opt/homebrew/var 218 | mkdir -p /opt/homebrew/share/doc /opt/homebrew/man/man1 /opt/homebrew/share/man/man1 219 | chown -R "$currentUser:_developer" /opt/homebrew 220 | echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zshrc 221 | eval "$(/opt/homebrew/bin/brew shellenv)" 222 | fi 223 | 224 | update_dialog "listitem: index: $((currentStep++)), status: success" 225 | 226 | log_it "Creating system wide cache folder." 227 | # Create a system wide cache folder 228 | mkdir -p /Library/Caches/Homebrew 229 | chmod g+rwx /Library/Caches/Homebrew 230 | chown "$currentUser:_developer" /Library/Caches/Homebrew 231 | 232 | log_it "Installing the MD5 Checker for Homebrew." 233 | update_dialog "listitem: index: $((currentStep)), status: wait" 234 | # Install the MD5 checker or the recipes will fail 235 | su -l "$currentUser" -c "$homebrewPath install md5sha1sum" 236 | echo 'export PATH="/usr/local/opt/openssl/bin:$PATH"' | 237 | tee -a /Users/"$currentUser"/.bash_profile /Users/"$currentUser"/.zshrc 238 | chown "$currentUser" /Users/"$currentUser"/.bash_profile /Users/"$currentUser"/.zshrc 239 | update_dialog "listitem: index: $((currentStep++)), status: success" 240 | 241 | log_it "Setting permissions." 242 | update_dialog "listitem: index: $((currentStep)), status: wait" 243 | # Fix the permissions 244 | chown -R root:wheel /private/tmp 245 | chmod 777 /private/tmp 246 | chmod +t /private/tmp 247 | update_dialog "listitem: index: $((currentStep++)), status: success" 248 | 249 | log_it "success" "Homebrew was successfully installed! Lets double check there aren't any updates available!" 250 | update_dialog "listitem: index: $((currentStep)), status: wait" 251 | su -l "$currentUser" -c "$homebrewPath update" 2>&1 | tee -a "$homebrewLog" 252 | update_dialog "listitem: index: $((currentStep++)), status: success" 253 | else 254 | log_it "success" "Homebrew is already installed. Checking for any updates now.." 255 | update_dialog "listitem: index: $((currentStep++)), status: success" 256 | update_dialog "listitem: index: $((currentStep++)), status: success" 257 | update_dialog "listitem: index: $((currentStep++)), status: success" 258 | update_dialog "listitem: index: $((currentStep++)), status: success" 259 | update_dialog "listitem: index: $((currentStep)), status: wait" 260 | su -l "$currentUser" -c "$homebrewPath update" 2>&1 | tee -a "$homebrewLog" 261 | update_dialog "listitem: index: $((currentStep++)), status: success" 262 | fi 263 | } 264 | 265 | if [[ -z "$xcodeCLITrigger" ]]; then 266 | log_it "error" "The xcodeCLITrigger variable is empty. Make sure you put the trigger of the policy that's installing Xcode Command Line Tools in the xcodeCLITrigger variable on Line 42, then try running the script again." 267 | exit 1 268 | else 269 | log_it "Starting the requirements check to see if Xcode CLI is installed and $currentUser is a member of the correct group." 270 | requirements_check 271 | if [[ "$xcodeCLI" == "Installed" ]]; then 272 | install_homebrew 273 | finish_dialog 274 | else 275 | log_it "error" "Unable to install Homebrew due to Xcode Command Line Tools not being found. Please verify that Xcode Command Line Tools is installed then try running this script again." 276 | update_dialog "listitem: index: $((currentStep++)), status: fail" 277 | update_dialog "listitem: index: $((currentStep++)), status: fail" 278 | update_dialog "listitem: index: $((currentStep++)), status: fail" 279 | update_dialog "listitem: index: $((currentStep++)), status: fail" 280 | update_dialog "listitem: index: $((currentStep++)), status: fail" 281 | exit 1 282 | fi 283 | fi 284 | 285 | -------------------------------------------------------------------------------- /Homebrew/InstallHomebrewPackages.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #################################################################################################### 4 | # 5 | # Copyright (c) 2022, JAMF Software, LLC. All rights reserved. 6 | # 7 | # Redistribution and use in source and binary forms, with or without 8 | # modification, are permitted provided that the following conditions are met: 9 | # * Redistributions of source code must retain the above copyright 10 | # notice, this list of conditions and the following disclaimer. 11 | # * Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # * Neither the name of the JAMF Software, LLC nor the 15 | # names of its contributors may be used to endorse or promote products 16 | # derived from this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY JAMF SOFTWARE, LLC "AS IS" AND ANY 19 | # EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL JAMF SOFTWARE, LLC BE LIABLE FOR ANY 22 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Author: Josh Harvey 30 | # Last Modified: 06/02/2022 31 | # Version: 0.1 32 | # 33 | # Description: This script will verify that Homebrew is installed and then installs any Homebrew 34 | # Packages that you need for your environment. 35 | # 36 | #################################################################################################### 37 | 38 | ################# VARIABLES ###################### 39 | ## homebrewPackages: The list of packages you want to install via Homebrew, seperated by commas **REQUIRED** 40 | homebrewPackages="$4" 41 | ## currentUser: Grabs the username of the current logged in user **DO NOT CHANGE** 42 | currentUser=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ && ! /loginwindow/ { print $3 }') 43 | ## InstallHomebrewPackages: Location of the InstallHomebrewPackages script log **DO NOT CHANGE** 44 | InstallHomebrewPackages="/private/var/log/InstallHomebrewPackages.log" 45 | ## homebrewLog: Location of the Homebrew log **DO NOT CHANGE** 46 | homebrewLog="/private/var/log/Homebrew.log" 47 | ## currentTime: Gets the time for the log **DO NOT CHANGE** 48 | currentTime=$(date +%H:%M) 49 | 50 | ### swiftDialog Variables 51 | dialogLogFile="/var/tmp/dialog.log" 52 | dialogPath="/usr/local/bin/dialog" 53 | dialogTitle="Homebrew Package Installs" 54 | dialogIcon="https://upload.wikimedia.org/wikipedia/commons/3/34/Homebrew_logo.png" 55 | declare -a theSteps 56 | theSteps=( 57 | "\"Getting List of Packages\"" 58 | ) 59 | 60 | for s in ${homebrewPackages//,/ }; do 61 | echo "$s" 62 | theSteps+=("\"$s\"") 63 | done 64 | 65 | theStepsLength="${#theSteps[@]}" 66 | currentStep=0 67 | dialogConfig=( 68 | "--title \"$dialogTitle\"" 69 | "--icon \"$dialogIcon\"" 70 | "--position topleft" 71 | "--message \" \"" 72 | "--messagefont \"size=16\"" 73 | # "--small" 74 | "--ontop" 75 | "--moveable" 76 | # "--position centre" 77 | "${theSteps[@]/#/--listitem }" 78 | ) 79 | ################################################### 80 | 81 | ## Logging Function 82 | log_it () { 83 | if [[ ! -z "$1" && -z "$2" ]]; then 84 | logEvent="INFO" 85 | logMessage="$1" 86 | elif [[ "$1" == "warning" ]]; then 87 | logEvent="WARN" 88 | logMessage="$2" 89 | elif [[ "$1" == "success" ]]; then 90 | logEvent="SUCCESS" 91 | logMessage="$2" 92 | elif [[ "$1" == "error" ]]; then 93 | logEvent="ERROR" 94 | logMessage="$2" 95 | fi 96 | 97 | if [[ ! -z "$logEvent" ]]; then 98 | echo ">>[InstallHomebrewPackages.sh] :: $logEvent [$(date +%H:%M)] :: $logMessage" 99 | echo ">>[InstallHomebrewPackages.sh] :: $logEvent [$(date +%H:%M)] :: $logMessage" >> "$InstallHomebrewPackages" 100 | fi 101 | } 102 | 103 | update_dialog () { 104 | log_it "DIALOG: $1" 105 | echo "$1" >> "$dialogLogFile" 106 | } 107 | 108 | finish_dialog () { 109 | update_dialog "progresstext: Homebrew Package Installs Complete" 110 | sleep 1 111 | update_dialog "quit:" 112 | exit 0 113 | } 114 | 115 | rm "$dialogLogFile" 116 | eval "$dialogPath" "${dialogConfig[*]}" & sleep 1 117 | 118 | for (( i=0; i&1 | tee -a "$homebrewLog" 160 | # update_dialog "listitem: title: \"Updating Homebrew\", status: success" 161 | fi 162 | } 163 | 164 | install_packages () { 165 | # brew_packages="jq,wget,git,python,mint,carthage,watchman,chargepoint/xcparse/xcparse,danger/tap/danger-swift,nvm,saucectl" 166 | 167 | for p in ${brew_packages//,/ }; do 168 | log_it "Installing $p.." 169 | update_dialog "listitem: title: $p, status: wait" 170 | su -l "$currentUser" -c "$homebrewPath install $p" 2>&1 | tee -a "$homebrewLog" 171 | checkInstall=$(su -l "$currentUser" -c "$homebrewPath list $p" | grep "Error:") 172 | if [[ -z "$checkInstall" ]]; then 173 | log_it "success" "$p was installed successfully." 174 | update_dialog "listitem: title: $p, status: success" 175 | else 176 | log_it "error" "$p was unable to be installed. View Homebrew.log for details." 177 | update_dialog "listitem: title: $p, status: error" 178 | fi 179 | done 180 | } 181 | 182 | homebrew_check 183 | install_packages 184 | finish_dialog -------------------------------------------------------------------------------- /Homebrew/README.md: -------------------------------------------------------------------------------- 1 | # Homebrew 2 | 3 | > This repository also contains Extension Attributes that can be used to help scope and return the Homebrew and Xcode Command Line Tools versions. Those can be found within the **Extension Attributes** folder. 4 | 5 | ## `InstallHomebrew.sh` 6 | 7 | An easy way to install Homebrew on macOS systems via Jamf Pro. 8 | 9 | ---- 10 | ## Requirements 11 | - Xcode Command Line Tools Package uploaded to Jamf Pro 12 | - *Requires a free Developer Account for [developer.apple.com](https://developer.apple.com)* 13 | - A policy in Jamf Pro to install XcodeCLI with a custom trigger 14 | - [swiftDialog](https://github.com/bartreardon/swiftDialog) installed. 15 | - **Note:** This script will download and install swiftDialog if it's not found. 16 | 17 | ---- 18 | ## Setup 19 | 1. Add script to Jamf Pro Server 20 | 1. Create a new policy and add the `InstallHomebrew.sh` script 21 | 1. Enter the custom trigger for the Install Xcode Command Line Tools Policy in Script Parameter #4 22 | 23 | > Be sure to set the trigger and scope correctly. This will vary based on how you want to deploy it. 24 | 25 | ---- 26 | ## Logging 27 | This script creates the following log files: 28 | - `/private/var/log/InstallHomebrew.log` 29 | - This is the logfile for the `InstallHomebrew` script. 30 | - `/private/var/log/Homebrew.log` 31 | - This is the logfile for when the script updates Homebrew. 32 | - `/Users/Shared/xcodecliversion` 33 | - This is the logfile that contains the Xcode Command Line Tools version 34 | 35 | ---- 36 | 37 | ## `InstallHomebrewPackages.sh` 38 | 39 | An easy way to install Homebrew Packages on macOS systems via Jamf Pro 40 | 41 | ---- 42 | ## Requirements 43 | - [swiftDialog](https://github.com/bartreardon/swiftDialog) installed. 44 | - **Note:** This script will download and install swiftDialog if it's not found. 45 | 46 | ---- 47 | ## Setup 48 | 1. Add script to Jamf Pro Server 49 | 1. Create a new policy and add the `InstallHomebrewPackages.sh` script 50 | 1. Enter the list of Homebrew Packages to install in Script Parameter #4 as a Comma Seperated List 51 | - **Example:** `jq,wget,git,python,mint,carthage` 52 | 53 | > Be sure to set the trigger and scope correctly. This will vary based on how you want to deploy it. 54 | 55 | ---- 56 | ## Logging 57 | This script creates the following log files: 58 | - `/private/var/log/InstallHomebrewPackages.log` 59 | - This is the logfile for the `InstallHomebrewPackages` script. 60 | - `/private/var/log/Homebrew.log` 61 | - This is the logfile for when the script updates Homebrew. -------------------------------------------------------------------------------- /Install Python Packages/README.md: -------------------------------------------------------------------------------- 1 | # installPythonPackages.py 2 | 3 | An easy way to install python3 packages on macOS systems via Jamf Pro. 4 | 5 | ---- 6 | ## Requirements 7 | - Python3 *(Tested with 3.9.13)* 8 | - List of packages as a Comma Seperated List in Script Parameter #4 9 | 10 | ---- 11 | ## Setup 12 | 1. Add script to Jamf Pro Server 13 | 1. Create a new policy and add the `installPythonPackages.py` script 14 | 1. Enter the list of python3 packages to install in Script Parameter #4 as a Comma Seperated List 15 | - **Example:** `requests, virtualenv, slack_sdk, tinydb` 16 | 17 | > Be sure to set the trigger and scope correctly. This will vary based on how you want to deploy it. 18 | 19 | ---- 20 | ## Logging 21 | This script creates a log file at `/private/var/log/installPythonPackages.log` 22 | -------------------------------------------------------------------------------- /Install Python Packages/installPythonPackages.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | #################################################################################################### 4 | # 5 | # Copyright (c) 2022, JAMF Software, LLC. All rights reserved. 6 | # 7 | # Redistribution and use in source and binary forms, with or without 8 | # modification, are permitted provided that the following conditions are met: 9 | # * Redistributions of source code must retain the above copyright 10 | # notice, this list of conditions and the following disclaimer. 11 | # * Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # * Neither the name of the JAMF Software, LLC nor the 15 | # names of its contributors may be used to endorse or promote products 16 | # derived from this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY JAMF SOFTWARE, LLC "AS IS" AND ANY 19 | # EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL JAMF SOFTWARE, LLC BE LIABLE FOR ANY 22 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Author: Josh Harvey 30 | # Github: https://github.com/therealmacjeezy 31 | # Last Modified: 06/07/2022 32 | # Version: 0.1 33 | # 34 | # Description: This script will update pip3 then bulk install pip3 packages using 35 | # Jamf Pro Script Parameters 36 | # 37 | #################################################################################################### 38 | 39 | import logging, sys, subprocess, os 40 | 41 | ################# VARIABLES ###################### 42 | findUser = os.popen('stat -f %Su /dev/console') 43 | currentUser = findUser.read() 44 | currentUser = currentUser.strip() 45 | ################################################### 46 | 47 | logging.basicConfig( 48 | ## Logging Levels: DEBUG, INFO, WARNING, ERROR, CRITICAL 49 | ## Usage: logging.LEVEL('message') 50 | filename = '/private/var/log/installPythonPackages.log', 51 | level = logging.DEBUG, 52 | format = '>>[%(filename)s] :: %(levelname)s [%(asctime)s] :: %(message)s' 53 | ) 54 | 55 | logging.info(f'Starting script as user {currentUser}') 56 | 57 | ## Check to see if Script Parameter #4 contains the list of python3 packages to install, if not exit. 58 | if sys.argv[4]: 59 | logging.info('Found python3 packages to install.') 60 | packages = sys.argv[4] 61 | packages = packages.split(',') 62 | else: 63 | logging.error('Missing list of python3 packages to install. Check Script Parameter #4.') 64 | sys.exit(1) 65 | 66 | ## Function to install the python3 package 67 | def install(package): 68 | try: 69 | # __import__(package) 70 | os.system(f"su -l {currentUser} -c \"/usr/local/bin/python3 -c 'import {package}'\"") 71 | logging.info(f'{package} is already installed! Lets make sure it is up to date!') 72 | try: 73 | # subprocess.check_call([sys.executable, "-m", "pip", "-q", "-q", "install", "--upgrade", package]) 74 | subprocess.run(["su", "-l", currentUser, "-c", f"/usr/local/bin/python3 -m pip -q -q install --upgrade {package} --user"]) 75 | logging.info(f'{package} is up to date.') 76 | except Exception as errorMessage: 77 | logging.error(errorMessage) 78 | except: 79 | logging.info(f'Looks like {package} isnt installed..installing now') 80 | try: 81 | subprocess.run(["su", "-l", currentUser, "-c", f"/usr/local/bin/python3 -m pip -q -q install {package} --user"]) 82 | # subprocess.check_call([sys.executable, "-m", "pip", "-q", "-q", "install", package]) 83 | logging.info(f'Successfully installed {package}!') 84 | except Exception as errorMessage: 85 | logging.error(errorMessage) 86 | 87 | 88 | 89 | ## Check to see if pip3 is up to date and if not, install the latest version 90 | try: 91 | logging.info('Making sure pip3 is up to date.') 92 | # subprocess.check_call([sys.executable, "-m", "pip", "-q", "-q", "install", "--upgrade", "pip"]) 93 | subprocess.run(["su", "-l", currentUser, "-c", f"/usr/local/bin/python3 -m pip -q -q install --upgrade pip"]) 94 | logging.info('pip3 update check complete.') 95 | except Exception as errorMessage: 96 | logging.error(errorMessage) 97 | 98 | ## Start the package installs 99 | for p in packages: 100 | p = p.strip() 101 | logging.info(f'Checking to see if {p} is installed..') 102 | install(p) 103 | 104 | -------------------------------------------------------------------------------- /LAPS for Mac/Display Local Admin Password - Self Service.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ################################################# 4 | # Display Local Admin Password - Self Service 5 | # Joshua Harvey | February 2019 6 | # josh[at]macjeezy.com 7 | # GitHub - github.com/therealmacjeezy 8 | # JAMFnation - therealmacjeezy 9 | ################################################# 10 | 11 | #### NOTES ###################################### 12 | ############ Script Parameters Info ############# 13 | ## 4 - API Username String (Required) 14 | ## 5 - API Password String (Required) 15 | ################################################# 16 | 17 | # Decrypt String 18 | DecryptString() { 19 | # Usage: ~$ DecryptString "Encrypted String" "Salt" "Passphrase" 20 | echo "${1}" | /usr/bin/openssl enc -aes256 -d -a -A -S "${2}" -k "${3}" 21 | } 22 | 23 | # Account Information 24 | if [[ -z "$4" ]]; then 25 | echo "Error: API USER MISSING" 26 | exit 1 27 | else 28 | apiUser=$(DecryptString "$4" '' '') 29 | fi 30 | 31 | if [[ -z "$5" ]]; then 32 | echo "Error: API PASS MISSING" 33 | exit 1 34 | else 35 | apiPass=$(DecryptString "$5" '' '') 36 | fi 37 | 38 | # Script Variables 39 | jssURL="https://your.jamf.pro/" 40 | currUser=$(scutil <<< "show State:/Users/ConsoleUser" | awk -F': ' '/[[:space:]]+Name[[:space:]]:/ { if ( $2 != "loginwindow" ) { print $2 }} ') 41 | currUserUID=$(id -u "$currUser") 42 | udid=$(/usr/sbin/system_profiler SPHardwareDataType | /usr/bin/awk '/Hardware UUID:/ { print $3 }') 43 | 44 | # ID of the EA that is storing the password from the LAPS policy 45 | EAID=60 46 | xml=$(curl -s -u $apiUser:$apiPass -H "Accept: application/xml" $jssURL/JSSResource/computers/udid/$udid/subset/extension_attributes | xpath "//*[id=$EAID]/value/text()" 2>&1) 47 | lapsPass=$(echo $xml | awk '{print $7}') 48 | 49 | # Checks the lapsPass variable to see if the EA contains the local admin password, if not displays the message stating the password is not stored in the EA then exits 50 | if [[ -z "$lapsPass" ]]; then 51 | lapsPass="Unable to find password in jamf." 52 | lapsError=$( 53 | /bin/launchctl asuser "$currUserUID" sudo -iu "$currUser" /usr/bin/osascript <\"" 17 | newPass=$(env LC_CTYPE=C tr -dc "A-Za-z0-9#$^_+=" < /dev/urandom | head -c 12 > /tmp/pwlaps) 18 | getPass=$(cat /tmp/pwlaps) 19 | 20 | # Decrypt String 21 | DecryptString() { 22 | # Usage: ~$ DecryptString "Encrypted String" "Salt" "Passphrase" 23 | echo "${1}" | /usr/bin/openssl enc -aes256 -d -a -A -S "${2}" -k "${3}" 24 | } 25 | 26 | # Account Information 27 | if [[ -z "$4" ]]; then 28 | echo "Error: API USER MISSING" 29 | exit 1 30 | else 31 | apiUser=$(DecryptString "$4" '' '') 32 | fi 33 | 34 | if [[ -z "$5" ]]; then 35 | echo "Error: API PASS MISSING" 36 | exit 1 37 | else 38 | apiPass=$(DecryptString "$5" '' '') 39 | fi 40 | 41 | if [[ -z "$6" ]]; then 42 | echo "ERROR: ADMIN NAME MISSING" 43 | exit 1 44 | else 45 | adminUser="$6" 46 | fi 47 | 48 | # Verify local admin 49 | checkUser=$(dseditgroup -o checkmember -m $adminUser localaccounts | awk '{ print $1 }') 50 | 51 | if [[ "$checkUser" = "yes" ]];then 52 | echo "$adminUser is a local user" 53 | else 54 | echo "ERROR: $adminUser is not a local user! :( Exiting." 55 | exit 1 56 | fi 57 | 58 | # Magic Below 59 | passwordCheck() { 60 | passCheck=$(/usr/bin/dscl /Local/Default -authonly "$adminUser" "$oldPass") 61 | if [[ -z "$passCheck" ]]; then 62 | echo "Continue" 63 | else 64 | echo "ERROR: Password is either old or unknown, checking EA" 65 | oldPass=$(curl -s -f -u $apiUser:$apiPass -H "Accept: application/xml" $jssURL/JSSResource/computers/udid/$udid/subset/extension_attributes | xpath "//extension_attribute[name=$extAttName]" 2>&1 | awk -F'|' '{print $2}' | tail -1) 66 | passCheck2=$(/usr/bin/dscl /Local/Default -authonly "$adminUser" "$oldPass") 67 | if [[ ! -z "$passCheck2" ]]; then 68 | echo "ERROR: Password is unknown. Exiting" 69 | exit 1 70 | fi 71 | fi 72 | } 73 | 74 | if [[ ! -z "$7" ]]; then 75 | echo "$7" 76 | oldPass="$7" 77 | passwordCheck 78 | else 79 | oldPass=$(curl -s -f -u $apiUser:$apiPass -H "Accept: application/xml" $jssURL/JSSResource/computers/udid/$udid/subset/extension_attributes | xpath "//extension_attribute[name=$extAttName]" 2>&1 | awk -F'|' '{print $2}') 80 | passwordCheck 81 | fi 82 | 83 | genLAPS() { 84 | /usr/sbin/sysadminctl -adminUser $adminUser -adminPassword $oldPass -resetPasswordFor $adminUser -newPassword $getPass 85 | } 86 | 87 | resetCheck() { 88 | /usr/bin/dscl /Local/Default -authonly "$adminUser" "$getPass" 89 | echo "New Password works as: $getPass" 90 | } 91 | 92 | setEAStatus() { 93 | 94 | curl -s -u $apiUser:"$apiPass" -X "PUT" "$jssURL/JSSResource/computers/udid/$udid/subset/extension_attributes" \ 95 | -H "Content-Type: application/xml" \ 96 | -H "Accept: application/xml" \ 97 | -d "testLAPSStringText Field$getPass" \ 98 | 2>&1 > /dev/null 99 | 100 | rm -f /tmp/pwlaps 101 | } 102 | 103 | genLAPS 104 | resetCheck 105 | setEAStatus 106 | -------------------------------------------------------------------------------- /LAPS for Mac/README.md: -------------------------------------------------------------------------------- 1 | ## LAPS for macOS 2 | 3 | #### This script will randomize the Local Administrator account password. It uses an Extension Attribute to store the randomized password and script parameters to store the following items: 4 | - API Username 5 | - API Password 6 | - Local Administrator Username 7 | - Local Administrator Password *(Used when the script is ran for the first time)* 8 | 9 | #### Requirements 10 | - Extension Attribute 11 | Used to store the randomized password 12 | - Policy 13 | Used to run the script and store the variables 14 | 15 | ## Display Local Admin Password - Self Service Policy 16 | 17 | #### Allows the Local Admin Password to be displayed through a Self Service policy. 18 | This script pulls the LAPS for macOS EA for the computer it is being run on and if found, displays it via an AppleScript prompt. There is also an option to copy the password from the AppleScript prompt. 19 | 20 | If the EA doesn't contain the password, another AppleScript prompt will appear stating that it is unable to find the password in jamf and will exit 21 | -------------------------------------------------------------------------------- /Microsoft Office Update Scripts/Office_2016_Updater.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ################################################# 4 | # Microsoft AutoUpdate Script 5 | # Office 2016 6 | # Joshua Harvey | November 2018 7 | # Updated: December 2018 8 | # josh[at]macjeezy.com 9 | # GitHub - github.com/therealmacjeezy 10 | # JAMFnation - therealmacjeezy 11 | ################################################# 12 | 13 | ############ Script Parameters Info ############# 14 | ## 4 - Word Version (16.16.xxxxxxxx) 15 | ## 5 - Excel Version (16.16.xxxxxxxx) 16 | ## 6 - PowerPoint Version (16.16.xxxxxxxx) 17 | ## 7 - Outlook Version (16.16.xxxxxxxx) 18 | ## 8 - OneNote Version (16.16.xxxxxxxx) 19 | ## 20 | ## If a Parameter is left blank, the script will 21 | ## output "Missing Version" and move on 22 | ## to the next app. Each time this script is run, 23 | ## it will always check and install (if available) 24 | ## updates for Skype for Business, MAU and Remote 25 | ## Desktop since they are the same for both versions. 26 | ################################################# 27 | 28 | ## 12-20-18 - Resolved Issues 29 | # Added a version check for msupdate at the beginning of the script. This resolves the issue where the script was throwing an error and exiting prior to updating the apps. The cause of the issue was msupdate not being on the latest version. msupdate updates override any updates that are avaiable for the other applications. 30 | 31 | # Function that gets called to look for any updates that are avaiable for the Microsoft Office applications 32 | updateCheck() { 33 | versionCheck=$(/Library/Application\ Support/Microsoft/MAU2.0/Microsoft\ AutoUpdate.app/Contents/MacOS/msupdate -l | grep "No updates available") 34 | 35 | # Uses the above variable that checks for any avaiable updates and exits the script if no updates are found 36 | if [[ "$versionCheck" == "No updates available" ]]; then 37 | echo "All Microsoft Office applications are up to date. Exiting" 38 | exit 0 39 | else 40 | echo "Microsoft Office updates found.. starting updates.." 41 | fi 42 | } 43 | 44 | # Checks to see if Microsoft AutoUpdate is on the latest version and updates it if not, if already on the latest version it will continue on and use the above function to look for additonal updates. 45 | if [[ ! -z `/Library/Application\ Support/Microsoft/MAU2.0/Microsoft\ AutoUpdate.app/Contents/MacOS/msupdate -l | grep "MSau03"` ]]; then 46 | echo "Microsoft AutoUpdate requires an update before continuing. Starting Update." 47 | /Library/Application\ Support/Microsoft/MAU2.0/Microsoft\ AutoUpdate.app/Contents/MacOS/msupdate -i -a msau03 48 | echo "Microsoft AutoUpdate has been updated. Looking for additional updates.." 49 | updateCheck 50 | else 51 | echo "Microsoft AutoUpdate is up to date. Checking for any additional available application updates.." 52 | updateCheck 53 | fi 54 | 55 | # Script Parameters to apply version control with updates 56 | # Word 57 | if [[ ! -z "$4" ]]; then 58 | /Library/Application\ Support/Microsoft/MAU2.0/Microsoft\ AutoUpdate.app/Contents/MacOS/msupdate -i -a mswd15 -v "$4" 59 | else 60 | echo "Missing Word Version" 61 | fi 62 | 63 | # Excel 64 | if [[ ! -z "$5" ]]; then 65 | /Library/Application\ Support/Microsoft/MAU2.0/Microsoft\ AutoUpdate.app/Contents/MacOS/msupdate -i -a xcel15 -v "$5" 66 | else 67 | echo "Missing Excel Version" 68 | fi 69 | 70 | # PowerPoint 71 | if [[ ! -z "$6" ]]; then 72 | /Library/Application\ Support/Microsoft/MAU2.0/Microsoft\ AutoUpdate.app/Contents/MacOS/msupdate -i -a ppt315 -v "$6" 73 | else 74 | echo "Missing PowerPoint Version" 75 | fi 76 | 77 | # Outlook 78 | if [[ ! -z "$7" ]]; then 79 | /Library/Application\ Support/Microsoft/MAU2.0/Microsoft\ AutoUpdate.app/Contents/MacOS/msupdate -i -a opim15 -v "$7" 80 | else 81 | echo "Missing Outlook Version" 82 | fi 83 | 84 | # OneNote 85 | if [[ ! -z "$8" ]]; then 86 | /Library/Application\ Support/Microsoft/MAU2.0/Microsoft\ AutoUpdate.app/Contents/MacOS/msupdate -i -a onmc15 -v "$8" 87 | else 88 | echo "Missing OneNote Version" 89 | fi 90 | 91 | # Skype for Business and Remote Desktop 92 | # Uses the same version for both 2019 and 2016 so adding them to the update each time 93 | /Library/Application\ Support/Microsoft/MAU2.0/Microsoft\ AutoUpdate.app/Contents/MacOS/msupdate -i -a msfb16 msrd10 94 | 95 | exit 0 96 | -------------------------------------------------------------------------------- /Microsoft Office Update Scripts/Office_2019-O365_Updater.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ################################################# 4 | # Microsoft AutoUpdate Script 5 | # Office 2019/O365 6 | # Joshua Harvey | November 2018 7 | # Updated: December 2018 8 | # josh[at]macjeezy.com 9 | # GitHub - github.com/therealmacjeezy 10 | # JAMFnation - therealmacjeezy 11 | ################################################# 12 | 13 | ############ Script Parameters Info ############# 14 | ## 4 - Word Version (16.19.xxxxxxxx) 15 | ## 5 - Excel Version (16.19.xxxxxxxx) 16 | ## 6 - PowerPoint Version (16.19.xxxxxxxx) 17 | ## 7 - Outlook Version (16.19.xxxxxxxx) 18 | ## 8 - OneNote Version (16.19.xxxxxxxx) 19 | ## 20 | ## If a Parameter is left blank, the script will 21 | ## output "Missing Version" and move on 22 | ## to the next app. Each time this script is run, 23 | ## it will always check and install (if available) 24 | ## updates for Skype for Business, MAU and Remote 25 | ## Desktop since they are the same for both versions. 26 | ################################################# 27 | 28 | ## 12-20-18 - Resolved Issues 29 | # Added a version check for msupdate at the beginning of the script. This resolves the issue where the script was throwing an error and exiting prior to updating the apps. The cause of the issue was msupdate not being on the latest version. msupdate updates override any updates that are avaiable for the other applications. 30 | 31 | # Function that gets called to look for any updates that are avaiable for the Microsoft Office applications 32 | updateCheck() { 33 | versionCheck=$(/Library/Application\ Support/Microsoft/MAU2.0/Microsoft\ AutoUpdate.app/Contents/MacOS/msupdate -l | grep "No updates available") 34 | 35 | # Uses the above variable that checks for any avaiable updates and exits the script if no updates are found 36 | if [[ "$versionCheck" == "No updates available" ]]; then 37 | echo "All Microsoft Office applications are up to date. Exiting" 38 | exit 0 39 | else 40 | echo "Microsoft Office updates found.. starting updates.." 41 | fi 42 | } 43 | 44 | # Checks to see if Microsoft AutoUpdate is on the latest version and updates it if not, if already on the latest version it will continue on and use the above function to look for additonal updates. 45 | if [[ ! -z `/Library/Application\ Support/Microsoft/MAU2.0/Microsoft\ AutoUpdate.app/Contents/MacOS/msupdate -l | grep "MSau03"` ]]; then 46 | echo "Microsoft AutoUpdate requires an update before continuing. Starting Update." 47 | /Library/Application\ Support/Microsoft/MAU2.0/Microsoft\ AutoUpdate.app/Contents/MacOS/msupdate -i -a msau03 48 | echo "Microsoft AutoUpdate has been updated. Looking for additional updates.." 49 | updateCheck 50 | else 51 | echo "Microsoft AutoUpdate is up to date. Checking for any additional available application updates.." 52 | updateCheck 53 | fi 54 | 55 | # Script Parameters to apply version control with updates 56 | # Word 57 | if [[ ! -z "$4" ]]; then 58 | /Library/Application\ Support/Microsoft/MAU2.0/Microsoft\ AutoUpdate.app/Contents/MacOS/msupdate -i -a MSWD2019 -v "$4" 59 | else 60 | echo "Missing Word Version" 61 | fi 62 | 63 | # Excel 64 | if [[ ! -z "$5" ]]; then 65 | /Library/Application\ Support/Microsoft/MAU2.0/Microsoft\ AutoUpdate.app/Contents/MacOS/msupdate -i -a XCEL2019 -v "$5" 66 | else 67 | echo "Missing Excel Version" 68 | fi 69 | 70 | # PowerPoint 71 | if [[ ! -z "$6" ]]; then 72 | /Library/Application\ Support/Microsoft/MAU2.0/Microsoft\ AutoUpdate.app/Contents/MacOS/msupdate -i -a PPT32019 -v "$6" 73 | else 74 | echo "Missing PowerPoint Version" 75 | fi 76 | 77 | # Outlook 78 | if [[ ! -z "$7" ]]; then 79 | /Library/Application\ Support/Microsoft/MAU2.0/Microsoft\ AutoUpdate.app/Contents/MacOS/msupdate -i -a OPIM2019 -v "$7" 80 | else 81 | echo "Missing Outlook Version" 82 | fi 83 | 84 | # OneNote 85 | if [[ ! -z "$8" ]]; then 86 | /Library/Application\ Support/Microsoft/MAU2.0/Microsoft\ AutoUpdate.app/Contents/MacOS/msupdate -i -a ONMC2019 -v "$8" 87 | else 88 | echo "Missing OneNote Version" 89 | fi 90 | 91 | # Skype for Business and Remote Desktop 92 | # Uses the same version for both 2019 and 2016 so adding them to the update each time 93 | /Library/Application\ Support/Microsoft/MAU2.0/Microsoft\ AutoUpdate.app/Contents/MacOS/msupdate -i -a msfb16 msrd10 94 | 95 | exit 0 96 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Scripts 2 | A collection of scripts that I have written for both personal and professional use. These scripts will be a mixture of standalone 3 | scripts and Jamf Pro scripts (Policy Scripts & Extension Attributes). Each repository will have a readme that will list the files inside 4 | and a brief description of what the script does and any other important information about the script. 5 | 6 | 7 | - **Current Repository List** 8 | 1. Apple Software Update Search (Version 2) *[Jamf Pro Ready]* 9 | 2. Disable Smart Card Pairing *[Jamf Pro Ready]* 10 | 3. Encrypt External Volume *[Jamf Pro Ready]* 11 | 4. Rename Startup Volume *[Jamf Pro Ready]* 12 | 5. Remote Connection Project *[Standalone]* 13 | 6. macOS Health Check *[Jamf Pro Ready]* 14 | 7. macOS 10.14 Update Script *[Jamf Pro Ready]* 15 | 8. macOS Installer Downlaod Script *[Jamf Pro Ready]* 16 | 9. macOS Update Ready Check *[Jamf Pro Ready]* 17 | 10. Active Directory Migration *[Jamf Pro Ready / Standalone]* 18 | 11. LAPS for Mac *[Jamf Pro Ready]* 19 | 12. Microsoft Office Update Scripts *[2016/2019/O365 - Jamf Pro Ready]* 20 | 13. Filevault Setup Script *[Jamf Pro Ready]* 21 | 14. APNS Command Check *[Standalone]* 22 | 15. Temporary User Account Elevation *[Jamf Pro Ready]* 23 | 16. Create Policy and Profile Scope Overview *[Requires [jamfAuth](https://github.com/therealmacjeezy/JamfAuth)]* 24 | 16. Bulk Lost Mode v2 *[Requires [jamfAuth](https://github.com/therealmacjeezy/JamfAuth)]* 25 | 1. Homebrew *(Homebrew Install and Setup Scripts)* 26 | 1. Ruby Gems *(Installs Ruby Gems)* 27 | 1. Install Python Packages 28 | 29 | If you plan to use these scripts, I just ask that you credit my work and if possible, send me an email letting me know that you are using 30 | it and any feedback or issues you may have. 31 | 32 | **Contact Info** 33 | - josh[at]macjeezy.com 34 | - JAMFnation - therealmacjeezy 35 | -------------------------------------------------------------------------------- /Remote Connection Project/README.md: -------------------------------------------------------------------------------- 1 | # Remote Connection Project 2 | This repo contains a script that will help simplify the process of estabishing a remote connection. 3 | 4 | ## Version 1.0 (March 2018) 5 | The script contains the following tools and utilities: 6 | - SSH 7 | - VNC 8 | - Host Lookup 9 | 10 | **Notes and Features** 11 | - Sometimes, when attempting to establish a VNC (Screen Sharing) connection, you may see a prompt stating that VNC (Screen Sharing) is not enabled and must be enabled before you are allowed to connect. If you are able to ssh into the remote computer, you are automatically given the option to copy the command to enable VNC (Screen Sharing) to your clipboard, which will allow you to enable VNC (Screen Sharing) if needed to. 12 | -------------------------------------------------------------------------------- /Remote Connection Project/RemoteConnectionScript.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Set Console Height and Width to 100x40 4 | printf '\033[8;40;110t' 5 | 6 | # Clear Console Window 7 | clear 8 | 9 | # Script Header and Title Section 10 | setHeader() { 11 | echo " _ _ __ __ "; 12 | echo " | |_| |--.----.---.----.--.-| .-----.--.-.----|__.----.----.----.--.-."; 13 | echo " | _| | -_| _| -_| _ | | | _ | __| | -_| -_|-- _| | |"; 14 | echo " |___|_|__|____|_| |____|__._|__|_|_|_|__._|____| |____|____|____|___ |"; 15 | echo " josh[at]macjeezy.com |___| |____|"; 16 | echo " "; 17 | 18 | 19 | 20 | cat <<'EOF' 21 | ************************************************************************* 22 | > Remote Connection Script | Version 1.0 23 | > Created By: Josh Harvey | March 2018 24 | 25 | > JamfNation: therealmacjeezy 26 | > Github: github.com/therealmacjeezy 27 | ************************************************************************* 28 | 29 | EOF 30 | } 31 | 32 | setHeader 33 | 34 | setMenu() { 35 | while [[ -z "$optionSelected" ]]; do 36 | # Menu Section 37 | echo "Select an option from the menu:" 38 | 39 | # Menu Options 40 | cat <<'EOF' 41 | 1) SSH 42 | 2) VNC (Screen Sharing) 43 | 3) Host Lookup 44 | 4) Quit 45 | EOF 46 | 47 | printf 'Selection: ' 48 | read selectedOption 49 | 50 | # Clears the input from the above line 51 | tput cuu1; tput cr; tput el; 52 | echo " " 53 | # Handles the user selection 54 | case $selectedOption in 55 | 1|SSH|ssh|Ssh) 56 | echo "SSH Selected" 57 | optionSelected=ssh 58 | ;; 59 | 2|VNC|vnc|"Screen Sharing"|"screen sharing"|Vnc) 60 | echo "VNC (Screen Sharing) Selected" 61 | optionSelected=vnc 62 | ;; 63 | 3|"Host Lookup"|"host lookup") 64 | echo "Host Lookup Selected" 65 | optionSelected=lookup 66 | ;; 67 | 4|Q|q|Quit|quit) 68 | clear 69 | exit 0 70 | ;; 71 | *) 72 | echo "Invalid Option.. Try Again" 73 | clear 74 | setHeader 75 | ;; 76 | esac 77 | done 78 | echo "$optionSelected" 79 | } 80 | 81 | setMenu 82 | 83 | until [[ "$exitScript" == yes ]]; do 84 | # Remote Connection Section 85 | if [[ "$optionSelected" == "ssh" ]]; then 86 | echo " " 87 | 88 | echo "Would you like to copy the command to enable VNC to the clipboard? [y,n]" 89 | 90 | printf 'Copy Command?: ' 91 | read copyVNC 92 | 93 | tput cuu1; tput cr; tput el; 94 | tput cuu1; tput cr; tput el; 95 | 96 | case $copyVNC in 97 | y|Y|yes|Yes) 98 | echo 'sudo /System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -activate -configure -access -on -clientopts -setvnclegacy -vnclegacy yes -clientopts -setvncpw -vncpw mypasswd -restart -agent -privs -all' | pbcopy 99 | echo "Command to enable VNC has been copied to the clipboard" 100 | ;; 101 | n|N|no|No) 102 | echo "Command to enable VNC has NOT been copied to the clipboard" 103 | tput cuu1; tput cr; tput el; 104 | ;; 105 | *) 106 | echo "Invalid Option.. Continuting without copying command" 107 | tput cuu1; tput cr; tput el; 108 | ;; 109 | esac 110 | 111 | echo "Please type the host you are connecting to: (IP Address or FQDN) " 112 | printf 'Host: ' 113 | read sshHost 114 | checkHost=yes 115 | while [[ "$checkHost" == yes ]]; do 116 | echo "Verify: You entered $sshHost.. Is this correct? [y,n]" 117 | read hostAnswer 118 | 119 | tput cuu1; tput cr; tput el; 120 | case "$hostAnswer" in 121 | y|yes|Yes|Y) 122 | tput cuu1; tput cr; tput el; 123 | checkHost=done 124 | ;; 125 | n|no|No|N) 126 | tput cuu1; tput cr; tput el; 127 | tput cuu1; tput cr; tput el; 128 | tput cuu1; tput cr; tput el; 129 | echo "Please type the IP Address or FQDN you are connecting to: " 130 | printf 'Host: ' 131 | read sshHost 132 | checkUser=done 133 | ;; 134 | *) 135 | echo "Invalid Answer.. using $checkHost" 136 | checkUser=done 137 | ;; 138 | esac 139 | done 140 | 141 | echo "Please enter the username to use for connecting: " 142 | read sshUser 143 | checkUser=yes 144 | while [[ "$checkUser" == yes ]]; do 145 | echo "You entered $sshUser.. Is this correct? [y,n]" 146 | read userAnswer 147 | 148 | tput cuu1; tput cr; tput el; 149 | case "$userAnswer" in 150 | y|yes|Yes|Y) 151 | tput cuu1; tput cr; tput el; 152 | tput cuu1; tput cr; tput el; 153 | checkUser=done 154 | ;; 155 | n|no|No|N) 156 | tput cuu1; tput cr; tput el; 157 | tput cuu1; tput cr; tput el; 158 | tput cuu1; tput cr; tput el; 159 | echo "Please enter the username to use for connecting: " 160 | read sshUser 161 | checkUser=done 162 | ;; 163 | *) 164 | echo "Invalid Answer.. using $checkUser" 165 | checkUser=done 166 | ;; 167 | esac 168 | done 169 | 170 | clear 171 | 172 | echo "Starting SSH Connection to $sshHost as $sshUser ..." 173 | echo " " 174 | echo "****************************** Note ******************************" 175 | echo "You will be prompted to enter the password once the connection has been established." 176 | echo "You may also be prompted to add the fingerprint to your ssh hosts file if this is your first time connecting to this host" 177 | echo "******************************************************************" 178 | echo " " 179 | ssh "$sshUser"@"$sshHost" 180 | exitScript=yes 181 | elif [[ "$optionSelected" == "vnc" ]]; then 182 | echo " " 183 | 184 | echo "Please type the IP Address or FQDN you are connecting to: " 185 | read vncHost 186 | 187 | checkHost=yes 188 | while [[ "$checkHost" == yes ]]; do 189 | echo "You entered $vncHost.. Is this correct? [y,n]" 190 | read hostAnswer 191 | 192 | tput cuu1; tput cr; tput el; 193 | case "$hostAnswer" in 194 | y|yes|Yes|Y) 195 | tput cuu1; tput cr; tput el; 196 | checkHost=done 197 | ;; 198 | n|no|No|N) 199 | tput cuu1; tput cr; tput el; 200 | tput cuu1; tput cr; tput el; 201 | tput cuu1; tput cr; tput el; 202 | echo "Please type the IP Address or FQDN you are connecting to: " 203 | read vncHost 204 | checkUser=done 205 | ;; 206 | *) 207 | echo "Invalid Answer.. using $checkHost" 208 | checkUser=done 209 | ;; 210 | esac 211 | done 212 | 213 | echo "Please enter the username to user for connecting: " 214 | read vncUser 215 | 216 | checkUser=yes 217 | while [[ "$checkUser" == yes ]]; do 218 | echo "You entered $vncUser.. Is this correct? [y,n]" 219 | read userAnswer 220 | 221 | tput cuu1; tput cr; tput el; 222 | case "$userAnswer" in 223 | y|yes|Yes|Y) 224 | tput cuu1; tput cr; tput el; 225 | checkUser=done 226 | ;; 227 | n|no|No|N) 228 | tput cuu1; tput cr; tput el; 229 | tput cuu1; tput cr; tput el; 230 | tput cuu1; tput cr; tput el; 231 | echo "Please enter the username to user for connecting: " 232 | read vncUser 233 | checkUser=done 234 | ;; 235 | *) 236 | echo "Invalid Answer.. using $checkUser" 237 | checkUser=done 238 | ;; 239 | esac 240 | done 241 | 242 | clear 243 | 244 | echo "Starting VNC (Screen Sharing) Connection to $vncHost as $vncUser ..." 245 | echo " " 246 | echo "****************************** Note ******************************" 247 | echo "You will be prompted to enter the password once the connection has been established." 248 | echo " " 249 | echo "If a prompt stating Screen Sharing is not enabled, you can rerun this script using -e flag and selecting ssh as the Remote Connection option. This will copy the command to enable Screen Sharing to your clipboard, which can then be pasted into the SSH session once it has been established." 250 | echo "******************************************************************" 251 | echo " " 252 | open "vnc://"$vncUser"@"$vncHost"" 253 | exit 0 254 | elif [[ "$optionSelected" == "lookup" ]]; then 255 | echo " " 256 | 257 | echo "Which type of host are you looking up?" 258 | cat <<'EOF' 259 | 1) FQDN 260 | 2) IP Address 261 | EOF 262 | printf 'Selection:' 263 | read hostType 264 | 265 | tput cuu1; tput cr; tput el; 266 | 267 | case $hostType in 268 | 1|fqdn|FQDN) 269 | printf 'Enter the FQDN to lookup: ' 270 | read theHost 271 | 272 | hostName=$(nslookup "$theHost" | grep Address | awk '{print $2}'| tail -1) 273 | 274 | if [[ "$hostName" =~ "#" ]]; then 275 | echo "No Host Found. Exiting" 276 | sleep 1 277 | echo "Returning to Main Menu" 278 | clear 279 | optionSelected="" 280 | setHeader 281 | setMenu 282 | else 283 | echo "$hostName" | pbcopy 284 | echo "The IP Address has been copied to the clipboard" 285 | sleep 2 286 | echo "Returning to Main Menu" 287 | clear 288 | optionSelected="" 289 | setHeader 290 | setMenu 291 | fi 292 | ;; 293 | 2|IP|ip|"IP Address"|"ip address") 294 | printf 'Enter the IP Address to lookup: ' 295 | read theHost 296 | 297 | ipAddress=$(nslookup "$theHost" | grep name | awk '{print $4}' | cut -b1-) 298 | 299 | if [[ -z "$ipAddress" ]]; then 300 | echo "No IP Address Found. Exiting" 301 | sleep 1 302 | echo "Returning to Main Menu" 303 | clear 304 | optionSelected="" 305 | setHeader 306 | setMenu 307 | else 308 | echo "${ipAddress%?}" | pbcopy 309 | echo "The Hostname has been copied to the clipboard" 310 | sleep 2 311 | echo "Returning to Main Menu" 312 | clear 313 | optionSelected="" 314 | setHeader 315 | setMenu 316 | fi 317 | ;; 318 | *) 319 | echo "Invalid Option.. Returning to Main Menu" 320 | sleep 1 321 | clear 322 | optionSelected="" 323 | setHeader 324 | setMenu 325 | ;; 326 | esac 327 | fi 328 | done 329 | 330 | 331 | 332 | 333 | 334 | -------------------------------------------------------------------------------- /Rename Startup Volume/EA_StartupVolumeName.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ########################################## 4 | # Startup Volume Name 5 | # Extension Attribute 6 | # Josh Harvey | Jul 2017 7 | # josh[at]macjeezy.com 8 | # GitHub - github.com/therealmacjeezy 9 | # JAMFnation - therealmacjeezy 10 | ########################################## 11 | 12 | ############################### Notes ################################## 13 | # This Extension Attribute can be used to pull the Volume Name from the 14 | # startup volume. 15 | ########### ISSUES / USAGE ############################################# 16 | # If you have any issues or questions please feel free to contact 17 | # using the information in the header of this attribute 18 | # 19 | # Also, Please give me credit and let me know if you are going to use 20 | # this script. I would love to know how it works out and if you find 21 | # it helpful. 22 | ######################################################################## 23 | 24 | # Finds the current boot volume 25 | bootVolume=`/usr/sbin/bless --info --getboot` 26 | 27 | # Uses the variable above to pull the name of the boot volume 28 | bootVolumeName=`/usr/sbin/diskutil info $bootVolume | grep "Volume Name" | sed 's/.*://g' | awk '{$1=$1};1'` 29 | 30 | # Sets the Volume Name as the text for the Extension Attribute 31 | if [[ -z "$bootVolumeName" ]]; 32 | then 33 | echo "Volume Name Unavailable" 34 | else 35 | echo "$bootVolumeName" 36 | fi 37 | -------------------------------------------------------------------------------- /Rename Startup Volume/README.md: -------------------------------------------------------------------------------- 1 | # Rename Startup Volume 2 | 3 | - File List 4 | 1. RenameStartupVolume.sh 5 | 2. EA_StartupVolumeName.sh 6 | 7 | This repo contains a script *[RenameStartupVolume.sh]* that can be used to rename the Startup Volume based off of the macOS version it has installed. There is also 8 | an Extension Attribute script *[EA_StartupVolumeName.sh]* that can be uploaded or created in your JSS to pull the computers current Startup Volume name and use it for 9 | Smart Groups or Computer Searches. 10 | -------------------------------------------------------------------------------- /Rename Startup Volume/RenameStartupVolume.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ########################################## 4 | # Rename Startup Volume 5 | # Josh Harvey | Jul 2017 6 | # josh[at]macjeezy.com 7 | # GitHub - github.com/therealmacjeezy 8 | # JAMFnation - therealmacjeezy 9 | ########################################## 10 | 11 | ############################### Notes ################################## 12 | # This script will find the boot volume using the bless command 13 | # and then get the current volume name for the boot volume using 14 | # the diskutil command. It will then find the short version of 15 | # macOS the computer has installed. 16 | # 17 | # The reason for this script is so that the startup volume names 18 | # are uniformed based off of the macOS version they have installed. 19 | # The variable "newName" is then assigned a string based off of the 20 | # macOS version installed. This variable is then compaired to the 21 | # current volume name. If the names do not match, it will automatically 22 | # rename the startup volume to the correct name. 23 | # 24 | ########### ISSUES / USAGE ############################################# 25 | # If you have any issues or questions please feel free to contact 26 | # using the information in the header of this script. 27 | # 28 | # Also, Please give me credit and let me know if you are going to use 29 | # this script. I would love to know how it works out and if you find 30 | # it helpful. 31 | ######################################################################## 32 | 33 | 34 | # Finds the current boot volume 35 | bootVolume=`/usr/sbin/bless --info --getboot` 36 | 37 | # Uses the variable above to pull the name of the boot volume 38 | bootVolumeName=`/usr/sbin/diskutil info $bootVolume | grep "Volume Name" | sed 's/.*://g' | awk '{$1=$1};1'` 39 | 40 | # Finds the OS version installed on the computer 41 | osVersion=`/usr/bin/sw_vers -productVersion` 42 | 43 | # Finds the correct Volume Name for the macOS version 44 | if [[ "$osVersion" =~ "10.11" ]]; 45 | then 46 | newName="macOS1011" 47 | elif [[ "$osVersion" =~ "10.12" ]]; 48 | then 49 | newName="macOS1012" 50 | fi 51 | 52 | # Compares the current volume name to the one that it's supposed to have based off the variables set above 53 | if [[ "$bootVolumeName" == "$newName" ]]; 54 | then 55 | validName="Yes" 56 | else 57 | validName="No" 58 | fi 59 | 60 | # If the volume name is invalid, it will be renamed to the correct name 61 | if [[ "$validName" == "No" ]]; 62 | then 63 | /usr/sbin/diskutil rename "$bootVolume" "$newName" 64 | else 65 | echo "Current Volume Name is Valid" 66 | fi 67 | -------------------------------------------------------------------------------- /Ruby Gems/InstallRubyGems.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #################################################################################################### 4 | # 5 | # Copyright (c) 2022, JAMF Software, LLC. All rights reserved. 6 | # 7 | # Redistribution and use in source and binary forms, with or without 8 | # modification, are permitted provided that the following conditions are met: 9 | # * Redistributions of source code must retain the above copyright 10 | # notice, this list of conditions and the following disclaimer. 11 | # * Redistributions in binary form must reproduce the above copyright 12 | # notice, this list of conditions and the following disclaimer in the 13 | # documentation and/or other materials provided with the distribution. 14 | # * Neither the name of the JAMF Software, LLC nor the 15 | # names of its contributors may be used to endorse or promote products 16 | # derived from this software without specific prior written permission. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY JAMF SOFTWARE, LLC "AS IS" AND ANY 19 | # EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | # DISCLAIMED. IN NO EVENT SHALL JAMF SOFTWARE, LLC BE LIABLE FOR ANY 22 | # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | # 29 | # Author: Josh Harvey 30 | # Last Modified: 06/07/2022 31 | # Version: 0.2 32 | # 33 | # Description: This script will install Ruby Gems on macOS systems via Jamf Pro 34 | # 35 | #################################################################################################### 36 | 37 | ################# VARIABLES ###################### 38 | ## rubyGems: The list of packages you want to install via Ruby, seperated by commas **REQUIRED** 39 | rubyGems="$4" 40 | ## currentUser: Grabs the username of the current logged in user **DO NOT CHANGE** 41 | currentUser=$(echo "show State:/Users/ConsoleUser" | scutil | awk '/Name :/ && ! /loginwindow/ { print $3 }') 42 | ## installRubyGemsLog: Location of the installRubyGems script log **DO NOT CHANGE** 43 | installRubyGemsLog="/private/var/log/installRubyGemsLog.log" 44 | ## currentTime: Gets the time for the log **DO NOT CHANGE** 45 | currentTime=$(date +%H:%M) 46 | 47 | ### swiftDialog Variables 48 | dialogLogFile="/var/tmp/dialog.log" 49 | dialogPath="/usr/local/bin/dialog" 50 | dialogTitle="Ruby Gem Installs" 51 | dialogIcon="https://upload.wikimedia.org/wikipedia/commons/thumb/7/73/Ruby_logo.svg/128px-Ruby_logo.svg.png" 52 | declare -a theSteps 53 | theSteps=( 54 | "\"Getting List of Ruby Gems\"" 55 | ) 56 | 57 | for s in ${rubyGems//,/ }; do 58 | echo "$s" 59 | theSteps+=("\"$s\"") 60 | done 61 | 62 | theStepsLength="${#theSteps[@]}" 63 | currentStep=0 64 | dialogConfig=( 65 | "--title \"$dialogTitle\"" 66 | "--icon \"$dialogIcon\"" 67 | "--position topleft" 68 | "--message \" \"" 69 | "--messagefont \"size=16\"" 70 | # "--small" 71 | "--ontop" 72 | "--moveable" 73 | # "--position centre" 74 | "${theSteps[@]/#/--listitem }" 75 | ) 76 | ################################################### 77 | 78 | ## Logging Function 79 | log_it () { 80 | if [[ ! -z "$1" && -z "$2" ]]; then 81 | logEvent="INFO" 82 | logMessage="$1" 83 | elif [[ "$1" == "warning" ]]; then 84 | logEvent="WARN" 85 | logMessage="$2" 86 | elif [[ "$1" == "success" ]]; then 87 | logEvent="SUCCESS" 88 | logMessage="$2" 89 | elif [[ "$1" == "error" ]]; then 90 | logEvent="ERROR" 91 | logMessage="$2" 92 | fi 93 | 94 | if [[ ! -z "$logEvent" ]]; then 95 | echo ">>[installRubyGemsLog.sh] :: $logEvent [$(date +%H:%M)] :: $logMessage" 96 | echo ">>[installRubyGemsLog.sh] :: $logEvent [$(date +%H:%M)] :: $logMessage" >> "$installRubyGemsLog" 97 | fi 98 | } 99 | 100 | update_dialog () { 101 | log_it "DIALOG: $1" 102 | echo "$1" >> "$dialogLogFile" 103 | } 104 | 105 | finish_dialog () { 106 | update_dialog "progresstext: Ruby Gem Installs Complete" 107 | sleep 1 108 | update_dialog "quit:" 109 | exit 0 110 | } 111 | 112 | if [[ ! -f "$dialogPath" ]]; then 113 | log_it "swiftDialog not installed" 114 | dialogDownload=$( curl -sL https://api.github.com/repos/bartreardon/swiftDialog/releases/latest ) 115 | dialogURL=$(get_json_value "$dialogDownload" 'assets[0].browser_dialogURL') 116 | curl -L --output "dialog.pkg" --create-dirs --output-dir "/var/tmp" "$dialogURL" 117 | installer -pkg "/var/tmp/dialog.pkg" -target / 118 | fi 119 | 120 | rm "$dialogLogFile" 121 | eval "$dialogPath" "${dialogConfig[*]}" & sleep 1 122 | 123 | for (( i=0; i&1 | tee -a "$installRubyGemsLog" 143 | checkInstall=$(which $p | grep "not found") 144 | if [[ -z "$checkInstall" ]]; then 145 | log_it "success" "$p was installed successfully." 146 | update_dialog "listitem: title: $p, status: success" 147 | else 148 | log_it "error" "$p was unable to be installed. View installRubyGemsLog.log for details." 149 | update_dialog "listitem: title: $p, status: error" 150 | fi 151 | done 152 | } 153 | 154 | install_gems 155 | finish_dialog -------------------------------------------------------------------------------- /Ruby Gems/README.md: -------------------------------------------------------------------------------- 1 | # `InstallRubyGems.sh` 2 | 3 | An easy way to install Ruby Gems on macOS system via Jamf Pro. 4 | 5 | ---- 6 | ## Requirements 7 | - [swiftDialog](https://github.com/bartreardon/swiftDialog) installed. 8 | - **Note:** This script will download and install swiftDialog if it's not found. 9 | 10 | ---- 11 | ## Setup 12 | 1. Add script to Jamf Pro Server 13 | 1. Create a new policy and add the `InstallRubyGems.sh` script 14 | 1. Enter the list of Ruby Gems to install in Script Parameter #4 as a Comma Seperated List 15 | - **Example:** `fastlane,cocoapods,slather,xcpretty,xcode-install,bundler,jazzy` 16 | 17 | > Be sure to set the trigger and scope correctly. This will vary based on how you want to deploy it. 18 | 19 | ---- 20 | ## Logging 21 | This script creates a logfile at `/private/var/log/installRubyGemsLog.log` -------------------------------------------------------------------------------- /Scripting Tips and Examples: -------------------------------------------------------------------------------- 1 | Created by: Josh Harvey 2 | Date: June 2016 3 | Updated: June 2017 4 | 5 | This is a document that will get updated and have new content added overtime. 6 | 7 | 8 | // Scripting Tips and Examples // 9 | Bash (Shell Script) and AppleScript Examples 10 | 11 | -- Bash (Shell Script) Section -- 12 | 13 | #Packages 14 | - Expand a package 15 | pkgutil --expand /path/to/mystubbornpackage.pkg /path/to/expand/newname 16 | 17 | - Flatten a package 18 | pkgutil --flatten /path/to/expand/newname /path/to/flattento.pkg 19 | 20 | - Install a package (NEEDS SUDO) 21 | sudo installer -pkg /path/of.pkg -target / 22 | 23 | #Add Certificates to Keychain (NEEDS SUDO) 24 | sudo security add-trusted-cert -d -r trustRoot -k /path/of/cert.cer 25 | 26 | #Pause 27 | /bin/sleep [number of seconds to wait] 28 | 29 | #Find Computer Name [ --get | --set ] 30 | scutil --get ComputerName [ LocalHostName | HostName ] 31 | 32 | #Output to text file with multiple lines (Make sure to use double quotes) 33 | echo “text 34 | goes 35 | here” >> /path/to.txt 36 | #”>>” causes the log to record on next line w/o overwrite | “>” overwrites the file each time) 37 | 38 | #Find version number of file from Info.plist 39 | cat /path/to/Info.plist | grep -A1 CFBundleShortVersionString | grep string | sed 's/<[^>]*>//g' 40 | 41 | #Filter Output Options 42 | grep "text here" 43 | awk {'print $1'} - $1 = first column, $2 = second column, etc.. 44 | 45 | #Applescript In Shell Script (Mutliple Lines) 46 | /usr/bin/osascript <<'APPLESCRIPT' 47 | your applescript 48 | goes here 49 | APPLESCRIPT 50 | 51 | #List Applications in the parents directory only 52 | find /Applications -maxdepth '1' -iname '*.app' 53 | 54 | #Hides the file from Finder 55 | chflags hidden /file/goes/here 56 | 57 | #Unhides the file from Finder 58 | chflags nohidden /file/goes/here 59 | 60 | #Have alert box appear 61 | osascript -e 'tell app "System Events" to display dialog “put text here”’ 62 | 63 | #function to get the current time in a Shell Script 64 | #Call function inside the script by using timestamp 65 | timestamp() { 66 | date +"%T" 67 | } 68 | 69 | #Displays message with icon and one button 70 | osascript -e 'tell app "System Events" to display dialog "Please Install PGP Now" with icon caution buttons {"Ok"}' 71 | 72 | #Change Permissions on a Directory 73 | #Add Read/Write for all users: 74 | chmod ugo+rwx /Path/To/Directory 75 | #Remove Read/Write for all other users and give them Read only 76 | chmod go-wx /Path/To/Directory 77 | 78 | #Clear History in Terminal 79 | history -c 80 | 81 | #Clear Entire History 82 | echo '' > ~/.bash_history 83 | 84 | #Compare Strings using if Statements 85 | # == - matches 86 | # != - does not match 87 | if [[ $theVar1 == $theVar2 ]] #matches 88 | then 89 | command goes here 90 | fi 91 | #### OR #### 92 | if [[ $theVar1 == $theVar2 ]] #matches 93 | then 94 | command goes here 95 | elif 96 | #Does NOT Match 97 | if [[ $theVar1 != $theVar2 ]] 98 | then 99 | command goes here 100 | fi 101 | 102 | #Hide command output 103 | [command] &> /dev/null 104 | 105 | #Progress Spinner 106 | varGoesHere=`Command You Want To Pull Progress From` 107 | 108 | sp='/-\|' 109 | printf ' ' 110 | for varGoesHere in $(seq 9); do 111 | printf '\r%.1s' "$sp" 112 | sp=${sp#?}${sp%???} 113 | sleep 1 114 | done 115 | echo '' 116 | 117 | #Progress Bar 118 | processgoes.here & PID=$! 119 | 120 | echo "Sample Test Here" 121 | printf "[" 122 | while kill -0 $PID 2> /dev/null; do 123 | printf "▓|▓|" 124 | sleep 1 125 | done 126 | printf "] done!" 127 | 128 | #Yes/No Input from user 129 | echo "Would you like to restart the computer now?" 130 | echo "Press Y to restart now | Press N to restart later" 131 | select yn in "Y" "N"; do 132 | case $yn in 133 | y|Y ) echo $rebootNow; break;; 134 | n|N ) exit;; 135 | esac 136 | done 137 | 138 | #Function 139 | testFunction() { 140 | #commandsgo.here 141 | } 142 | 143 | [to call function in script just user the name of the function without ()] 144 | 145 | #Install Configuration Profiles 146 | [sudo] /usr/bin/profiles -i -F /Path/To/Profile.mobileconfig 147 | sudo - Installs profile as device profile instead of user 148 | -i - Installs profile as user profiles [unless ran under sudo] 149 | 150 | #Copy a file and show the ETA and Size of transfer 151 | rsync -ah --progress /Original/Path/To/File /Destination/Path/To/File 152 | 153 | 154 | ##AppleScript Examples & Tips## 155 | 156 | #Set Variables 157 | #Text 158 | set variableName to “text” 159 | #Shell Script 160 | set variableName to do shell script “/command/goes/here” [with administrator privileges] 161 | 162 | #If Statements 163 | 164 | 165 | #Display Dialog with Variables 166 | set theDialogText to "An error has occurred. Would you like to continue?" 167 | display dialog theDialogText buttons {"Don't Continue", "Continue"} default button "Continue" cancel button "Don't Continue" 168 | 169 | #Dialog with icons 170 | #Custom icons can be referenced but must be hard linked using ":"" not "/"" 171 | tell app "System Events" display dialog "text here" [with title "Title Goes Here"] with icon caution [file "Path:To:File"] [buttons {"Button One", "Button Two"} default button "Button Two"] 172 | 173 | 174 | #Alert Dialog 175 | #Alert Display with Bold Title and Additional Text 176 | set theAlertText to "An error has occurred." 177 | set theAlertMessage to "The amount of available free space is dangerously low. Would you like to continue?" 178 | display alert theAlertText message theAlertMessage as critical buttons {"Don't Continue", "Continue"} default button "Continue" cancel button "Don't Continue" 179 | 180 | #Notification Messages 181 | display notification "Please Continue with Step 5 of the Cookbook" with title "ESE Deploy Prep" subtitle "Completed Successfully" sound name "Frog" 182 | 183 | #Variable to have user select file 184 | set theDocument to choose file with prompt "Please select a document to process:" 185 | #Define specific file type needed 186 | [ of type {"extension"} ] 187 | #Allow multiple files to be selected 188 | [ with multiple selections allowed ] 189 | 190 | #Display Menu with Choices 191 | set theChoiceOptions to {"One", "Two", "Three"} 192 | set theBestOption to choose from list theChoiceOptions with prompt "Select your favorite number:" default items {"One"} 193 | theBestOption 194 | 195 | 196 | -------------------------------------------------------------------------------- /Temporary User Account Elevation/README.md: -------------------------------------------------------------------------------- 1 | ## Temporary User Account Elevation 2 | 3 | **Note:** This script requires the user to have a smartcard inserted in the system. If you are looking for the **non-smartcard** version, use `TempUserAccountElevation-NoSmartcard.sh` 4 | 5 | This script will temporarily elevate a user's account. The user's account can either be set in a script parameter (#4) or pull the user account of the user that runs the policy via Self Service. 6 | 7 | When the script runs, the user will be prompted to insert their smartcard into their card reader and then prompted to select one of the following options: 8 | - Elevate 9 | - Remove Privileges 10 | - Cancel 11 | 12 | If the **Elevate** option is selected, the script will perform the following actions: 13 | 1. Create an entry in the local log file with the user's UPN (which is pulled from their smartcard, this ensures that the user being logged is actually in front of the computer) and the type of request being made 14 | 2. Uses the chflags command to hide the log file 15 | 3. Adds the user to the groups "admin" and "wheel" 16 | 4. Creates a LaunchDaemon that runs the "RemoveElevation" script after the number of seconds set (default is 120 for testing, 10 minutes for prod) 17 | 5. Creates the RemoveElevation script which is used to revert the user back to standard 18 | 19 | If the **Remove Privileges** option is selected, the script will perform the following actions: 20 | 1. Check if the user is a member of the "admin" and "wheel" groups 21 | 2. If present in those groups, it will remove the user from them and revert them back to a standard user 22 | 23 | If the **Cancel** option is selected, the script will exit 24 | 25 | **Note:** 26 | > This script pulls information from a smartcard, to use this script without a smartcard, you will need to comment out the **Prompt_For_Smartcard** and **getUPN** functions (Lines 137-158) and remove the *$UPN* variable that is used when creating the log (Line 189, in the if statement at the end of the script) 27 | -------------------------------------------------------------------------------- /Temporary User Account Elevation/TempUserAccountElevation-NoSmartcard.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ################################################# 4 | # Elevate User Account [No Smartcard Version] 5 | # Joshua Harvey | May 2022 6 | # josh[at]macjeezy.com 7 | # GitHub - github.com/therealmacjeezy 8 | # JAMFnation - therealmacjeezy 9 | ################################################# 10 | 11 | # Verify the TRMJ Scripts directory exists, change the location to a location you want to use 12 | if [[ ! -d /Library/Scripts/TRMJ ]]; then 13 | echo "Creating TRMJ Scripts folder" 14 | /bin/mkdir -p /Library/Scripts/TRMJ 15 | fi 16 | 17 | # Check to see if the user account has been set in Script Parameter 4. If not it will pull the current user 18 | if [[ ! -z "$4" ]];then 19 | echo "User Account has been found in policy." 20 | userAccount="$4" 21 | else 22 | userAccount=$(scutil <<< "show State:/Users/ConsoleUser" | awk -F': ' '/[[:space:]]+Name[[:space:]]:/ { if ( $2 != "loginwindow" ) { print $2 }} ') 23 | fi 24 | 25 | START_ACCOUNT_ELEVATION() { 26 | ## Add the group account to the admin and wheel groups 27 | /usr/sbin/dseditgroup -o edit -a $userAccount -t user admin 28 | /usr/sbin/dseditgroup -o edit -a $userAccount -t user wheel 29 | 30 | ## Create the LaunchDaemon to remove the elevated priviliges after 30 minutes 31 | ## Testing at 120 seconds.. change to 1600 after finished with testing 32 | ## Remove the StandardErrorPath and StandardOutPath when testing is finished to avoid additonal logs going on the system 33 | echo "Creating Launchd item" 34 | /bin/cat > "/Library/LaunchDaemons/com.therealmacjeezy.remove-elevation.plist" <<'Remove_Daemon' 35 | 36 | 37 | 38 | 39 | Label 40 | com.therealmacjeezy.remove-elevation 41 | ProgramArguments 42 | 43 | sh 44 | -c 45 | /Library/Scripts/TRMJ/Remove_Elevation.sh 46 | 47 | StandardErrorPath 48 | /Users/Shared/NewError.log 49 | StandardOutPath 50 | /Users/Shared/NewOutput.log 51 | StartInterval 52 | 120 53 | 54 | 55 | Remove_Daemon 56 | 57 | sudo /bin/chmod 0644 "/Library/LaunchDaemons/com.therealmacjeezy.remove-elevation.plist" 58 | sudo /bin/launchctl load "/Library/LaunchDaemons/com.therealmacjeezy.remove-elevation.plist" 59 | 60 | ## Create the script to remove the elevated access 61 | cat > /Library/Scripts/TRMJ/Remove_Elevation.sh < /tmp/user_receipt 138 | 139 | # Ask user what they want to do (add / remove) 140 | # Applescript prompt 141 | SCRIPT_OPTIONS=$( 142 | /bin/launchctl asuser "$currUserUID" sudo -iu "$currUser" /usr/bin/osascript <> /Users/Shared/ElevationRequests.log 169 | chflags hidden "/Users/Shared/ElevationRequests.log" 170 | START_ACCOUNT_ELEVATION 171 | elif [[ "$SCRIPT_OPTIONS" == "remove" ]]; then 172 | echo "Removing account elevation" 173 | REMOVE_ACCOUNT_ELEVATION 174 | else 175 | echo "Cancel selected" 176 | exit 0 177 | fi 178 | -------------------------------------------------------------------------------- /Temporary User Account Elevation/TempUserAccountElevation.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ################################################# 4 | # Elevate User Account 5 | # Joshua Harvey | November 2019 6 | # josh[at]macjeezy.com 7 | # GitHub - github.com/therealmacjeezy 8 | # JAMFnation - therealmacjeezy 9 | ################################################# 10 | 11 | # Verify the TRMJ Scripts directory exists, change the location to a location you want to use 12 | if [[ ! -d /Library/Scripts/TRMJ ]]; then 13 | echo "Creating TRMJ Scripts folder" 14 | /bin/mkdir -p /Library/Scripts/TRMJ 15 | fi 16 | 17 | # Check to see if the user account has been set in Script Parameter 4. If not it will pull the current user 18 | if [[ ! -z "$4" ]];then 19 | echo "User Account has been found in policy." 20 | userAccount="$4" 21 | else 22 | userAccount=$(scutil <<< "show State:/Users/ConsoleUser" | awk -F': ' '/[[:space:]]+Name[[:space:]]:/ { if ( $2 != "loginwindow" ) { print $2 }} ') 23 | fi 24 | 25 | START_ACCOUNT_ELEVATION() { 26 | ## Add the group account to the admin and wheel groups 27 | /usr/sbin/dseditgroup -o edit -a $userAccount -t user admin 28 | /usr/sbin/dseditgroup -o edit -a $userAccount -t user wheel 29 | 30 | ## Create the LaunchDaemon to remove the elevated priviliges after 30 minutes 31 | ## Testing at 120 seconds.. change to 1600 after finished with testing 32 | ## Remove the StandardErrorPath and StandardOutPath when testing is finished to avoid additonal logs going on the system 33 | echo "Creating Launchd item" 34 | /bin/cat > "/Library/LaunchDaemons/com.therealmacjeezy.remove-elevation.plist" <<'Remove_Daemon' 35 | 36 | 37 | 38 | 39 | Label 40 | com.therealmacjeezy.remove-elevation 41 | ProgramArguments 42 | 43 | sh 44 | -c 45 | /Library/Scripts/TRMJ/Remove_Elevation.sh 46 | 47 | StandardErrorPath 48 | /Users/Shared/NewError.log 49 | StandardOutPath 50 | /Users/Shared/NewOutput.log 51 | StartInterval 52 | 120 53 | 54 | 55 | Remove_Daemon 56 | 57 | sudo /bin/chmod 0644 "/Library/LaunchDaemons/com.therealmacjeezy.remove-elevation.plist" 58 | sudo /bin/launchctl load "/Library/LaunchDaemons/com.therealmacjeezy.remove-elevation.plist" 59 | 60 | ## Create the script to remove the elevated access 61 | cat > /Library/Scripts/TRMJ/Remove_Elevation.sh </dev/null \ 141 | | grep -c com.apple.pivtoken ) -lt 1 ]]; do sleep 1; done; kill -9 $! 142 | } 143 | 144 | Prompt_For_Smartcard 145 | 146 | getUPN(){ 147 | # Get the PIV Identity Hash 148 | hash=$(sc_auth identities | grep PIV | awk '{print $1}' | tr '[:upper:]' '[:lower:]' | sed 's/.\{8\}/& /g' | sed 's/.$//g') 149 | 150 | # Extract the certificate associated with that hash to the temp folder. 151 | system_profiler SPSmartCardsDataType | grep -A5 "$hash" | awk '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/{print; count++; if (count==3) exit}' | fold -w67 > /tmp/temp.pem 152 | 153 | echo "Getting UPN" 154 | UPN="$(openssl asn1parse -i -dump -in /tmp/temp.pem -strparse $(openssl asn1parse -i -dump -in /tmp/temp.pem | awk -F ':' '/X509v3 Subject Alternative Name/ {getline; print $1}') | awk -F ':' '/UTF8STRING/{print $4}')" 155 | echo "$UPN" > /tmp/user_receipt 156 | } 157 | 158 | getUPN 159 | 160 | # Ask user what they want to do (add / remove) 161 | # Applescript prompt 162 | SCRIPT_OPTIONS=$( 163 | /bin/launchctl asuser "$currUserUID" sudo -iu "$currUser" /usr/bin/osascript <> /Users/Shared/ElevationRequests.log 190 | chflags hidden "/Users/Shared/ElevationRequests.log" 191 | START_ACCOUNT_ELEVATION 192 | elif [[ "$SCRIPT_OPTIONS" == "remove" ]]; then 193 | echo "Removing account elevation" 194 | REMOVE_ACCOUNT_ELEVATION 195 | else 196 | echo "Cancel selected" 197 | exit 0 198 | fi 199 | -------------------------------------------------------------------------------- /macOS 10.14 Update Script/macOS1014UpdateScript.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ################################################# 4 | # macOS 10.14 Update Script 5 | # Joshua Harvey | August 2018 6 | # josh[at]macjeezy.com 7 | ################################################# 8 | 9 | ####### Supported macOS Versions ########################################################## 10 | # macOS 10.11.x, macOS 10.12.x, macOS 10.13.x 11 | ####### Script Overview ################################################################### 12 | # This script will setup a plist for an authenticated reboot, check the disk type for the 13 | # computer, then run the startosinstall binary based on the disk type returned. Before the 14 | # computer restarts, it will kill self service which is required due to the startosinstall 15 | # performing a soft restart and is not able to force quit other applications 16 | ####### NOTE ############################################################################## 17 | # This script requires the "Install macOS Mojave.app" to be located in the Applications 18 | # directory 19 | ########################################################################################### 20 | 21 | # Pulls the current logged in user and their UID 22 | currUser=$(scutil <<< "show State:/Users/ConsoleUser" | awk -F': ' '/[[:space:]]+Name[[:space:]]:/ { if ( $2 != "loginwindow" ) { print $2 }} ') 23 | currUserUID=$(id -u "$currUser") 24 | 25 | fvPass=$( 26 | # Prompts the user to input their FileVault password using Applescript. This password is used for a one time authenticated reboot. Once the installation is started, the file that was used to reboot the system is deleted. 27 | /bin/launchctl asuser "$currUserUID" sudo -iu "$currUser" /usr/bin/osascript <