mirror of
https://github.com/mtan93/Installomator.git
synced 2026-03-09 05:11:59 +00:00
Compare commits
92 Commits
v9.0
...
Detect-spc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
07efbb394f | ||
|
|
93844fdad9 | ||
|
|
27aa86b279 | ||
|
|
f0f4ff5747 | ||
|
|
579862274a | ||
|
|
72fdc2365e | ||
|
|
ac042bc700 | ||
|
|
f001a829bd | ||
|
|
9736e1dbfa | ||
|
|
d78c6fdd5c | ||
|
|
65b16dc1ed | ||
|
|
9f5b89c37e | ||
|
|
05c1bf7cfc | ||
|
|
e07b4dd08f | ||
|
|
88da86d4f0 | ||
|
|
b512ae17a3 | ||
|
|
1787842366 | ||
|
|
3e0ad885d8 | ||
|
|
001cd592b0 | ||
|
|
de93df0f85 | ||
|
|
0d9628b587 | ||
|
|
41e828f87a | ||
|
|
eb25c271e3 | ||
|
|
25c419b50d | ||
|
|
7025efe566 | ||
|
|
22a34c45c9 | ||
|
|
cc06b77611 | ||
|
|
70c4d59df7 | ||
|
|
7fcba4cb6e | ||
|
|
00ebfa35fd | ||
|
|
2d813bce80 | ||
|
|
69e4cdd216 | ||
|
|
55eb9e2d89 | ||
|
|
2349f456bc | ||
|
|
8fd949a567 | ||
|
|
f9997623f1 | ||
|
|
4b14b31ff3 | ||
|
|
ed737510bb | ||
|
|
ec9f1bb9a2 | ||
|
|
9022d8e74d | ||
|
|
2a9b73dba7 | ||
|
|
40f20b3536 | ||
|
|
3a0c104f48 | ||
|
|
7629acf6a5 | ||
|
|
54070273bc | ||
|
|
3d84300665 | ||
|
|
bbae9356c4 | ||
|
|
57733423b1 | ||
|
|
c3f751bad8 | ||
|
|
56bf2a3dc4 | ||
|
|
28ddefbd57 | ||
|
|
3a0373af60 | ||
|
|
fb7d9c43a8 | ||
|
|
ebed623837 | ||
|
|
b18aac905e | ||
|
|
4f1c56177a | ||
|
|
0a3b7af338 | ||
|
|
9b6c337d7a | ||
|
|
9fd2b87e3c | ||
|
|
a16cd44b0e | ||
|
|
74f6b569dd | ||
|
|
d475b2b8ab | ||
|
|
d79886b88f | ||
|
|
56125c07b1 | ||
|
|
a3dbf75818 | ||
|
|
afbd1e363e | ||
|
|
22bc0ecbf6 | ||
|
|
24f729d357 | ||
|
|
81b02e3932 | ||
|
|
800912be0c | ||
|
|
1e3a50c07f | ||
|
|
693164c9a0 | ||
|
|
0c12343fbb | ||
|
|
cba0e8c766 | ||
|
|
a25c904ba7 | ||
|
|
d64c18df93 | ||
|
|
9afdc233f9 | ||
|
|
bc7d005fb9 | ||
|
|
175f682b43 | ||
|
|
ff8a9c2c3a | ||
|
|
bf740d1ffe | ||
|
|
1da37a13ca | ||
|
|
b30d4da703 | ||
|
|
c3714d855c | ||
|
|
dd83f6bd75 | ||
|
|
c55cc788bb | ||
|
|
df616d2f51 | ||
|
|
557d63a4f3 | ||
|
|
0432eb62d3 | ||
|
|
071586e43c | ||
|
|
aea7d282fe | ||
|
|
cd6b1397c8 |
48
CHANGELOG.md
48
CHANGELOG.md
@@ -1,4 +1,48 @@
|
||||
## v9?
|
||||
- if `spctl`-check is `rejected` then we now show an error that it can be due to Gatekeepr only allowing apps from App Store only. Installomator requires that all identified developers are accepted as well.
|
||||
|
||||
## v9.1
|
||||
|
||||
**Note**: Both Google and Mozilla recommend using the pkg installers instead of the dmg downloads for managed deployments. So far, Installomator has provided labels for both. (`googlechrome` and `googlechromepkg` or `firefox` and `firefoxpkg`, respectively) Since there are problems with the dmg downloads, a future release of Installomator will _disable_ the `firefox` and `googlechrome` dmg labels. You should switch to using the respective pkg labels instead.
|
||||
|
||||
- added option for Microsoft Endpoint Manager (Intune) to `LOGO` (#446)
|
||||
- minor fixes (#427, #434, #436)
|
||||
- the `googlechrome` label now always downloads the universal version (#430)
|
||||
- new labels:
|
||||
- 1passwordcli (#429)
|
||||
- amazoncorretto8jdk (#423)
|
||||
- autodeskfusion360admininstall (#447)
|
||||
- axurerp10 (#439)
|
||||
- calcservice (#426)
|
||||
- clipy (#412)
|
||||
- dockutil (#432)
|
||||
- easyfind (#426)
|
||||
- grammarly (#444)
|
||||
- houdahspot (#426)
|
||||
- macadminspython (#431)
|
||||
- microsoftazuredatastudio (#438)
|
||||
- nanosaur (#426)
|
||||
- tembo (#426)
|
||||
- wordservice (#426)
|
||||
- xmenu (#426)
|
||||
- updated labels:
|
||||
- appcleaner (#428)
|
||||
- dialog (#435, #437)
|
||||
- googlechrome (#430)
|
||||
- microsoftdefender (#440)
|
||||
- supportapp (#426)
|
||||
- zoom and zoomgov (#426, #433)
|
||||
|
||||
|
||||
|
||||
## v9.0.1
|
||||
|
||||
- improved logging levels throughout the script #408
|
||||
- fixed a bug for `pkgindmg` style labels #408
|
||||
- changed the criteria used to locate an app in the case the it cannot be found in the default locations, this should help with some apps with similar name (Virtual Box and Box Drive, #401) #413
|
||||
- new label: WhiteBox Packages (`packages`) #415
|
||||
- modified label: `loom` (added Apple silicon download) #417
|
||||
|
||||
## v9
|
||||
|
||||
- We have moved the root check to the beginning of the script, and improved DEBUG handling with two different modes. `DEBUG=0` is still for production, and `1` is still for the DEBUG we previously knew downloading to the directory it is running from, but `2` will download to temporary folder, will detect updates, but will not install anything, but it will notify the user (almost as running the script without root before).
|
||||
- Added option to not interrupt Do Not Disturb full screen apps like Keynote or Zoom with `INTERRUPT_DND="no"`. Default is `"yes"` which is how it has worked until now.
|
||||
@@ -7,7 +51,7 @@
|
||||
- New variable `RETURN_LABEL_NAME`. If given the value `1`, like `RETURN_LABEL_NAME=1` then Installomator only returns the name of the label. It makes for a better user friendly message for displaying in DEPNotify if that is integrated.
|
||||
- Changed logic if `IGNORE_APP_STORE_APPS=yes`. Before this version a label like `microsoftonedrive` that was installed from App Store, and that we want to replace with the “ordinary” version, Installomator would still use `updateTool`, even though `IGNORE_APP_STORE_APPS=yes`. So we would have to have `INSTALL=force` in order to have the app replaced, as `updateTool` would be used. But now if `IGNORE_APP_STORE_APPS=yes` then `updateTool` will be not set, and the App Store app will be replaced. BUT if the installed software was not from App Store, then `updateTool` will not be used, and it would be a kind of a forced install (in the example of `microsoftonedrive`), except if the version is the same (where installation is skipped).
|
||||
- Added variable `SYSTEMOWNER` that is used when copying files when installing. Default `0` is to change owner of the app to the current user on the Mac, like this user was installing this app themselves. When using `1` we will put “root:wheel” on the app, which can be useful for shared machines.
|
||||
- Added option `curlOptions` to the labels. It can be filled with extra headers need for downloading the specific software. It needs to be an array, like `curlOptions=( )`. See “mocha”-software-labels.
|
||||
- Added option `curlOptions` to the labels. It can be filled with extra headers need for downloading the specific software. It needs to be an array, like `curlOptions=( )`. See “mocha”-software-labels.
|
||||
|
||||
Big changes to logging:
|
||||
- Introducing variable `LOGGING`, that can be either of the logging levels
|
||||
|
||||
@@ -4,6 +4,21 @@ __Please note, that if you are contributing to this project with new labels or o
|
||||
|
||||
We try to keep the script as short as possible, and with more than 300 labels, we can save 300 lines in the script, if we do not have credit lines on each of these. So we are thankful for your contribution, but we will be removing these lines in the coming releases.
|
||||
|
||||
## Branches
|
||||
|
||||
The branch list is as follows:
|
||||
|
||||
- `release`: this branch will have the latest released version
|
||||
- `main`: (default) this branch will be the latest release plus new and updated app labels, and critical bug fixes
|
||||
- `dev`: this will contain new and updated app labels, as well as any other code changes
|
||||
there will be other branches for new features and testing
|
||||
|
||||
This should allow the contributing team to release minor updates for new and updated app labels while also work on new features for the next major release.
|
||||
|
||||
With all the new branches, your local repo may get confused. If you don’t have local changes, it is easiest to delete your local repo and re-clone it. If you have local changes you want to preserve, then you should commit those to a local branch, pull the latest changes `git pull --all`, then delete the old master branch: `git branch -d master`.
|
||||
|
||||
Make sure you branch off of main for new and updated labels and off of `dev` for other code changes. Thank you for contributing!
|
||||
|
||||
## Labels
|
||||
|
||||
If you need a new label for a piece of software, please take a look at the tutorials in the Wiki, if those can be helpful for starting out on the creation of the label.
|
||||
|
||||
350
Installomator.sh
350
Installomator.sh
@@ -80,6 +80,7 @@ LOGO=appstore
|
||||
# - mosyleb Mosyle Business
|
||||
# - mosylem Mosyle Manager (Education)
|
||||
# - addigy Addigy
|
||||
# - microsoft Microsoft Endpoint Manager (Intune)
|
||||
# path can also be set in the command call, and if file exists, it will be used.
|
||||
# Like 'LOGO="/System/Applications/App\ Store.app/Contents/Resources/AppIcon.icns"'
|
||||
# (spaces have to be escaped).
|
||||
@@ -301,8 +302,8 @@ if [[ $(/usr/bin/arch) == "arm64" ]]; then
|
||||
rosetta2=no
|
||||
fi
|
||||
fi
|
||||
VERSION="9.0"
|
||||
VERSIONDATE="2022-02-08"
|
||||
VERSION="9.1"
|
||||
VERSIONDATE="2022-03-18"
|
||||
|
||||
# MARK: Functions
|
||||
|
||||
@@ -324,8 +325,10 @@ cleanupAndExit() { # $1 = exit code, $2 message, $3 level
|
||||
reopenClosedProcess
|
||||
if [[ -n $2 && $1 -ne 0 ]]; then
|
||||
printlog "ERROR: $2" $3
|
||||
else
|
||||
printlog "$2" $3
|
||||
fi
|
||||
printlog "################## End Installomator, exit code $1 \n\n" REQ
|
||||
printlog "################## End Installomator, exit code $1 \n" REQ
|
||||
|
||||
# if label is wrong and we wanted name of the label, then return ##################
|
||||
if [[ $RETURN_LABEL_NAME -eq 1 ]]; then
|
||||
@@ -403,7 +406,7 @@ printlog(){
|
||||
curl -s -X POST https://http-intake.logs.datadoghq.com/v1/input -H "Content-Type: text/plain" -H "DD-API-KEY: $datadogAPI" -d "${log_priority} : $mdmURL : Installomator-${label} : ${VERSIONDATE//-/} : $SESSION : ${logmessage}" > /dev/null
|
||||
done <<< "$log_message"
|
||||
fi
|
||||
|
||||
|
||||
# Extra spaces
|
||||
space_char=""
|
||||
if [[ ${#log_priority} -eq 3 ]]; then
|
||||
@@ -460,10 +463,10 @@ downloadURLFromGit() { # $1 git user name, $2 git repo name
|
||||
fi
|
||||
|
||||
if [ -n "$archiveName" ]; then
|
||||
downloadURL=$(curl --silent --fail "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" \
|
||||
downloadURL=$(curl -L --silent --fail "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" \
|
||||
| awk -F '"' "/browser_download_url/ && /$archiveName\"/ { print \$4; exit }")
|
||||
else
|
||||
downloadURL=$(curl --silent --fail "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" \
|
||||
downloadURL=$(curl -L --silent --fail "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" \
|
||||
| awk -F '"' "/browser_download_url/ && /$filetype\"/ { print \$4; exit }")
|
||||
fi
|
||||
if [ -z "$downloadURL" ]; then
|
||||
@@ -480,9 +483,9 @@ versionFromGit() {
|
||||
gitusername=${1?:"no git user name"}
|
||||
gitreponame=${2?:"no git repo name"}
|
||||
|
||||
appNewVersion=$(curl --silent --fail "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | grep tag_name | cut -d '"' -f 4 | sed 's/[^0-9\.]//g')
|
||||
appNewVersion=$(curl -L --silent --fail "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | grep tag_name | cut -d '"' -f 4 | sed 's/[^0-9\.]//g')
|
||||
if [ -z "$appNewVersion" ]; then
|
||||
printlog "could not retrieve version number for $gitusername/$gitreponame"
|
||||
printlog "could not retrieve version number for $gitusername/$gitreponame" WARN
|
||||
appNewVersion=""
|
||||
else
|
||||
echo "$appNewVersion"
|
||||
@@ -526,19 +529,34 @@ getAppVersion() {
|
||||
fi
|
||||
fi
|
||||
|
||||
# get app in /Applications, or /Applications/Utilities, or find using Spotlight
|
||||
if [[ -d "/Applications/$appName" ]]; then
|
||||
# get app in targetDir, /Applications, or /Applications/Utilities
|
||||
if [[ -d "$targetDir/$appName" ]]; then
|
||||
applist="$targetDir/$appName"
|
||||
elif [[ -d "/Applications/$appName" ]]; then
|
||||
applist="/Applications/$appName"
|
||||
# if [[ $type =~ '^(dmg|zip|tbz|app.*)$' ]]; then
|
||||
# targetDir="/Applications"
|
||||
# fi
|
||||
elif [[ -d "/Applications/Utilities/$appName" ]]; then
|
||||
applist="/Applications/Utilities/$appName"
|
||||
# if [[ $type =~ '^(dmg|zip|tbz|app.*)$' ]]; then
|
||||
# targetDir="/Applications/Utilities"
|
||||
# fi
|
||||
else
|
||||
applist=$(mdfind "kind:application $appName" -0 )
|
||||
# applist=$(mdfind "kind:application $appName" -0 )
|
||||
printlog "name: $name, appName: $appName"
|
||||
applist=$(mdfind "kind:application AND name:$name" -0 )
|
||||
# printlog "App(s) found: ${applist}" DEBUG
|
||||
# applist=$(mdfind "kind:application AND name:$appName" -0 )
|
||||
fi
|
||||
if [[ -z applist ]]; then
|
||||
printlog "No previous app found" DEBUG
|
||||
printlog "No previous app found" INFO
|
||||
else
|
||||
printlog "App(s) found: ${applist}" DEBUG
|
||||
printlog "App(s) found: ${applist}" INFO
|
||||
fi
|
||||
# if [[ $type =~ '^(dmg|zip|tbz|app.*)$' ]]; then
|
||||
# printlog "targetDir for installation: $targetDir" INFO
|
||||
# fi
|
||||
|
||||
appPathArray=( ${(0)applist} )
|
||||
|
||||
@@ -561,10 +579,10 @@ getAppVersion() {
|
||||
fi
|
||||
fi
|
||||
else
|
||||
printlog "could not determine location of $appName"
|
||||
printlog "could not determine location of $appName" WARN
|
||||
fi
|
||||
else
|
||||
printlog "could not find $appName"
|
||||
printlog "could not find $appName" WARN
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -691,7 +709,7 @@ reopenClosedProcess() {
|
||||
processuser=$(ps aux | grep -i "${appName}" | grep -vi "grep" | awk '{print $1}')
|
||||
printlog "Reopened ${appName} as $processuser"
|
||||
else
|
||||
printlog "App not closed, so no reopen." DEBUG
|
||||
printlog "App not closed, so no reopen." INFO
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -701,7 +719,7 @@ installAppWithPath() { # $1: path to app to install in $targetDir
|
||||
|
||||
# check if app exists
|
||||
if [ ! -e "$appPath" ]; then
|
||||
cleanupAndExit 8 "could not find: $appPath" DEBUG
|
||||
cleanupAndExit 8 "could not find: $appPath" ERROR
|
||||
fi
|
||||
|
||||
# verify with spctl
|
||||
@@ -733,10 +751,12 @@ installAppWithPath() { # $1: path to app to install in $targetDir
|
||||
printlog "notifying"
|
||||
displaynotification "$message" "No update for $name!"
|
||||
fi
|
||||
cleanupAndExit 0 "No new version to install" INFO
|
||||
cleanupAndExit 0 "No new version to install" REG
|
||||
else
|
||||
printlog "Using force to install anyway."
|
||||
fi
|
||||
elif [[ -z $appversion ]]; then
|
||||
printlog "Installing $name version $appNewVersion on versionKey $versionKey."
|
||||
else
|
||||
printlog "Downloaded version of $name is $appNewVersion on versionKey $versionKey (replacing version $appversion)."
|
||||
fi
|
||||
@@ -752,7 +772,7 @@ installAppWithPath() { # $1: path to app to install in $targetDir
|
||||
printlog "notifying"
|
||||
displaynotification "$message" "Error updating $name!"
|
||||
fi
|
||||
cleanupAndExit 6 "Installed macOS is too old for this app." INFO
|
||||
cleanupAndExit 6 "Installed macOS is too old for this app." ERROR
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -773,7 +793,7 @@ installAppWithPath() { # $1: path to app to install in $targetDir
|
||||
|
||||
# remove existing application
|
||||
if [ -e "$targetDir/$appName" ]; then
|
||||
printlog "Removing existing $targetDir/$appName" DEBUG
|
||||
printlog "Removing existing $targetDir/$appName" WARN
|
||||
deleteAppOut=$(rm -Rfv "$targetDir/$appName" 2>&1)
|
||||
tempName="$targetDir/$appName"
|
||||
tempNameLength=$((${#tempName} + 10))
|
||||
@@ -784,16 +804,21 @@ installAppWithPath() { # $1: path to app to install in $targetDir
|
||||
|
||||
# copy app to /Applications
|
||||
printlog "Copy $appPath to $targetDir"
|
||||
if ! ditto "$appPath" "$targetDir/$appName"; then
|
||||
cleanupAndExit 7 "Error while copying" ERROR
|
||||
copyAppOut=$(ditto -v "$appPath" "$targetDir/$appName" 2>&1)
|
||||
copyAppStatus=$(echo $?)
|
||||
deduplicatelogs "$copyAppOut"
|
||||
printlog "Debugging enabled, App copy output was:\n$logoutput" DEBUG
|
||||
if [[ $copyAppStatus -ne 0 ]] ; then
|
||||
#if ! ditto "$appPath" "$targetDir/$appName"; then
|
||||
cleanupAndExit 7 "Error while copying:\n$logoutput" ERROR
|
||||
fi
|
||||
|
||||
# set ownership to current user
|
||||
if [[ "$currentUser" != "loginwindow" && $SYSTEMOWNER -ne 1 ]]; then
|
||||
printlog "Changing owner to $currentUser"
|
||||
printlog "Changing owner to $currentUser" WARN
|
||||
chown -R "$currentUser" "$targetDir/$appName"
|
||||
else
|
||||
printlog "No user logged in or SYSTEMOWNER=1, setting owner to root:wheel"
|
||||
printlog "No user logged in or SYSTEMOWNER=1, setting owner to root:wheel" WARN
|
||||
chown -R root:wheel "$targetDir/$appName"
|
||||
fi
|
||||
|
||||
@@ -823,7 +848,7 @@ mountDMG() {
|
||||
dmgmountStatus=$(echo $?)
|
||||
dmgmount=$(echo $dmgmountOut | tail -n 1 | cut -c 54- )
|
||||
deduplicatelogs "$dmgmountOut"
|
||||
|
||||
|
||||
if [[ $dmgmountStatus -ne 0 ]] ; then
|
||||
#if ! dmgmount=$(echo 'Y'$'\n' | hdiutil attach "$tmpDir/$archiveName" -nobrowse -readonly | tail -n 1 | cut -c 54- ); then
|
||||
cleanupAndExit 3 "Error mounting $tmpDir/$archiveName error:\n$logoutput" ERROR
|
||||
@@ -832,7 +857,7 @@ mountDMG() {
|
||||
cleanupAndExit 3 "Error accessing mountpoint for $tmpDir/$archiveName error:\n$logoutput" ERROR
|
||||
fi
|
||||
printlog "Debugging enabled, dmgmount output was:\n$logoutput" DEBUG
|
||||
|
||||
|
||||
printlog "Mounted: $dmgmount" INFO
|
||||
}
|
||||
|
||||
@@ -849,7 +874,7 @@ installFromPKG() {
|
||||
spctlOut=$(spctl -a -vv -t install "$archiveName" 2>&1 )
|
||||
spctlStatus=$(echo $?)
|
||||
printlog "spctlOut is $spctlOut" DEBUG
|
||||
|
||||
|
||||
teamID=$(echo $spctlOut | awk -F '(' '/origin=/ {print $2 }' | tr -d '()' )
|
||||
# Apple signed software has no teamID, grab entire origin instead
|
||||
if [[ -z $teamID ]]; then
|
||||
@@ -857,7 +882,7 @@ installFromPKG() {
|
||||
fi
|
||||
|
||||
deduplicatelogs "$spctlOut"
|
||||
|
||||
|
||||
if [[ $spctlStatus -ne 0 ]] ; then
|
||||
#if ! spctlout=$(spctl -a -vv -t install "$archiveName" 2>&1 ); then
|
||||
cleanupAndExit 4 "Error verifying $archiveName error:\n$logoutput" ERROR
|
||||
@@ -891,7 +916,7 @@ installFromPKG() {
|
||||
printlog "notifying"
|
||||
displaynotification "$message" "No update for $name!"
|
||||
fi
|
||||
cleanupAndExit 0 "No new version to install" INFO
|
||||
cleanupAndExit 0 "No new version to install" REQ
|
||||
else
|
||||
printlog "Using force to install anyway."
|
||||
fi
|
||||
@@ -965,27 +990,28 @@ installPkgInDmg() {
|
||||
if [[ -z $pkgName ]]; then
|
||||
# find first file ending with 'pkg'
|
||||
findfiles=$(find "$dmgmount" -iname "*.pkg" -type f -maxdepth 1 )
|
||||
printlog "Found pkg(s):\n$findfiles" DEBUG
|
||||
filearray=( ${(f)findfiles} )
|
||||
if [[ ${#filearray} -eq 0 ]]; then
|
||||
cleanupAndExit 20 "couldn't find pkg in dmg $archiveName" ERROR
|
||||
fi
|
||||
archiveName="${filearray[1]}"
|
||||
printlog "found pkg: $archiveName"
|
||||
else
|
||||
if ls "$tmpDir/$pkgName" ; then
|
||||
archiveName="$tmpDir/$pkgName"
|
||||
if [[ -s "$dmgmount/$pkgName" ]] ; then # was: $tmpDir
|
||||
archiveName="$dmgmount/$pkgName"
|
||||
else
|
||||
# try searching for pkg
|
||||
findfiles=$(find "$tmpDir" -iname "$pkgName")
|
||||
findfiles=$(find "$dmgmount" -iname "$pkgName") # was: $tmpDir
|
||||
printlog "Found pkg(s):\n$findfiles" DEBUG
|
||||
filearray=( ${(f)findfiles} )
|
||||
if [[ ${#filearray} -eq 0 ]]; then
|
||||
cleanupAndExit 20 "couldn't find pkg “$pkgName” in zip $archiveName" ERROR
|
||||
cleanupAndExit 20 "couldn't find pkg “$pkgName” in dmg $archiveName" ERROR
|
||||
fi
|
||||
# it is now safe to overwrite archiveName for installFromPKG
|
||||
archiveName="${filearray[1]}"
|
||||
printlog "found pkg: $archiveName"
|
||||
fi
|
||||
fi
|
||||
printlog "found pkg: $archiveName"
|
||||
|
||||
# installFromPkgs
|
||||
installFromPKG
|
||||
@@ -1000,6 +1026,7 @@ installPkgInZip() {
|
||||
if [[ -z $pkgName ]]; then
|
||||
# find first file ending with 'pkg'
|
||||
findfiles=$(find "$tmpDir" -iname "*.pkg" -type f -maxdepth 2 )
|
||||
printlog "Found pkg(s):\n$findfiles" DEBUG
|
||||
filearray=( ${(f)findfiles} )
|
||||
if [[ ${#filearray} -eq 0 ]]; then
|
||||
cleanupAndExit 20 "couldn't find pkg in zip $archiveName" ERROR
|
||||
@@ -1076,13 +1103,13 @@ runUpdateTool() {
|
||||
printlog "Error running $updateTool, Procceding with normal installation. Exit Status: $updateStatus Error:\n$logoutput" WARN
|
||||
return 1
|
||||
if [[ $type == updateronly ]]; then
|
||||
cleanupAndExit 77 "No Download URL Set, this is an update only application and the updater failed" WARN
|
||||
cleanupAndExit 77 "No Download URL Set, this is an update only application and the updater failed" ERROR
|
||||
fi
|
||||
elif [[ $updateStatus -eq 0 ]]; then
|
||||
printlog "Debugging enabled, update tool output was:\n$logoutput" DEBUG
|
||||
fi
|
||||
else
|
||||
printlog "couldn't find $updateTool, continuing normally"
|
||||
printlog "couldn't find $updateTool, continuing normally" WARN
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
@@ -1099,7 +1126,7 @@ finishing() {
|
||||
message="Installed $name, version $appversion"
|
||||
fi
|
||||
|
||||
printlog "$message"
|
||||
printlog "$message" REQ
|
||||
|
||||
if [[ $currentUser != "loginwindow" && ( $NOTIFY == "success" || $NOTIFY == "all" ) ]]; then
|
||||
printlog "notifying"
|
||||
@@ -1143,28 +1170,28 @@ autoload is-at-least
|
||||
|
||||
installedOSversion=$(sw_vers -productVersion)
|
||||
if ! is-at-least 10.14 $installedOSversion; then
|
||||
printlog "Installomator requires at least macOS 10.14 Mojave."
|
||||
printlog "Installomator requires at least macOS 10.14 Mojave." ERROR
|
||||
exit 98
|
||||
fi
|
||||
|
||||
# MARK: argument parsing
|
||||
if [[ $# -eq 0 ]]; then
|
||||
if [[ -z $label ]]; then # check if label is set inside script
|
||||
printlog "no label provided, printing labels"
|
||||
printlog "no label provided, printing labels" REQ
|
||||
grep -E '^[a-z0-9\_-]*(\)|\|\\)$' "$0" | tr -d ')|\' | grep -v -E '^(broken.*|longversion|version|valuesfromarguments)$' | sort
|
||||
#grep -E '^[a-z0-9\_-]*(\)|\|\\)$' "${labelFile}" | tr -d ')|\' | grep -v -E '^(broken.*|longversion|version|valuesfromarguments)$' | sort
|
||||
exit 0
|
||||
fi
|
||||
elif [[ $1 == "/" ]]; then
|
||||
# jamf uses sends '/' as the first argument
|
||||
printlog "shifting arguments for Jamf"
|
||||
printlog "shifting arguments for Jamf" REQ
|
||||
shift 3
|
||||
fi
|
||||
|
||||
while [[ -n $1 ]]; do
|
||||
if [[ $1 =~ ".*\=.*" ]]; then
|
||||
# if an argument contains an = character, send it to eval
|
||||
printlog "setting variable from argument $1"
|
||||
printlog "setting variable from argument $1" WARN
|
||||
eval $1
|
||||
else
|
||||
# assume it's a label
|
||||
@@ -1236,31 +1263,31 @@ currentUser=$(scutil <<< "show State:/Users/ConsoleUser" | awk '/Name :/ { print
|
||||
# MARK: check for root
|
||||
if [[ "$(whoami)" != "root" && "$DEBUG" -eq 0 ]]; then
|
||||
# not running as root
|
||||
cleanupAndExit 6 "not running as root, exiting"
|
||||
cleanupAndExit 6 "not running as root, exiting" ERROR
|
||||
fi
|
||||
|
||||
# MARK: labels in case statement
|
||||
case $label in
|
||||
longversion)
|
||||
# print the script version
|
||||
printlog "Installomater: version $VERSION ($VERSIONDATE)"
|
||||
printlog "Installomater: version $VERSION ($VERSIONDATE)" REQ
|
||||
exit 0
|
||||
;;
|
||||
valuesfromarguments)
|
||||
if [[ -z $name ]]; then
|
||||
printlog "need to provide 'name'"
|
||||
printlog "need to provide 'name'" ERROR
|
||||
exit 1
|
||||
fi
|
||||
if [[ -z $type ]]; then
|
||||
printlog "need to provide 'type'"
|
||||
printlog "need to provide 'type'" ERROR
|
||||
exit 1
|
||||
fi
|
||||
if [[ -z $downloadURL ]]; then
|
||||
printlog "need to provide 'downloadURL'"
|
||||
printlog "need to provide 'downloadURL'" ERROR
|
||||
exit 1
|
||||
fi
|
||||
if [[ -z $expectedTeamID ]]; then
|
||||
printlog "need to provide 'expectedTeamID'"
|
||||
printlog "need to provide 'expectedTeamID'" ERROR
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
@@ -1275,6 +1302,15 @@ valuesfromarguments)
|
||||
blockingProcesses=( "1Password Extension Helper" "1Password 7" "1Password (Safari)" "1PasswordNativeMessageHost" "1PasswordSafariAppExtension" )
|
||||
#forcefulQuit=YES
|
||||
;;
|
||||
1passwordcli)
|
||||
name="1Password CLI"
|
||||
type="pkg"
|
||||
#packageID="com.1password.op"
|
||||
downloadURL=$(curl -fs https://app-updates.agilebits.com/product_history/CLI | grep -m 1 -i op_apple_universal | cut -d'"' -f 2)
|
||||
appNewVersion=$(echo $downloadURL | sed -E 's/.*\/[a-zA-Z_]*([0-9.]*)\..*/\1/g')
|
||||
appCustomVersion(){ /usr/local/bin/op -v }
|
||||
expectedTeamID="2BUA8C4S2C"
|
||||
;;
|
||||
4kvideodownloader)
|
||||
name="4K Video Downloader"
|
||||
type="dmg"
|
||||
@@ -1413,6 +1449,13 @@ amazonchime)
|
||||
appNewVersion=$( curl -fsIL "${downloadURL}" | grep -i "^location" | awk '{print $2}' | sed -E 's/.*\/[a-zA-Z.\-]*-([0-9.]*)\..*/\1/g' )
|
||||
expectedTeamID="94KV3E626L"
|
||||
;;
|
||||
amazoncorretto8jdk)
|
||||
name="Amazon Corretto 8 JDK"
|
||||
type="pkg"
|
||||
downloadURL="https://corretto.aws/downloads/latest/amazon-corretto-8-x64-macos-jdk.pkg"
|
||||
appNewVersion=$(curl -s https://raw.githubusercontent.com/corretto/corretto-8/develop/CHANGELOG.md | grep "## Corretto version" | head -n 1 | awk '{ print $4; exit}')
|
||||
expectedTeamID="94KV3E626L"
|
||||
;;
|
||||
amazonworkspaces)
|
||||
# credit: Isaac Ordonez, Mann consulting (@mannconsulting)
|
||||
name="Workspaces"
|
||||
@@ -1442,10 +1485,10 @@ apparency)
|
||||
expectedTeamID="936EB786NH"
|
||||
;;
|
||||
appcleaner)
|
||||
# credit: Tadayuki Onishi (@kenchan0130)
|
||||
name="AppCleaner"
|
||||
type="zip"
|
||||
downloadURL=$(curl -fs https://freemacsoft.net/appcleaner/Updates.xml | xpath '//rss/channel/*/enclosure/@url' 2>/dev/null | tr " " "\n" | sort | tail -1 | cut -d '"' -f 2)
|
||||
downloadURL=$(curl -fs https://freemacsoft.net/appcleaner/Updates.xml | xpath '//rss/channel/item[last()]/enclosure/@url' 2>/dev/null | tr " " "\n" | sort | tail -1 | cut -d '"' -f 2)
|
||||
appNewVersion=$(curl -fsL "https://freemacsoft.net/appcleaner/Updates.xml" | xpath '//rss/channel/item[last()]/enclosure/@sparkle:shortVersionString' 2>/dev/null | cut -d '"' -f 2)
|
||||
expectedTeamID="X85ZX835W9"
|
||||
;;
|
||||
applenyfonts)
|
||||
@@ -1543,6 +1586,16 @@ authydesktop)
|
||||
appNewVersion="$(curl -sfL --output /dev/null -r 0-0 "${downloadURL}" --remote-header-name --remote-name -w "%{url_effective}\n" | grep -o -E '([a-zA-Z0-9\_.%-]*)\.(dmg|pkg|zip|tbz)$' | sed -E 's/.*-([0-9.]*)\.dmg/\1/g')"
|
||||
expectedTeamID="9EVH78F4V4"
|
||||
;;
|
||||
autodeskfusion360admininstall)
|
||||
name="Autodesk Fusion 360 Admin Install"
|
||||
type="pkg"
|
||||
packageID="com.autodesk.edu.fusion360"
|
||||
downloadURL="https://dl.appstreaming.autodesk.com/production/installers/Autodesk%20Fusion%20360%20Admin%20Install.pkg"
|
||||
appNewVersion=$(curl -fs "https://dl.appstreaming.autodesk.com/production/97e6dd95735340d6ad6e222a520454db/73e72ada57b7480280f7a6f4a289729f/full.json" | sed -E 's/.*build-version":"([[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+).*/\1/g')
|
||||
expectedTeamID="XXKJ396S2Y"
|
||||
appName="Autodesk Fusion 360.app"
|
||||
blockingProcesses=( "Autodesk Fusion 360" "Fusion 360" )
|
||||
;;
|
||||
autodmg)
|
||||
# credit: Mischa van der Bent (@mischavdbent)
|
||||
name="AutoDMG"
|
||||
@@ -1581,6 +1634,20 @@ awsvpnclient)
|
||||
expectedTeamID="94KV3E626L"
|
||||
appNewVersion=$(curl -is "https://beta2.communitypatch.com/jamf/v1/ba1efae22ae74a9eb4e915c31fef5dd2/patch/AWSVPNClient" | grep currentVersion | tr ',' '\n' | grep currentVersion | cut -d '"' -f 4)
|
||||
;;
|
||||
axurerp10)
|
||||
name="Axure RP 10"
|
||||
type="dmg"
|
||||
if [[ $(arch) == "arm64" ]]; then
|
||||
downloadURL="https://d3uii9pxdigrx1.cloudfront.net/AxureRP-Setup-arm64.dmg"
|
||||
elif [[ $(arch) == "i386" ]]; then
|
||||
downloadURL="https://d3uii9pxdigrx1.cloudfront.net/AxureRP-Setup.dmg"
|
||||
fi
|
||||
appNewVersion=$( curl -sL https://www.axure.com/release-history | grep -Eo '[0-9]{1,4}\.[0-9]{1,4}\.[0-9]{1,4}\.[0-9]{1,4}' -m 1 )
|
||||
expectedTeamID="HUMW6UU796"
|
||||
versionKey="CFBundleVersion"
|
||||
appName="Axure RP 10.app"
|
||||
blockingProcesses=( "Axure RP 10" )
|
||||
;;
|
||||
balenaetcher)
|
||||
name="balenaEtcher"
|
||||
type="dmg"
|
||||
@@ -1708,6 +1775,13 @@ cakebrew)
|
||||
appNewVersion=$( curl -fsL "https://www.cakebrew.com/appcast/profileInfo.php" | xpath '//rss/channel/item[1]/enclosure/@sparkle:shortVersionString' 2>/dev/null | cut -d '"' -f 2 )
|
||||
expectedTeamID="R85D3K8ATT"
|
||||
;;
|
||||
calcservice)
|
||||
name="CalcService"
|
||||
type="zip"
|
||||
downloadURL="$(curl -fs -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15" "https://www.devontechnologies.com/support/download" | tr '"' "\n" | grep -o "http.*download.*.zip" | grep -i calcservice | head -1)"
|
||||
appNewVersion="$(echo $downloadURL | sed -E 's/.*\/([0-9.]*)\/.*/\1/g')"
|
||||
expectedTeamID="679S2QUWR8"
|
||||
;;
|
||||
calibre)
|
||||
# credit: Drew Diver (@grumpydrew on MacAdmins Slack)
|
||||
name="calibre"
|
||||
@@ -1782,6 +1856,13 @@ clickshare)
|
||||
downloadURL=https://www.barco.com$(curl -fs "https://www.barco.com/en/clickshare/app" | grep -E -o '(\/\S*Download\?FileNumber=R3306192\S*ShowDownloadPage=False)' | tail -1)
|
||||
expectedTeamID="P6CDJZR997"
|
||||
;;
|
||||
clipy)
|
||||
name="Clipy"
|
||||
type="dmg"
|
||||
downloadURL=$(downloadURLFromGit Clipy Clipy)
|
||||
appNewVersion=$(versionFromGit Clipy Clipy)
|
||||
expectedTeamID="BBCHAJ584H"
|
||||
;;
|
||||
closeio)
|
||||
name="Close.io"
|
||||
type="dmg"
|
||||
@@ -1928,12 +2009,13 @@ devonthink)
|
||||
appNewVersion=$( echo ${downloadURL} | tr '/' '\n' | grep "[0-9]" | grep "[.]" | head -1 )
|
||||
expectedTeamID="679S2QUWR8"
|
||||
;;
|
||||
dialog)
|
||||
dialog|\
|
||||
swiftdialog)
|
||||
name="Dialog"
|
||||
type="pkg"
|
||||
packageID="au.csiro.dialogcli"
|
||||
downloadURL="$(downloadURLFromGit bartreardon Dialog)"
|
||||
appNewVersion="$(versionFromGit bartreardon Dialog)"
|
||||
downloadURL="$(downloadURLFromGit bartreardon swiftDialog)"
|
||||
appNewVersion="$(versionFromGit bartreardon swiftDialog)"
|
||||
expectedTeamID="PWA5E9TQ59"
|
||||
;;
|
||||
dialpad)
|
||||
@@ -1969,6 +2051,15 @@ docker)
|
||||
fi
|
||||
expectedTeamID="9BNSXJN65R"
|
||||
;;
|
||||
dockutil)
|
||||
name="dockutil"
|
||||
type="pkg"
|
||||
packageID="dockutil.cli.tool"
|
||||
downloadURL=$(downloadURLFromGit "kcrawford" "dockutil")
|
||||
appNewVersion=$(versionFromGit "kcrawford" "dockutil")
|
||||
expectedTeamID="Z5J8CJBUWC"
|
||||
blockingProcesses=( NONE )
|
||||
;;
|
||||
drift)
|
||||
# credit Elena Ackley (@elenaelago)
|
||||
name="Drift"
|
||||
@@ -1990,6 +2081,13 @@ easeusdatarecoverywizard)
|
||||
#appNewVersion=""
|
||||
expectedTeamID="DLLVW95FSM"
|
||||
;;
|
||||
easyfind)
|
||||
name="EasyFind"
|
||||
type="zip"
|
||||
downloadURL="$(curl -fs "https://www.devontechnologies.com/apps/freeware" | grep -o "http.*download.*.zip" | grep -i easyfind)"
|
||||
appNewVersion="$(echo $downloadURL | sed -E 's/.*\/([0-9.]*)\/.*/\1/g')"
|
||||
expectedTeamID="679S2QUWR8"
|
||||
;;
|
||||
egnyte)
|
||||
# credit: #MoeMunyoki from MacAdmins Slack
|
||||
name="Egnyte Connect"
|
||||
@@ -2245,15 +2343,8 @@ golang)
|
||||
googlechrome)
|
||||
name="Google Chrome"
|
||||
type="dmg"
|
||||
if [[ $(arch) != "i386" ]]; then
|
||||
printlog "Architecture: arm64 (not i386)"
|
||||
downloadURL="https://dl.google.com/chrome/mac/universal/stable/GGRO/googlechrome.dmg"
|
||||
appNewVersion=$(curl -s https://omahaproxy.appspot.com/history | awk -F',' '/mac_arm64,stable/{print $3; exit}')
|
||||
else
|
||||
printlog "Architecture: i386"
|
||||
downloadURL="https://dl.google.com/chrome/mac/stable/GGRO/googlechrome.dmg"
|
||||
appNewVersion=$(curl -s https://omahaproxy.appspot.com/history | awk -F',' '/mac,stable/{print $3; exit}')
|
||||
fi
|
||||
downloadURL="https://dl.google.com/chrome/mac/universal/stable/GGRO/googlechrome.dmg"
|
||||
appNewVersion=$(curl -s https://omahaproxy.appspot.com/history | awk -F',' '/mac_arm64,stable/{print $3; exit}')
|
||||
expectedTeamID="EQHXZ8M8AV"
|
||||
;;
|
||||
googlechromepkg)
|
||||
@@ -2332,6 +2423,15 @@ gpgsync)
|
||||
appNewVersion="$(versionFromGit firstlookmedia gpgsync)"
|
||||
expectedTeamID="P24U45L8P5"
|
||||
;;
|
||||
grammarly)
|
||||
name="Grammarly Desktop"
|
||||
type="dmg"
|
||||
packageID="com.grammarly.ProjectLlama"
|
||||
downloadURL=$(curl -fsL "https://download-mac.grammarly.com/appcast.xml" | xpath '//rss/channel/item[1]/enclosure/@url' 2>/dev/null | cut -d '"' -f 2)
|
||||
expectedTeamID="W8F64X92K3"
|
||||
appNewVersion=$(curl -is "https://download-mac.grammarly.com/appcast.xml" | grep sparkle:version | tr ',' '\n' | grep sparkle:version | cut -d '"' -f 4)
|
||||
appName="Grammarly Installer.app"
|
||||
;;
|
||||
grandperspective)
|
||||
name="GrandPerspective"
|
||||
type="dmg"
|
||||
@@ -2386,6 +2486,13 @@ hazel)
|
||||
appNewVersion=$(curl -fsI https://www.noodlesoft.com/Products/Hazel/download | grep -i "^location" | awk '{print $2}' | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)\..*/\1/g')
|
||||
expectedTeamID="86Z3GCJ4MF"
|
||||
;;
|
||||
houdahspot)
|
||||
name="HoudahSpot"
|
||||
type="zip"
|
||||
downloadURL="$(curl -fs https://www.houdah.com/houdahSpot/updates/cast6.php | xpath '(//rss/channel/item/enclosure/@url)[1]' 2>/dev/null | head -1 | cut -d '"' -f 2)"
|
||||
appNewVersion="$(curl -fs https://www.houdah.com/houdahSpot/updates/cast6.php | xpath '(//rss/channel/item/enclosure/@sparkle:shortVersionString)[1]' 2>/dev/null | head -1 | cut -d '"' -f 2)"
|
||||
expectedTeamID="DKGQD8H8ZY"
|
||||
;;
|
||||
hpeasyadmin)
|
||||
# credit: Søren Theilgaard (@theilgaard)
|
||||
name="HP Easy Admin"
|
||||
@@ -2795,7 +2902,11 @@ loom)
|
||||
# credit: Lance Stephens (@pythoninthegrass on MacAdmins Slack)
|
||||
name="Loom"
|
||||
type="dmg"
|
||||
downloadURL=https://cdn.loom.com/desktop-packages/$(curl -fs https://s3-us-west-2.amazonaws.com/loom.desktop.packages/loom-inc-production/desktop-packages/latest-mac.yml | awk '/url/ && /dmg/ {print $3}' | head -1)
|
||||
if [[ $(arch) == "arm64" ]]; then
|
||||
downloadURL=https://cdn.loom.com/desktop-packages/$(curl -fs https://s3-us-west-2.amazonaws.com/loom.desktop.packages/loom-inc-production/desktop-packages/latest-mac.yml | awk '/url/ && /arm64/ && /dmg/ {print $3}' | head -1)
|
||||
elif [[ $(arch) == "i386" ]]; then
|
||||
downloadURL=https://cdn.loom.com/desktop-packages/$(curl -fs https://s3-us-west-2.amazonaws.com/loom.desktop.packages/loom-inc-production/desktop-packages/latest-mac.yml | awk '/url/ && /dmg/ {print $3}' | head -1)
|
||||
fi
|
||||
appNewVersion=$(curl -fs https://s3-us-west-2.amazonaws.com/loom.desktop.packages/loom-inc-production/desktop-packages/latest-mac.yml | awk '/version/ {print $2}' )
|
||||
expectedTeamID="QGD2ZPXZZG"
|
||||
;;
|
||||
@@ -2823,6 +2934,15 @@ lulu)
|
||||
appNewVersion=$(versionFromGit objective-see LuLu)
|
||||
expectedTeamID="VBG97UB4TA"
|
||||
;;
|
||||
macadminspython)
|
||||
name="MacAdmins Python"
|
||||
type="pkg"
|
||||
packageID="org.macadmins.python.recommended"
|
||||
downloadURL=$(curl --silent --fail "https://api.github.com/repos/macadmins/python/releases/latest" | awk -F '"' "/browser_download_url/ && /python_recommended_signed/ { print \$4; exit }")
|
||||
appNewVersion=$(grep -o -E '\d+\.\d+\.\d+\.\d+' <<< $downloadURL | head -n 1)
|
||||
expectedTeamID="9GQZ7KUFR6"
|
||||
blockingProcesses=( NONE )
|
||||
;;
|
||||
maccyapp)
|
||||
name="Maccy"
|
||||
type="zip"
|
||||
@@ -2919,6 +3039,16 @@ microsoftautoupdate)
|
||||
#updateTool="/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate"
|
||||
#updateToolArguments=( --install --apps MSau04 )
|
||||
;;
|
||||
microsoftazuredatastudio|\
|
||||
azuredatastudio)
|
||||
name="Azure Data Studio"
|
||||
type="zip"
|
||||
downloadURL=$( curl -sL https://github.com/microsoft/azuredatastudio/releases/latest | grep 'macOS ZIP' | grep -Eo "(http|https)://[a-zA-Z0-9./?=_%:-]*" )
|
||||
appNewVersion=$(versionFromGit microsoft azuredatastudio )
|
||||
expectedTeamID="UBF8T346G9"
|
||||
appName="Azure Data Studio.app"
|
||||
blockingProcesses=( "Azure Data Studio" )
|
||||
;;
|
||||
microsoftazurestorageexplorer)
|
||||
name="Microsoft Azure Storage Explorer"
|
||||
type="zip"
|
||||
@@ -2941,8 +3071,9 @@ microsoftcompanyportal)
|
||||
updateTool="/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate"
|
||||
updateToolArguments=( --install --apps IMCP01 )
|
||||
;;
|
||||
microsoftdefender|\
|
||||
microsoftdefenderatp)
|
||||
name="Microsoft Defender ATP"
|
||||
name="Microsoft Defender"
|
||||
type="pkg"
|
||||
downloadURL="https://go.microsoft.com/fwlink/?linkid=2097502"
|
||||
appNewVersion=$(curl -fs https://macadmins.software/latest.xml | xpath '//latest/package[id="com.microsoft.defender.standalone"]/version' 2>/dev/null | sed -E 's/<version>([0-9.]*) .*/\1/')
|
||||
@@ -3292,6 +3423,13 @@ muzzle)
|
||||
appNewVersion=$(curl -fs https://muzzleapp.com/updates/ | grep -io 'h2.*Version.* [0-9.]*.*h2' | head -1 | sed -E 's/.*ersion *([0-9.]*).*/\1/g')
|
||||
expectedTeamID="49EYHPJ4Q3"
|
||||
;;
|
||||
nanosaur)
|
||||
name="Nanosaur"
|
||||
type="dmg"
|
||||
downloadURL=$(downloadURLFromGit jorio Nanosaur)
|
||||
appNewVersion=$(versionFromGit jorio Nanosaur)
|
||||
expectedTeamID="RVNL7XC27G"
|
||||
;;
|
||||
netnewswire)
|
||||
name="NetNewsWire"
|
||||
type="zip"
|
||||
@@ -3494,6 +3632,15 @@ pacifist)
|
||||
downloadURL="https://charlessoft.com/cgi-bin/pacifist_download.cgi?type=dmg"
|
||||
expectedTeamID="HRLUCP7QP4"
|
||||
;;
|
||||
|
||||
packages)
|
||||
#NOTE: Packages is signed but _not_ notarized, so spctl will reject it
|
||||
name="Packages"
|
||||
type="pkgInDmg"
|
||||
pkgName="Install Packages.pkg"
|
||||
downloadURL="http://s.sudre.free.fr/Software/files/Packages.dmg"
|
||||
expectedTeamID="NL5M9E394P"
|
||||
;;
|
||||
pandoc)
|
||||
name="Pandoc"
|
||||
type="pkg"
|
||||
@@ -4030,13 +4177,14 @@ superhuman)
|
||||
expectedTeamID="6XHFYUTQGX"
|
||||
;;
|
||||
supportapp)
|
||||
# credit: Søren Theilgaard (@theilgaard)
|
||||
name="Support"
|
||||
type="pkg"
|
||||
packageID="nl.root3.support"
|
||||
downloadURL=$(downloadURLFromGit root3nl SupportApp)
|
||||
appNewVersion=$(versionFromGit root3nl SupportApp)
|
||||
expectedTeamID="98LJ4XBGYK"
|
||||
uid=$(id -u "$currentUser")
|
||||
launchctl bootout gui/${uid} "/Library/LaunchAgents/nl.root3.support.plist"
|
||||
;;
|
||||
suspiciouspackage)
|
||||
# credit: Mischa van der Bent (@mischavdbent)
|
||||
@@ -4144,6 +4292,13 @@ telegram)
|
||||
appNewVersion=$( curl -fs https://macos.telegram.org | grep anchor | head -1 | sed -E 's/.*a>([0-9.]*) .*/\1/g' )
|
||||
expectedTeamID="6N38VWS5BX"
|
||||
;;
|
||||
tembo)
|
||||
name="Tembo"
|
||||
type="zip"
|
||||
downloadURL="$(curl -fs https://www.houdah.com/tembo/updates/cast2.xml | xpath '(//rss/channel/item/enclosure/@url)[1]' 2>/dev/null | head -1 | cut -d '"' -f 2)"
|
||||
appNewVersion="$(curl -fs https://www.houdah.com/tembo/updates/cast2.xml | xpath '(//rss/channel/item/enclosure/@sparkle:shortVersionString)[1]' 2>/dev/null | head -1 | cut -d '"' -f 2)"
|
||||
expectedTeamID="DKGQD8H8ZY"
|
||||
;;
|
||||
textexpander)
|
||||
name="TextExpander"
|
||||
type="dmg"
|
||||
@@ -4419,6 +4574,14 @@ wireshark)
|
||||
appNewVersion=$(curl -fs https://www.wireshark.org/download.html | grep -i "href.*_stable" | sed -E 's/.*\(([0-9.]*)\).*/\1/g')
|
||||
expectedTeamID="7Z6EMTD2C6"
|
||||
;;
|
||||
wordservice)
|
||||
name="WordService"
|
||||
type="zip"
|
||||
downloadURL="$(curl -fs -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15" "https://www.devontechnologies.com/support/download" | tr '"' "\n" | grep -o "http.*download.*.zip" | grep -i wordservice | head -1)"
|
||||
appNewVersion="$(echo $downloadURL | sed -E 's/.*\/([0-9.]*)\/.*/\1/g')"
|
||||
appNewVersion=""
|
||||
expectedTeamID="679S2QUWR8"
|
||||
;;
|
||||
wwdc)
|
||||
# credit: Søren Theilgaard (@theilgaard)
|
||||
name="WWDC"
|
||||
@@ -4441,6 +4604,14 @@ xink)
|
||||
appNewVersion=$(curl -fs "https://downloads.xink.io/macos/appcast" | xpath '(//rss/channel/item/enclosure/@sparkle:version)[1]' 2>/dev/null | head -1 | cut -d '"' -f 2)
|
||||
expectedTeamID="F287823HVS"
|
||||
;;
|
||||
xmenu)
|
||||
name="XMenu"
|
||||
type="zip"
|
||||
downloadURL="$(curl -fs "https://www.devontechnologies.com/apps/freeware" | grep -o "http.*download.*.zip" | grep -i xmenu)"
|
||||
appNewVersion="$(echo $downloadURL | sed -E 's/.*\/([0-9.]*)\/.*/\1/g')"
|
||||
expectedTeamID="679S2QUWR8"
|
||||
;;
|
||||
|
||||
xquartz)
|
||||
# credit: AP Orlebeke (@apizz)
|
||||
name="XQuartz"
|
||||
@@ -4506,6 +4677,7 @@ zoom)
|
||||
downloadURL="https://zoom.us/client/latest/ZoomInstallerIT.pkg"
|
||||
appNewVersion="$(curl -fsIL ${downloadURL} | grep -i ^location | cut -d "/" -f5)"
|
||||
expectedTeamID="BJ4HAAB9B3"
|
||||
versionKey="CFBundleVersion"
|
||||
;;
|
||||
zoomclient)
|
||||
name="zoom.us"
|
||||
@@ -4527,6 +4699,7 @@ zoomgov)
|
||||
downloadURL="https://www.zoomgov.com/client/latest/ZoomInstallerIT.pkg"
|
||||
appNewVersion="$(curl -fsIL ${downloadURL} | grep -i ^location | cut -d "/" -f5)"
|
||||
expectedTeamID="BJ4HAAB9B3"
|
||||
versionKey="CFBundleVersion"
|
||||
;;
|
||||
zoomrooms)
|
||||
name="ZoomRooms"
|
||||
@@ -4605,13 +4778,13 @@ zulujdk8)
|
||||
*)
|
||||
# unknown label
|
||||
#printlog "unknown label $label"
|
||||
cleanupAndExit 1 "unknown label $label"
|
||||
cleanupAndExit 1 "unknown label $label" ERROR
|
||||
;;
|
||||
esac
|
||||
|
||||
# Are we only asked to return label name
|
||||
if [[ $RETURN_LABEL_NAME -eq 1 ]]; then
|
||||
printlog "Only returning label name."
|
||||
printlog "Only returning label name." REQ
|
||||
printlog "$name"
|
||||
echo "$name"
|
||||
exit
|
||||
@@ -4622,7 +4795,7 @@ fi
|
||||
if [[ ${INTERRUPT_DND} = "no" ]]; then
|
||||
# Check if a fullscreen app is active
|
||||
if hasDisplaySleepAssertion; then
|
||||
cleanupAndExit 1 "active display sleep assertion detected, aborting"
|
||||
cleanupAndExit 1 "active display sleep assertion detected, aborting" ERROR
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -4659,6 +4832,11 @@ case $LOGO in
|
||||
LOGO="/Library/Addigy/macmanage/MacManage.app/Contents/Resources/atom.icns"
|
||||
if [[ -z $MDMProfileName ]]; then; MDMProfileName="MDM Profile"; fi
|
||||
;;
|
||||
microsoft)
|
||||
# Microsoft Endpoint Manager (Intune)
|
||||
LOGO="/Library/Intune/Microsoft Intune Agent.app/Contents/Resources/AppIcon.icns"
|
||||
if [[ -z $MDMProfileName ]]; then; MDMProfileName="Management Profile"; fi
|
||||
;;
|
||||
esac
|
||||
if [[ ! -a "${LOGO}" ]]; then
|
||||
if [[ $(sw_vers -buildVersion) > "19" ]]; then
|
||||
@@ -4667,9 +4845,9 @@ if [[ ! -a "${LOGO}" ]]; then
|
||||
LOGO="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
fi
|
||||
fi
|
||||
printlog "LOGO=${LOGO}"
|
||||
printlog "LOGO=${LOGO}" INFO
|
||||
|
||||
printlog "Label type: $type"
|
||||
printlog "Label type: $type" INFO
|
||||
|
||||
# MARK: extract info from data
|
||||
if [ -z "$archiveName" ]; then
|
||||
@@ -4691,7 +4869,7 @@ if [ -z "$archiveName" ]; then
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
printlog "archiveName: $archiveName" DEBUG
|
||||
printlog "archiveName: $archiveName" INFO
|
||||
|
||||
if [ -z "$appName" ]; then
|
||||
# when not given derive from name
|
||||
@@ -4709,14 +4887,13 @@ if [ -z "$targetDir" ]; then
|
||||
updateronly)
|
||||
;;
|
||||
*)
|
||||
printlog "Cannot handle type $type"
|
||||
cleanupAndExit 99
|
||||
cleanupAndExit 99 "Cannot handle type $type" ERROR
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if [[ -z $blockingProcesses ]]; then
|
||||
printlog "no blocking processes defined, using $name as default"
|
||||
printlog "no blocking processes defined, using $name as default" INFO
|
||||
blockingProcesses=( $name )
|
||||
fi
|
||||
|
||||
@@ -4732,8 +4909,7 @@ fi
|
||||
# MARK: change directory to temporary working directory
|
||||
printlog "Changing directory to $tmpDir" DEBUG
|
||||
if ! cd "$tmpDir"; then
|
||||
printlog "error changing directory $tmpDir"
|
||||
cleanupAndExit 1
|
||||
cleanupAndExit 1 "error changing directory $tmpDir" ERROR
|
||||
fi
|
||||
|
||||
# MARK: get installed version
|
||||
@@ -4756,10 +4932,10 @@ if [[ -n $appNewVersion ]]; then
|
||||
printlog "notifying"
|
||||
displaynotification "$message" "No update for $name!"
|
||||
fi
|
||||
cleanupAndExit 0 "No newer version."
|
||||
cleanupAndExit 0 "No newer version." REQ
|
||||
fi
|
||||
else
|
||||
printlog "DEBUG mode 1 enabled, not exiting, but there is no new version of app."
|
||||
printlog "DEBUG mode 1 enabled, not exiting, but there is no new version of app." WARN
|
||||
fi
|
||||
fi
|
||||
else
|
||||
@@ -4772,13 +4948,12 @@ if [[ (-n $appversion && -n "$updateTool") || "$type" == "updateronly" ]]; then
|
||||
if [[ $DEBUG -ne 1 ]]; then
|
||||
if runUpdateTool; then
|
||||
finishing
|
||||
cleanupAndExit 0
|
||||
cleanupAndExit 0 "updateTool has run" REQ
|
||||
elif [[ $type == "updateronly" ]];then
|
||||
printlog "type is $type so we end here."
|
||||
cleanupAndExit 0
|
||||
cleanupAndExit 0 "type is $type so we end here." REQ
|
||||
fi # otherwise continue
|
||||
else
|
||||
printlog "DEBUG mode 1 enabled, not running update tool"
|
||||
printlog "DEBUG mode 1 enabled, not running update tool" WARN
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -4801,14 +4976,14 @@ else
|
||||
deduplicatelogs "$curlDownload"
|
||||
if [[ $curlDownloadStatus -ne 0 ]]; then
|
||||
#if ! curl --location --fail --silent "$downloadURL" -o "$archiveName"; then
|
||||
printlog "error downloading $downloadURL"
|
||||
printlog "error downloading $downloadURL" ERROR
|
||||
message="$name update/installation failed. This will be logged, so IT can follow up."
|
||||
if [[ $currentUser != "loginwindow" && $NOTIFY == "all" ]]; then
|
||||
printlog "notifying"
|
||||
if [[ $updateDetected == "YES" ]]; then
|
||||
displaynotification "$message" "Error updating $name" ERROR
|
||||
displaynotification "$message" "Error updating $name"
|
||||
else
|
||||
displaynotification "$message" "Error installing $name" ERROR
|
||||
displaynotification "$message" "Error installing $name"
|
||||
fi
|
||||
fi
|
||||
printlog "File list: $(ls -lh "$archiveName")" ERROR
|
||||
@@ -4873,8 +5048,7 @@ case $type in
|
||||
installAppInDmgInZip
|
||||
;;
|
||||
*)
|
||||
printlog "Cannot handle type $type"
|
||||
cleanupAndExit 99
|
||||
cleanupAndExit 99 "Cannot handle type $type" ERROR
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -4882,4 +5056,4 @@ esac
|
||||
finishing
|
||||
|
||||
# all done!
|
||||
cleanupAndExit 0
|
||||
cleanupAndExit 0 "All done!" REQ
|
||||
|
||||
20
Labels.txt
20
Labels.txt
@@ -1,4 +1,5 @@
|
||||
1password7
|
||||
1passwordcli
|
||||
4kvideodownloader
|
||||
8x8
|
||||
abstract
|
||||
@@ -16,6 +17,7 @@ alephone
|
||||
alfred
|
||||
alttab
|
||||
amazonchime
|
||||
amazoncorretto8jdk
|
||||
amazonworkspaces
|
||||
androidfiletransfer
|
||||
anydesk
|
||||
@@ -34,11 +36,14 @@ atext
|
||||
atom
|
||||
audacity
|
||||
authydesktop
|
||||
autodeskfusion360admininstall
|
||||
autodmg
|
||||
autopkgr
|
||||
aviatrix
|
||||
awscli2
|
||||
awsvpnclient
|
||||
axurerp10
|
||||
azuredatastudio
|
||||
balenaetcher
|
||||
balsamiqwireframes
|
||||
bartender
|
||||
@@ -55,6 +60,7 @@ brave
|
||||
bugdom
|
||||
caffeine
|
||||
cakebrew
|
||||
calcservice
|
||||
calibre
|
||||
camostudio
|
||||
camtasia
|
||||
@@ -64,6 +70,7 @@ cisdem-documentreader
|
||||
citrixworkspace
|
||||
clevershare2
|
||||
clickshare
|
||||
clipy
|
||||
closeio
|
||||
cloudya
|
||||
code42
|
||||
@@ -88,9 +95,11 @@ dialpad
|
||||
discord
|
||||
diskspace
|
||||
docker
|
||||
dockutil
|
||||
drift
|
||||
dropbox
|
||||
easeusdatarecoverywizard
|
||||
easyfind
|
||||
egnyte
|
||||
element
|
||||
eraseinstall
|
||||
@@ -130,6 +139,7 @@ googlesoftwareupdate
|
||||
gotomeeting
|
||||
gpgsuite
|
||||
gpgsync
|
||||
grammarly
|
||||
grandperspective
|
||||
grasshopper
|
||||
gyazo
|
||||
@@ -137,6 +147,7 @@ gyazogif
|
||||
hancock
|
||||
handbrake
|
||||
hazel
|
||||
houdahspot
|
||||
hpeasyadmin
|
||||
hpeasystart
|
||||
hyper
|
||||
@@ -187,6 +198,7 @@ loom
|
||||
lowprofile
|
||||
lucifer
|
||||
lulu
|
||||
macadminspython
|
||||
maccyapp
|
||||
macfuse
|
||||
macports
|
||||
@@ -197,8 +209,10 @@ marathoninfinity
|
||||
mattermost
|
||||
menumeters
|
||||
microsoftautoupdate
|
||||
microsoftazuredatastudio
|
||||
microsoftazurestorageexplorer
|
||||
microsoftcompanyportal
|
||||
microsoftdefender
|
||||
microsoftdefenderatp
|
||||
microsoftedge
|
||||
microsoftedgeconsumerstable
|
||||
@@ -229,6 +243,7 @@ montereyblocker
|
||||
mowgliiitsycal
|
||||
musescore
|
||||
muzzle
|
||||
nanosaur
|
||||
netnewswire
|
||||
nextcloud
|
||||
nomad
|
||||
@@ -255,6 +270,7 @@ opera
|
||||
ottomatic
|
||||
overflow
|
||||
pacifist
|
||||
packages
|
||||
pandoc
|
||||
paretosecurity
|
||||
parsec
|
||||
@@ -334,6 +350,7 @@ sublimetext
|
||||
superhuman
|
||||
supportapp
|
||||
suspiciouspackage
|
||||
swiftdialog
|
||||
swiftruntimeforcommandlinetools
|
||||
sync
|
||||
tableaudesktop
|
||||
@@ -347,6 +364,7 @@ teamviewerhost
|
||||
teamviewerqs
|
||||
techsmithcapture
|
||||
telegram
|
||||
tembo
|
||||
textexpander
|
||||
textmate
|
||||
theunarchiver
|
||||
@@ -384,9 +402,11 @@ whatsapp
|
||||
wickrme
|
||||
wickrpro
|
||||
wireshark
|
||||
wordservice
|
||||
wwdc
|
||||
xeroxphaser7800
|
||||
xink
|
||||
xmenu
|
||||
xquartz
|
||||
yed
|
||||
yubikeymanagerqt
|
||||
|
||||
@@ -12,7 +12,7 @@ We have put a lot of work into making it stable and safe, but we cannot - of cou
|
||||
|
||||
## Authors
|
||||
|
||||
Intallomator was original inspired by the download scripts from William Smith and Sander Schram, and created by:
|
||||
Intallomator was originally inspired by the download scripts from William Smith and Sander Schram, and created by:
|
||||
Armin Briegel - @scriptingosx
|
||||
|
||||
Later on a few more contributers came on the project:
|
||||
|
||||
@@ -3,28 +3,28 @@ autoload is-at-least
|
||||
|
||||
installedOSversion=$(sw_vers -productVersion)
|
||||
if ! is-at-least 10.14 $installedOSversion; then
|
||||
printlog "Installomator requires at least macOS 10.14 Mojave."
|
||||
printlog "Installomator requires at least macOS 10.14 Mojave." ERROR
|
||||
exit 98
|
||||
fi
|
||||
|
||||
# MARK: argument parsing
|
||||
if [[ $# -eq 0 ]]; then
|
||||
if [[ -z $label ]]; then # check if label is set inside script
|
||||
printlog "no label provided, printing labels"
|
||||
printlog "no label provided, printing labels" REQ
|
||||
grep -E '^[a-z0-9\_-]*(\)|\|\\)$' "$0" | tr -d ')|\' | grep -v -E '^(broken.*|longversion|version|valuesfromarguments)$' | sort
|
||||
#grep -E '^[a-z0-9\_-]*(\)|\|\\)$' "${labelFile}" | tr -d ')|\' | grep -v -E '^(broken.*|longversion|version|valuesfromarguments)$' | sort
|
||||
exit 0
|
||||
fi
|
||||
elif [[ $1 == "/" ]]; then
|
||||
# jamf uses sends '/' as the first argument
|
||||
printlog "shifting arguments for Jamf"
|
||||
printlog "shifting arguments for Jamf" REQ
|
||||
shift 3
|
||||
fi
|
||||
|
||||
while [[ -n $1 ]]; do
|
||||
if [[ $1 =~ ".*\=.*" ]]; then
|
||||
# if an argument contains an = character, send it to eval
|
||||
printlog "setting variable from argument $1"
|
||||
printlog "setting variable from argument $1" WARN
|
||||
eval $1
|
||||
else
|
||||
# assume it's a label
|
||||
@@ -96,31 +96,31 @@ currentUser=$(scutil <<< "show State:/Users/ConsoleUser" | awk '/Name :/ { print
|
||||
# MARK: check for root
|
||||
if [[ "$(whoami)" != "root" && "$DEBUG" -eq 0 ]]; then
|
||||
# not running as root
|
||||
cleanupAndExit 6 "not running as root, exiting"
|
||||
cleanupAndExit 6 "not running as root, exiting" ERROR
|
||||
fi
|
||||
|
||||
# MARK: labels in case statement
|
||||
case $label in
|
||||
longversion)
|
||||
# print the script version
|
||||
printlog "Installomater: version $VERSION ($VERSIONDATE)"
|
||||
printlog "Installomater: version $VERSION ($VERSIONDATE)" REQ
|
||||
exit 0
|
||||
;;
|
||||
valuesfromarguments)
|
||||
if [[ -z $name ]]; then
|
||||
printlog "need to provide 'name'"
|
||||
printlog "need to provide 'name'" ERROR
|
||||
exit 1
|
||||
fi
|
||||
if [[ -z $type ]]; then
|
||||
printlog "need to provide 'type'"
|
||||
printlog "need to provide 'type'" ERROR
|
||||
exit 1
|
||||
fi
|
||||
if [[ -z $downloadURL ]]; then
|
||||
printlog "need to provide 'downloadURL'"
|
||||
printlog "need to provide 'downloadURL'" ERROR
|
||||
exit 1
|
||||
fi
|
||||
if [[ -z $expectedTeamID ]]; then
|
||||
printlog "need to provide 'expectedTeamID'"
|
||||
printlog "need to provide 'expectedTeamID'" ERROR
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
|
||||
@@ -18,8 +18,10 @@ cleanupAndExit() { # $1 = exit code, $2 message, $3 level
|
||||
reopenClosedProcess
|
||||
if [[ -n $2 && $1 -ne 0 ]]; then
|
||||
printlog "ERROR: $2" $3
|
||||
else
|
||||
printlog "$2" $3
|
||||
fi
|
||||
printlog "################## End Installomator, exit code $1 \n\n" REQ
|
||||
printlog "################## End Installomator, exit code $1 \n" REQ
|
||||
|
||||
# if label is wrong and we wanted name of the label, then return ##################
|
||||
if [[ $RETURN_LABEL_NAME -eq 1 ]]; then
|
||||
@@ -97,7 +99,7 @@ printlog(){
|
||||
curl -s -X POST https://http-intake.logs.datadoghq.com/v1/input -H "Content-Type: text/plain" -H "DD-API-KEY: $datadogAPI" -d "${log_priority} : $mdmURL : Installomator-${label} : ${VERSIONDATE//-/} : $SESSION : ${logmessage}" > /dev/null
|
||||
done <<< "$log_message"
|
||||
fi
|
||||
|
||||
|
||||
# Extra spaces
|
||||
space_char=""
|
||||
if [[ ${#log_priority} -eq 3 ]]; then
|
||||
@@ -154,10 +156,10 @@ downloadURLFromGit() { # $1 git user name, $2 git repo name
|
||||
fi
|
||||
|
||||
if [ -n "$archiveName" ]; then
|
||||
downloadURL=$(curl --silent --fail "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" \
|
||||
downloadURL=$(curl -L --silent --fail "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" \
|
||||
| awk -F '"' "/browser_download_url/ && /$archiveName\"/ { print \$4; exit }")
|
||||
else
|
||||
downloadURL=$(curl --silent --fail "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" \
|
||||
downloadURL=$(curl -L --silent --fail "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" \
|
||||
| awk -F '"' "/browser_download_url/ && /$filetype\"/ { print \$4; exit }")
|
||||
fi
|
||||
if [ -z "$downloadURL" ]; then
|
||||
@@ -174,9 +176,9 @@ versionFromGit() {
|
||||
gitusername=${1?:"no git user name"}
|
||||
gitreponame=${2?:"no git repo name"}
|
||||
|
||||
appNewVersion=$(curl --silent --fail "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | grep tag_name | cut -d '"' -f 4 | sed 's/[^0-9\.]//g')
|
||||
appNewVersion=$(curl -L --silent --fail "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | grep tag_name | cut -d '"' -f 4 | sed 's/[^0-9\.]//g')
|
||||
if [ -z "$appNewVersion" ]; then
|
||||
printlog "could not retrieve version number for $gitusername/$gitreponame"
|
||||
printlog "could not retrieve version number for $gitusername/$gitreponame" WARN
|
||||
appNewVersion=""
|
||||
else
|
||||
echo "$appNewVersion"
|
||||
@@ -220,19 +222,34 @@ getAppVersion() {
|
||||
fi
|
||||
fi
|
||||
|
||||
# get app in /Applications, or /Applications/Utilities, or find using Spotlight
|
||||
if [[ -d "/Applications/$appName" ]]; then
|
||||
# get app in targetDir, /Applications, or /Applications/Utilities
|
||||
if [[ -d "$targetDir/$appName" ]]; then
|
||||
applist="$targetDir/$appName"
|
||||
elif [[ -d "/Applications/$appName" ]]; then
|
||||
applist="/Applications/$appName"
|
||||
# if [[ $type =~ '^(dmg|zip|tbz|app.*)$' ]]; then
|
||||
# targetDir="/Applications"
|
||||
# fi
|
||||
elif [[ -d "/Applications/Utilities/$appName" ]]; then
|
||||
applist="/Applications/Utilities/$appName"
|
||||
# if [[ $type =~ '^(dmg|zip|tbz|app.*)$' ]]; then
|
||||
# targetDir="/Applications/Utilities"
|
||||
# fi
|
||||
else
|
||||
applist=$(mdfind "kind:application $appName" -0 )
|
||||
# applist=$(mdfind "kind:application $appName" -0 )
|
||||
printlog "name: $name, appName: $appName"
|
||||
applist=$(mdfind "kind:application AND name:$name" -0 )
|
||||
# printlog "App(s) found: ${applist}" DEBUG
|
||||
# applist=$(mdfind "kind:application AND name:$appName" -0 )
|
||||
fi
|
||||
if [[ -z applist ]]; then
|
||||
printlog "No previous app found" DEBUG
|
||||
printlog "No previous app found" INFO
|
||||
else
|
||||
printlog "App(s) found: ${applist}" DEBUG
|
||||
printlog "App(s) found: ${applist}" INFO
|
||||
fi
|
||||
# if [[ $type =~ '^(dmg|zip|tbz|app.*)$' ]]; then
|
||||
# printlog "targetDir for installation: $targetDir" INFO
|
||||
# fi
|
||||
|
||||
appPathArray=( ${(0)applist} )
|
||||
|
||||
@@ -255,10 +272,10 @@ getAppVersion() {
|
||||
fi
|
||||
fi
|
||||
else
|
||||
printlog "could not determine location of $appName"
|
||||
printlog "could not determine location of $appName" WARN
|
||||
fi
|
||||
else
|
||||
printlog "could not find $appName"
|
||||
printlog "could not find $appName" WARN
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -385,7 +402,7 @@ reopenClosedProcess() {
|
||||
processuser=$(ps aux | grep -i "${appName}" | grep -vi "grep" | awk '{print $1}')
|
||||
printlog "Reopened ${appName} as $processuser"
|
||||
else
|
||||
printlog "App not closed, so no reopen." DEBUG
|
||||
printlog "App not closed, so no reopen." INFO
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -395,7 +412,7 @@ installAppWithPath() { # $1: path to app to install in $targetDir
|
||||
|
||||
# check if app exists
|
||||
if [ ! -e "$appPath" ]; then
|
||||
cleanupAndExit 8 "could not find: $appPath" DEBUG
|
||||
cleanupAndExit 8 "could not find: $appPath" ERROR
|
||||
fi
|
||||
|
||||
# verify with spctl
|
||||
@@ -408,6 +425,13 @@ installAppWithPath() { # $1: path to app to install in $targetDir
|
||||
|
||||
if [[ $appVerifyStatus -ne 0 ]] ; then
|
||||
#if ! teamID=$(spctl -a -vv "$appPath" 2>&1 | awk '/origin=/ {print $NF }' | tr -d '()' ); then
|
||||
if [[ "$(echo $appVerify | head -1 | grep -oi rejected)" = "rejected" ]]; then
|
||||
if [[ "$(echo $appVerify | tail -1)" = "source=no usable signature" ]]; then
|
||||
printlog "Gatekeeper check rejected. No usable signature." ERROR
|
||||
else
|
||||
printlog "Gatekeeper check rejected. Could be that gatekeeper settings only accept App Store apps." ERROR
|
||||
fi
|
||||
fi
|
||||
cleanupAndExit 4 "Error verifying $appPath error:\n$logoutput" ERROR
|
||||
fi
|
||||
printlog "Debugging enabled, App Verification output was:\n$logoutput" DEBUG
|
||||
@@ -427,10 +451,12 @@ installAppWithPath() { # $1: path to app to install in $targetDir
|
||||
printlog "notifying"
|
||||
displaynotification "$message" "No update for $name!"
|
||||
fi
|
||||
cleanupAndExit 0 "No new version to install" INFO
|
||||
cleanupAndExit 0 "No new version to install" REG
|
||||
else
|
||||
printlog "Using force to install anyway."
|
||||
fi
|
||||
elif [[ -z $appversion ]]; then
|
||||
printlog "Installing $name version $appNewVersion on versionKey $versionKey."
|
||||
else
|
||||
printlog "Downloaded version of $name is $appNewVersion on versionKey $versionKey (replacing version $appversion)."
|
||||
fi
|
||||
@@ -446,7 +472,7 @@ installAppWithPath() { # $1: path to app to install in $targetDir
|
||||
printlog "notifying"
|
||||
displaynotification "$message" "Error updating $name!"
|
||||
fi
|
||||
cleanupAndExit 6 "Installed macOS is too old for this app." INFO
|
||||
cleanupAndExit 6 "Installed macOS is too old for this app." ERROR
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -467,7 +493,7 @@ installAppWithPath() { # $1: path to app to install in $targetDir
|
||||
|
||||
# remove existing application
|
||||
if [ -e "$targetDir/$appName" ]; then
|
||||
printlog "Removing existing $targetDir/$appName" DEBUG
|
||||
printlog "Removing existing $targetDir/$appName" WARN
|
||||
deleteAppOut=$(rm -Rfv "$targetDir/$appName" 2>&1)
|
||||
tempName="$targetDir/$appName"
|
||||
tempNameLength=$((${#tempName} + 10))
|
||||
@@ -478,16 +504,21 @@ installAppWithPath() { # $1: path to app to install in $targetDir
|
||||
|
||||
# copy app to /Applications
|
||||
printlog "Copy $appPath to $targetDir"
|
||||
if ! ditto "$appPath" "$targetDir/$appName"; then
|
||||
cleanupAndExit 7 "Error while copying" ERROR
|
||||
copyAppOut=$(ditto -v "$appPath" "$targetDir/$appName" 2>&1)
|
||||
copyAppStatus=$(echo $?)
|
||||
deduplicatelogs "$copyAppOut"
|
||||
printlog "Debugging enabled, App copy output was:\n$logoutput" DEBUG
|
||||
if [[ $copyAppStatus -ne 0 ]] ; then
|
||||
#if ! ditto "$appPath" "$targetDir/$appName"; then
|
||||
cleanupAndExit 7 "Error while copying:\n$logoutput" ERROR
|
||||
fi
|
||||
|
||||
# set ownership to current user
|
||||
if [[ "$currentUser" != "loginwindow" && $SYSTEMOWNER -ne 1 ]]; then
|
||||
printlog "Changing owner to $currentUser"
|
||||
printlog "Changing owner to $currentUser" WARN
|
||||
chown -R "$currentUser" "$targetDir/$appName"
|
||||
else
|
||||
printlog "No user logged in or SYSTEMOWNER=1, setting owner to root:wheel"
|
||||
printlog "No user logged in or SYSTEMOWNER=1, setting owner to root:wheel" WARN
|
||||
chown -R root:wheel "$targetDir/$appName"
|
||||
fi
|
||||
|
||||
@@ -517,7 +548,7 @@ mountDMG() {
|
||||
dmgmountStatus=$(echo $?)
|
||||
dmgmount=$(echo $dmgmountOut | tail -n 1 | cut -c 54- )
|
||||
deduplicatelogs "$dmgmountOut"
|
||||
|
||||
|
||||
if [[ $dmgmountStatus -ne 0 ]] ; then
|
||||
#if ! dmgmount=$(echo 'Y'$'\n' | hdiutil attach "$tmpDir/$archiveName" -nobrowse -readonly | tail -n 1 | cut -c 54- ); then
|
||||
cleanupAndExit 3 "Error mounting $tmpDir/$archiveName error:\n$logoutput" ERROR
|
||||
@@ -526,7 +557,7 @@ mountDMG() {
|
||||
cleanupAndExit 3 "Error accessing mountpoint for $tmpDir/$archiveName error:\n$logoutput" ERROR
|
||||
fi
|
||||
printlog "Debugging enabled, dmgmount output was:\n$logoutput" DEBUG
|
||||
|
||||
|
||||
printlog "Mounted: $dmgmount" INFO
|
||||
}
|
||||
|
||||
@@ -543,7 +574,7 @@ installFromPKG() {
|
||||
spctlOut=$(spctl -a -vv -t install "$archiveName" 2>&1 )
|
||||
spctlStatus=$(echo $?)
|
||||
printlog "spctlOut is $spctlOut" DEBUG
|
||||
|
||||
|
||||
teamID=$(echo $spctlOut | awk -F '(' '/origin=/ {print $2 }' | tr -d '()' )
|
||||
# Apple signed software has no teamID, grab entire origin instead
|
||||
if [[ -z $teamID ]]; then
|
||||
@@ -551,9 +582,16 @@ installFromPKG() {
|
||||
fi
|
||||
|
||||
deduplicatelogs "$spctlOut"
|
||||
|
||||
|
||||
if [[ $spctlStatus -ne 0 ]] ; then
|
||||
#if ! spctlout=$(spctl -a -vv -t install "$archiveName" 2>&1 ); then
|
||||
if [[ "$(echo $spctlOut | head -1 | grep -oi rejected)" = "rejected" ]]; then
|
||||
if [[ "$(echo $spctlOut | tail -1)" = "source=no usable signature" ]]; then
|
||||
printlog "Gatekeeper check rejected. No usable signature." ERROR
|
||||
else
|
||||
printlog "Gatekeeper check rejected. Could be that gatekeeper settings only accept App Store apps." ERROR
|
||||
fi
|
||||
fi
|
||||
cleanupAndExit 4 "Error verifying $archiveName error:\n$logoutput" ERROR
|
||||
fi
|
||||
|
||||
@@ -585,7 +623,7 @@ installFromPKG() {
|
||||
printlog "notifying"
|
||||
displaynotification "$message" "No update for $name!"
|
||||
fi
|
||||
cleanupAndExit 0 "No new version to install" INFO
|
||||
cleanupAndExit 0 "No new version to install" REQ
|
||||
else
|
||||
printlog "Using force to install anyway."
|
||||
fi
|
||||
@@ -659,27 +697,28 @@ installPkgInDmg() {
|
||||
if [[ -z $pkgName ]]; then
|
||||
# find first file ending with 'pkg'
|
||||
findfiles=$(find "$dmgmount" -iname "*.pkg" -type f -maxdepth 1 )
|
||||
printlog "Found pkg(s):\n$findfiles" DEBUG
|
||||
filearray=( ${(f)findfiles} )
|
||||
if [[ ${#filearray} -eq 0 ]]; then
|
||||
cleanupAndExit 20 "couldn't find pkg in dmg $archiveName" ERROR
|
||||
fi
|
||||
archiveName="${filearray[1]}"
|
||||
printlog "found pkg: $archiveName"
|
||||
else
|
||||
if ls "$tmpDir/$pkgName" ; then
|
||||
archiveName="$tmpDir/$pkgName"
|
||||
if [[ -s "$dmgmount/$pkgName" ]] ; then # was: $tmpDir
|
||||
archiveName="$dmgmount/$pkgName"
|
||||
else
|
||||
# try searching for pkg
|
||||
findfiles=$(find "$tmpDir" -iname "$pkgName")
|
||||
findfiles=$(find "$dmgmount" -iname "$pkgName") # was: $tmpDir
|
||||
printlog "Found pkg(s):\n$findfiles" DEBUG
|
||||
filearray=( ${(f)findfiles} )
|
||||
if [[ ${#filearray} -eq 0 ]]; then
|
||||
cleanupAndExit 20 "couldn't find pkg “$pkgName” in zip $archiveName" ERROR
|
||||
cleanupAndExit 20 "couldn't find pkg “$pkgName” in dmg $archiveName" ERROR
|
||||
fi
|
||||
# it is now safe to overwrite archiveName for installFromPKG
|
||||
archiveName="${filearray[1]}"
|
||||
printlog "found pkg: $archiveName"
|
||||
fi
|
||||
fi
|
||||
printlog "found pkg: $archiveName"
|
||||
|
||||
# installFromPkgs
|
||||
installFromPKG
|
||||
@@ -694,6 +733,7 @@ installPkgInZip() {
|
||||
if [[ -z $pkgName ]]; then
|
||||
# find first file ending with 'pkg'
|
||||
findfiles=$(find "$tmpDir" -iname "*.pkg" -type f -maxdepth 2 )
|
||||
printlog "Found pkg(s):\n$findfiles" DEBUG
|
||||
filearray=( ${(f)findfiles} )
|
||||
if [[ ${#filearray} -eq 0 ]]; then
|
||||
cleanupAndExit 20 "couldn't find pkg in zip $archiveName" ERROR
|
||||
@@ -770,13 +810,13 @@ runUpdateTool() {
|
||||
printlog "Error running $updateTool, Procceding with normal installation. Exit Status: $updateStatus Error:\n$logoutput" WARN
|
||||
return 1
|
||||
if [[ $type == updateronly ]]; then
|
||||
cleanupAndExit 77 "No Download URL Set, this is an update only application and the updater failed" WARN
|
||||
cleanupAndExit 77 "No Download URL Set, this is an update only application and the updater failed" ERROR
|
||||
fi
|
||||
elif [[ $updateStatus -eq 0 ]]; then
|
||||
printlog "Debugging enabled, update tool output was:\n$logoutput" DEBUG
|
||||
fi
|
||||
else
|
||||
printlog "couldn't find $updateTool, continuing normally"
|
||||
printlog "couldn't find $updateTool, continuing normally" WARN
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
@@ -793,7 +833,7 @@ finishing() {
|
||||
message="Installed $name, version $appversion"
|
||||
fi
|
||||
|
||||
printlog "$message"
|
||||
printlog "$message" REQ
|
||||
|
||||
if [[ $currentUser != "loginwindow" && ( $NOTIFY == "success" || $NOTIFY == "all" ) ]]; then
|
||||
printlog "notifying"
|
||||
|
||||
@@ -80,6 +80,7 @@ LOGO=appstore
|
||||
# - mosyleb Mosyle Business
|
||||
# - mosylem Mosyle Manager (Education)
|
||||
# - addigy Addigy
|
||||
# - microsoft Microsoft Endpoint Manager (Intune)
|
||||
# path can also be set in the command call, and if file exists, it will be used.
|
||||
# Like 'LOGO="/System/Applications/App\ Store.app/Contents/Resources/AppIcon.icns"'
|
||||
# (spaces have to be escaped).
|
||||
|
||||
9
fragments/labels/1passwordcli.sh
Normal file
9
fragments/labels/1passwordcli.sh
Normal file
@@ -0,0 +1,9 @@
|
||||
1passwordcli)
|
||||
name="1Password CLI"
|
||||
type="pkg"
|
||||
#packageID="com.1password.op"
|
||||
downloadURL=$(curl -fs https://app-updates.agilebits.com/product_history/CLI | grep -m 1 -i op_apple_universal | cut -d'"' -f 2)
|
||||
appNewVersion=$(echo $downloadURL | sed -E 's/.*\/[a-zA-Z_]*([0-9.]*)\..*/\1/g')
|
||||
appCustomVersion(){ /usr/local/bin/op -v }
|
||||
expectedTeamID="2BUA8C4S2C"
|
||||
;;
|
||||
7
fragments/labels/amazoncorretto8jdk.sh
Normal file
7
fragments/labels/amazoncorretto8jdk.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
amazoncorretto8jdk)
|
||||
name="Amazon Corretto 8 JDK"
|
||||
type="pkg"
|
||||
downloadURL="https://corretto.aws/downloads/latest/amazon-corretto-8-x64-macos-jdk.pkg"
|
||||
appNewVersion=$(curl -s https://raw.githubusercontent.com/corretto/corretto-8/develop/CHANGELOG.md | grep "## Corretto version" | head -n 1 | awk '{ print $4; exit}')
|
||||
expectedTeamID="94KV3E626L"
|
||||
;;
|
||||
@@ -1,7 +1,7 @@
|
||||
appcleaner)
|
||||
# credit: Tadayuki Onishi (@kenchan0130)
|
||||
name="AppCleaner"
|
||||
type="zip"
|
||||
downloadURL=$(curl -fs https://freemacsoft.net/appcleaner/Updates.xml | xpath '//rss/channel/*/enclosure/@url' 2>/dev/null | tr " " "\n" | sort | tail -1 | cut -d '"' -f 2)
|
||||
downloadURL=$(curl -fs https://freemacsoft.net/appcleaner/Updates.xml | xpath '//rss/channel/item[last()]/enclosure/@url' 2>/dev/null | tr " " "\n" | sort | tail -1 | cut -d '"' -f 2)
|
||||
appNewVersion=$(curl -fsL "https://freemacsoft.net/appcleaner/Updates.xml" | xpath '//rss/channel/item[last()]/enclosure/@sparkle:shortVersionString' 2>/dev/null | cut -d '"' -f 2)
|
||||
expectedTeamID="X85ZX835W9"
|
||||
;;
|
||||
|
||||
10
fragments/labels/autodeskfusion360admininstall.sh
Normal file
10
fragments/labels/autodeskfusion360admininstall.sh
Normal file
@@ -0,0 +1,10 @@
|
||||
autodeskfusion360admininstall)
|
||||
name="Autodesk Fusion 360 Admin Install"
|
||||
type="pkg"
|
||||
packageID="com.autodesk.edu.fusion360"
|
||||
downloadURL="https://dl.appstreaming.autodesk.com/production/installers/Autodesk%20Fusion%20360%20Admin%20Install.pkg"
|
||||
appNewVersion=$(curl -fs "https://dl.appstreaming.autodesk.com/production/97e6dd95735340d6ad6e222a520454db/73e72ada57b7480280f7a6f4a289729f/full.json" | sed -E 's/.*build-version":"([[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+).*/\1/g')
|
||||
expectedTeamID="XXKJ396S2Y"
|
||||
appName="Autodesk Fusion 360.app"
|
||||
blockingProcesses=( "Autodesk Fusion 360" "Fusion 360" )
|
||||
;;
|
||||
14
fragments/labels/axurerp10.sh
Normal file
14
fragments/labels/axurerp10.sh
Normal file
@@ -0,0 +1,14 @@
|
||||
axurerp10)
|
||||
name="Axure RP 10"
|
||||
type="dmg"
|
||||
if [[ $(arch) == "arm64" ]]; then
|
||||
downloadURL="https://d3uii9pxdigrx1.cloudfront.net/AxureRP-Setup-arm64.dmg"
|
||||
elif [[ $(arch) == "i386" ]]; then
|
||||
downloadURL="https://d3uii9pxdigrx1.cloudfront.net/AxureRP-Setup.dmg"
|
||||
fi
|
||||
appNewVersion=$( curl -sL https://www.axure.com/release-history | grep -Eo '[0-9]{1,4}\.[0-9]{1,4}\.[0-9]{1,4}\.[0-9]{1,4}' -m 1 )
|
||||
expectedTeamID="HUMW6UU796"
|
||||
versionKey="CFBundleVersion"
|
||||
appName="Axure RP 10.app"
|
||||
blockingProcesses=( "Axure RP 10" )
|
||||
;;
|
||||
7
fragments/labels/calcservice.sh
Normal file
7
fragments/labels/calcservice.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
calcservice)
|
||||
name="CalcService"
|
||||
type="zip"
|
||||
downloadURL="$(curl -fs -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15" "https://www.devontechnologies.com/support/download" | tr '"' "\n" | grep -o "http.*download.*.zip" | grep -i calcservice | head -1)"
|
||||
appNewVersion="$(echo $downloadURL | sed -E 's/.*\/([0-9.]*)\/.*/\1/g')"
|
||||
expectedTeamID="679S2QUWR8"
|
||||
;;
|
||||
7
fragments/labels/clipy.sh
Normal file
7
fragments/labels/clipy.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
clipy)
|
||||
name="Clipy"
|
||||
type="dmg"
|
||||
downloadURL=$(downloadURLFromGit Clipy Clipy)
|
||||
appNewVersion=$(versionFromGit Clipy Clipy)
|
||||
expectedTeamID="BBCHAJ584H"
|
||||
;;
|
||||
@@ -1,8 +1,9 @@
|
||||
dialog)
|
||||
dialog|\
|
||||
swiftdialog)
|
||||
name="Dialog"
|
||||
type="pkg"
|
||||
packageID="au.csiro.dialogcli"
|
||||
downloadURL="$(downloadURLFromGit bartreardon Dialog)"
|
||||
appNewVersion="$(versionFromGit bartreardon Dialog)"
|
||||
downloadURL="$(downloadURLFromGit bartreardon swiftDialog)"
|
||||
appNewVersion="$(versionFromGit bartreardon swiftDialog)"
|
||||
expectedTeamID="PWA5E9TQ59"
|
||||
;;
|
||||
|
||||
9
fragments/labels/dockutil.sh
Normal file
9
fragments/labels/dockutil.sh
Normal file
@@ -0,0 +1,9 @@
|
||||
dockutil)
|
||||
name="dockutil"
|
||||
type="pkg"
|
||||
packageID="dockutil.cli.tool"
|
||||
downloadURL=$(downloadURLFromGit "kcrawford" "dockutil")
|
||||
appNewVersion=$(versionFromGit "kcrawford" "dockutil")
|
||||
expectedTeamID="Z5J8CJBUWC"
|
||||
blockingProcesses=( NONE )
|
||||
;;
|
||||
7
fragments/labels/easyfind.sh
Normal file
7
fragments/labels/easyfind.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
easyfind)
|
||||
name="EasyFind"
|
||||
type="zip"
|
||||
downloadURL="$(curl -fs "https://www.devontechnologies.com/apps/freeware" | grep -o "http.*download.*.zip" | grep -i easyfind)"
|
||||
appNewVersion="$(echo $downloadURL | sed -E 's/.*\/([0-9.]*)\/.*/\1/g')"
|
||||
expectedTeamID="679S2QUWR8"
|
||||
;;
|
||||
@@ -1,14 +1,7 @@
|
||||
googlechrome)
|
||||
name="Google Chrome"
|
||||
type="dmg"
|
||||
if [[ $(arch) != "i386" ]]; then
|
||||
printlog "Architecture: arm64 (not i386)"
|
||||
downloadURL="https://dl.google.com/chrome/mac/universal/stable/GGRO/googlechrome.dmg"
|
||||
appNewVersion=$(curl -s https://omahaproxy.appspot.com/history | awk -F',' '/mac_arm64,stable/{print $3; exit}')
|
||||
else
|
||||
printlog "Architecture: i386"
|
||||
downloadURL="https://dl.google.com/chrome/mac/stable/GGRO/googlechrome.dmg"
|
||||
appNewVersion=$(curl -s https://omahaproxy.appspot.com/history | awk -F',' '/mac,stable/{print $3; exit}')
|
||||
fi
|
||||
downloadURL="https://dl.google.com/chrome/mac/universal/stable/GGRO/googlechrome.dmg"
|
||||
appNewVersion=$(curl -s https://omahaproxy.appspot.com/history | awk -F',' '/mac_arm64,stable/{print $3; exit}')
|
||||
expectedTeamID="EQHXZ8M8AV"
|
||||
;;
|
||||
|
||||
9
fragments/labels/grammarly.sh
Normal file
9
fragments/labels/grammarly.sh
Normal file
@@ -0,0 +1,9 @@
|
||||
grammarly)
|
||||
name="Grammarly Desktop"
|
||||
type="dmg"
|
||||
packageID="com.grammarly.ProjectLlama"
|
||||
downloadURL=$(curl -fsL "https://download-mac.grammarly.com/appcast.xml" | xpath '//rss/channel/item[1]/enclosure/@url' 2>/dev/null | cut -d '"' -f 2)
|
||||
expectedTeamID="W8F64X92K3"
|
||||
appNewVersion=$(curl -is "https://download-mac.grammarly.com/appcast.xml" | grep sparkle:version | tr ',' '\n' | grep sparkle:version | cut -d '"' -f 4)
|
||||
appName="Grammarly Installer.app"
|
||||
;;
|
||||
7
fragments/labels/houdahspot.sh
Normal file
7
fragments/labels/houdahspot.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
houdahspot)
|
||||
name="HoudahSpot"
|
||||
type="zip"
|
||||
downloadURL="$(curl -fs https://www.houdah.com/houdahSpot/updates/cast6.php | xpath '(//rss/channel/item/enclosure/@url)[1]' 2>/dev/null | head -1 | cut -d '"' -f 2)"
|
||||
appNewVersion="$(curl -fs https://www.houdah.com/houdahSpot/updates/cast6.php | xpath '(//rss/channel/item/enclosure/@sparkle:shortVersionString)[1]' 2>/dev/null | head -1 | cut -d '"' -f 2)"
|
||||
expectedTeamID="DKGQD8H8ZY"
|
||||
;;
|
||||
@@ -2,7 +2,11 @@ loom)
|
||||
# credit: Lance Stephens (@pythoninthegrass on MacAdmins Slack)
|
||||
name="Loom"
|
||||
type="dmg"
|
||||
downloadURL=https://cdn.loom.com/desktop-packages/$(curl -fs https://s3-us-west-2.amazonaws.com/loom.desktop.packages/loom-inc-production/desktop-packages/latest-mac.yml | awk '/url/ && /dmg/ {print $3}' | head -1)
|
||||
if [[ $(arch) == "arm64" ]]; then
|
||||
downloadURL=https://cdn.loom.com/desktop-packages/$(curl -fs https://s3-us-west-2.amazonaws.com/loom.desktop.packages/loom-inc-production/desktop-packages/latest-mac.yml | awk '/url/ && /arm64/ && /dmg/ {print $3}' | head -1)
|
||||
elif [[ $(arch) == "i386" ]]; then
|
||||
downloadURL=https://cdn.loom.com/desktop-packages/$(curl -fs https://s3-us-west-2.amazonaws.com/loom.desktop.packages/loom-inc-production/desktop-packages/latest-mac.yml | awk '/url/ && /dmg/ {print $3}' | head -1)
|
||||
fi
|
||||
appNewVersion=$(curl -fs https://s3-us-west-2.amazonaws.com/loom.desktop.packages/loom-inc-production/desktop-packages/latest-mac.yml | awk '/version/ {print $2}' )
|
||||
expectedTeamID="QGD2ZPXZZG"
|
||||
;;
|
||||
|
||||
9
fragments/labels/macadminspython.sh
Normal file
9
fragments/labels/macadminspython.sh
Normal file
@@ -0,0 +1,9 @@
|
||||
macadminspython)
|
||||
name="MacAdmins Python"
|
||||
type="pkg"
|
||||
packageID="org.macadmins.python.recommended"
|
||||
downloadURL=$(curl --silent --fail "https://api.github.com/repos/macadmins/python/releases/latest" | awk -F '"' "/browser_download_url/ && /python_recommended_signed/ { print \$4; exit }")
|
||||
appNewVersion=$(grep -o -E '\d+\.\d+\.\d+\.\d+' <<< $downloadURL | head -n 1)
|
||||
expectedTeamID="9GQZ7KUFR6"
|
||||
blockingProcesses=( NONE )
|
||||
;;
|
||||
10
fragments/labels/microsoftazuredatastudio.sh
Normal file
10
fragments/labels/microsoftazuredatastudio.sh
Normal file
@@ -0,0 +1,10 @@
|
||||
microsoftazuredatastudio|\
|
||||
azuredatastudio)
|
||||
name="Azure Data Studio"
|
||||
type="zip"
|
||||
downloadURL=$( curl -sL https://github.com/microsoft/azuredatastudio/releases/latest | grep 'macOS ZIP' | grep -Eo "(http|https)://[a-zA-Z0-9./?=_%:-]*" )
|
||||
appNewVersion=$(versionFromGit microsoft azuredatastudio )
|
||||
expectedTeamID="UBF8T346G9"
|
||||
appName="Azure Data Studio.app"
|
||||
blockingProcesses=( "Azure Data Studio" )
|
||||
;;
|
||||
@@ -1,5 +1,6 @@
|
||||
microsoftdefender|\
|
||||
microsoftdefenderatp)
|
||||
name="Microsoft Defender ATP"
|
||||
name="Microsoft Defender"
|
||||
type="pkg"
|
||||
downloadURL="https://go.microsoft.com/fwlink/?linkid=2097502"
|
||||
appNewVersion=$(curl -fs https://macadmins.software/latest.xml | xpath '//latest/package[id="com.microsoft.defender.standalone"]/version' 2>/dev/null | sed -E 's/<version>([0-9.]*) .*/\1/')
|
||||
@@ -1,9 +1,10 @@
|
||||
supportapp)
|
||||
# credit: Søren Theilgaard (@theilgaard)
|
||||
name="Support"
|
||||
type="pkg"
|
||||
packageID="nl.root3.support"
|
||||
downloadURL=$(downloadURLFromGit root3nl SupportApp)
|
||||
appNewVersion=$(versionFromGit root3nl SupportApp)
|
||||
expectedTeamID="98LJ4XBGYK"
|
||||
uid=$(id -u "$currentUser")
|
||||
launchctl bootout gui/${uid} "/Library/LaunchAgents/nl.root3.support.plist"
|
||||
;;
|
||||
|
||||
7
fragments/labels/tembo.sh
Normal file
7
fragments/labels/tembo.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
tembo)
|
||||
name="Tembo"
|
||||
type="zip"
|
||||
downloadURL="$(curl -fs https://www.houdah.com/tembo/updates/cast2.xml | xpath '(//rss/channel/item/enclosure/@url)[1]' 2>/dev/null | head -1 | cut -d '"' -f 2)"
|
||||
appNewVersion="$(curl -fs https://www.houdah.com/tembo/updates/cast2.xml | xpath '(//rss/channel/item/enclosure/@sparkle:shortVersionString)[1]' 2>/dev/null | head -1 | cut -d '"' -f 2)"
|
||||
expectedTeamID="DKGQD8H8ZY"
|
||||
;;
|
||||
8
fragments/labels/wordservice.sh
Normal file
8
fragments/labels/wordservice.sh
Normal file
@@ -0,0 +1,8 @@
|
||||
wordservice)
|
||||
name="WordService"
|
||||
type="zip"
|
||||
downloadURL="$(curl -fs -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.1 Safari/605.1.15" "https://www.devontechnologies.com/support/download" | tr '"' "\n" | grep -o "http.*download.*.zip" | grep -i wordservice | head -1)"
|
||||
appNewVersion="$(echo $downloadURL | sed -E 's/.*\/([0-9.]*)\/.*/\1/g')"
|
||||
appNewVersion=""
|
||||
expectedTeamID="679S2QUWR8"
|
||||
;;
|
||||
8
fragments/labels/xmenu.sh
Normal file
8
fragments/labels/xmenu.sh
Normal file
@@ -0,0 +1,8 @@
|
||||
xmenu)
|
||||
name="XMenu"
|
||||
type="zip"
|
||||
downloadURL="$(curl -fs "https://www.devontechnologies.com/apps/freeware" | grep -o "http.*download.*.zip" | grep -i xmenu)"
|
||||
appNewVersion="$(echo $downloadURL | sed -E 's/.*\/([0-9.]*)\/.*/\1/g')"
|
||||
expectedTeamID="679S2QUWR8"
|
||||
;;
|
||||
|
||||
@@ -4,4 +4,5 @@ zoom)
|
||||
downloadURL="https://zoom.us/client/latest/ZoomInstallerIT.pkg"
|
||||
appNewVersion="$(curl -fsIL ${downloadURL} | grep -i ^location | cut -d "/" -f5)"
|
||||
expectedTeamID="BJ4HAAB9B3"
|
||||
versionKey="CFBundleVersion"
|
||||
;;
|
||||
|
||||
@@ -4,4 +4,5 @@ zoomgov)
|
||||
downloadURL="https://www.zoomgov.com/client/latest/ZoomInstallerIT.pkg"
|
||||
appNewVersion="$(curl -fsIL ${downloadURL} | grep -i ^location | cut -d "/" -f5)"
|
||||
expectedTeamID="BJ4HAAB9B3"
|
||||
versionKey="CFBundleVersion"
|
||||
;;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
*)
|
||||
# unknown label
|
||||
#printlog "unknown label $label"
|
||||
cleanupAndExit 1 "unknown label $label"
|
||||
cleanupAndExit 1 "unknown label $label" ERROR
|
||||
;;
|
||||
esac
|
||||
|
||||
# Are we only asked to return label name
|
||||
if [[ $RETURN_LABEL_NAME -eq 1 ]]; then
|
||||
printlog "Only returning label name."
|
||||
printlog "Only returning label name." REQ
|
||||
printlog "$name"
|
||||
echo "$name"
|
||||
exit
|
||||
@@ -18,7 +18,7 @@ fi
|
||||
if [[ ${INTERRUPT_DND} = "no" ]]; then
|
||||
# Check if a fullscreen app is active
|
||||
if hasDisplaySleepAssertion; then
|
||||
cleanupAndExit 1 "active display sleep assertion detected, aborting"
|
||||
cleanupAndExit 1 "active display sleep assertion detected, aborting" ERROR
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -55,6 +55,11 @@ case $LOGO in
|
||||
LOGO="/Library/Addigy/macmanage/MacManage.app/Contents/Resources/atom.icns"
|
||||
if [[ -z $MDMProfileName ]]; then; MDMProfileName="MDM Profile"; fi
|
||||
;;
|
||||
microsoft)
|
||||
# Microsoft Endpoint Manager (Intune)
|
||||
LOGO="/Library/Intune/Microsoft Intune Agent.app/Contents/Resources/AppIcon.icns"
|
||||
if [[ -z $MDMProfileName ]]; then; MDMProfileName="Management Profile"; fi
|
||||
;;
|
||||
esac
|
||||
if [[ ! -a "${LOGO}" ]]; then
|
||||
if [[ $(sw_vers -buildVersion) > "19" ]]; then
|
||||
@@ -63,9 +68,9 @@ if [[ ! -a "${LOGO}" ]]; then
|
||||
LOGO="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
|
||||
fi
|
||||
fi
|
||||
printlog "LOGO=${LOGO}"
|
||||
printlog "LOGO=${LOGO}" INFO
|
||||
|
||||
printlog "Label type: $type"
|
||||
printlog "Label type: $type" INFO
|
||||
|
||||
# MARK: extract info from data
|
||||
if [ -z "$archiveName" ]; then
|
||||
@@ -87,7 +92,7 @@ if [ -z "$archiveName" ]; then
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
printlog "archiveName: $archiveName" DEBUG
|
||||
printlog "archiveName: $archiveName" INFO
|
||||
|
||||
if [ -z "$appName" ]; then
|
||||
# when not given derive from name
|
||||
@@ -105,14 +110,13 @@ if [ -z "$targetDir" ]; then
|
||||
updateronly)
|
||||
;;
|
||||
*)
|
||||
printlog "Cannot handle type $type"
|
||||
cleanupAndExit 99
|
||||
cleanupAndExit 99 "Cannot handle type $type" ERROR
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if [[ -z $blockingProcesses ]]; then
|
||||
printlog "no blocking processes defined, using $name as default"
|
||||
printlog "no blocking processes defined, using $name as default" INFO
|
||||
blockingProcesses=( $name )
|
||||
fi
|
||||
|
||||
@@ -128,8 +132,7 @@ fi
|
||||
# MARK: change directory to temporary working directory
|
||||
printlog "Changing directory to $tmpDir" DEBUG
|
||||
if ! cd "$tmpDir"; then
|
||||
printlog "error changing directory $tmpDir"
|
||||
cleanupAndExit 1
|
||||
cleanupAndExit 1 "error changing directory $tmpDir" ERROR
|
||||
fi
|
||||
|
||||
# MARK: get installed version
|
||||
@@ -152,10 +155,10 @@ if [[ -n $appNewVersion ]]; then
|
||||
printlog "notifying"
|
||||
displaynotification "$message" "No update for $name!"
|
||||
fi
|
||||
cleanupAndExit 0 "No newer version."
|
||||
cleanupAndExit 0 "No newer version." REQ
|
||||
fi
|
||||
else
|
||||
printlog "DEBUG mode 1 enabled, not exiting, but there is no new version of app."
|
||||
printlog "DEBUG mode 1 enabled, not exiting, but there is no new version of app." WARN
|
||||
fi
|
||||
fi
|
||||
else
|
||||
@@ -168,13 +171,12 @@ if [[ (-n $appversion && -n "$updateTool") || "$type" == "updateronly" ]]; then
|
||||
if [[ $DEBUG -ne 1 ]]; then
|
||||
if runUpdateTool; then
|
||||
finishing
|
||||
cleanupAndExit 0
|
||||
cleanupAndExit 0 "updateTool has run" REQ
|
||||
elif [[ $type == "updateronly" ]];then
|
||||
printlog "type is $type so we end here."
|
||||
cleanupAndExit 0
|
||||
cleanupAndExit 0 "type is $type so we end here." REQ
|
||||
fi # otherwise continue
|
||||
else
|
||||
printlog "DEBUG mode 1 enabled, not running update tool"
|
||||
printlog "DEBUG mode 1 enabled, not running update tool" WARN
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -197,14 +199,14 @@ else
|
||||
deduplicatelogs "$curlDownload"
|
||||
if [[ $curlDownloadStatus -ne 0 ]]; then
|
||||
#if ! curl --location --fail --silent "$downloadURL" -o "$archiveName"; then
|
||||
printlog "error downloading $downloadURL"
|
||||
printlog "error downloading $downloadURL" ERROR
|
||||
message="$name update/installation failed. This will be logged, so IT can follow up."
|
||||
if [[ $currentUser != "loginwindow" && $NOTIFY == "all" ]]; then
|
||||
printlog "notifying"
|
||||
if [[ $updateDetected == "YES" ]]; then
|
||||
displaynotification "$message" "Error updating $name" ERROR
|
||||
displaynotification "$message" "Error updating $name"
|
||||
else
|
||||
displaynotification "$message" "Error installing $name" ERROR
|
||||
displaynotification "$message" "Error installing $name"
|
||||
fi
|
||||
fi
|
||||
printlog "File list: $(ls -lh "$archiveName")" ERROR
|
||||
@@ -269,8 +271,7 @@ case $type in
|
||||
installAppInDmgInZip
|
||||
;;
|
||||
*)
|
||||
printlog "Cannot handle type $type"
|
||||
cleanupAndExit 99
|
||||
cleanupAndExit 99 "Cannot handle type $type" ERROR
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -278,4 +279,4 @@ esac
|
||||
finishing
|
||||
|
||||
# all done!
|
||||
cleanupAndExit 0
|
||||
cleanupAndExit 0 "All done!" REQ
|
||||
|
||||
@@ -1 +1 @@
|
||||
9.0
|
||||
10dev
|
||||
|
||||
9
grammarly.sh
Normal file
9
grammarly.sh
Normal file
@@ -0,0 +1,9 @@
|
||||
grammarly)
|
||||
name="Grammarly Desktop"
|
||||
type="dmg"
|
||||
packageID="com.grammarly.ProjectLlama"
|
||||
downloadURL=$(curl -fsL "https://download-mac.grammarly.com/appcast.xml" | xpath '//rss/channel/item[1]/enclosure/@url' 2>/dev/null | cut -d '"' -f 2)
|
||||
expectedTeamID="W8F64X92K3"
|
||||
appNewVersion=$(curl -is "https://download-mac.grammarly.com/appcast.xml" | grep sparkle:version | tr ',' '\n' | grep sparkle:version | cut -d '"' -f 4)
|
||||
appName="Grammarly Installer.app"
|
||||
;;
|
||||
Reference in New Issue
Block a user