diff --git a/CHANGELOG.md b/CHANGELOG.md
index d927514..0bc345c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,100 @@
+## v10beta2
+
+- fixed problem with GitHub labels (#659)
+- bz2 archive support (#659)
+- fixed WorkspaceOne support (#653)
+
+Plus everything from v10beta1
+
+- new labels:
+ - abetterfinderrename11 (#552)
+ - carboncopycloner (#553)
+ - cocoapods (#659)
+ - coconutbattery (#588)
+ - cricutdesignspace (#562)
+ - dynalist (#591)
+ - fellow (#591)
+ - flexoptixapp (#554)
+ - googleadseditor (#652, #541)
+ - kap (#568)
+ - keepingyouawake (#549)
+ - lcadvancedvpnclient (#584)
+ - masv (#569)
+ - merlinproject (#555)
+ - mongodbcompass (#654)
+ - netspot (#556)
+ - relatel (#619)
+ - sonicvisualiser (#575)
+ - strongdm (#559)
+ - synologyassistant (#557)
+ - synologydriveclient (#582)
+ - tencentmeeting (#570)
+ - typinator (#583)
+ - xcreds (#675)
+- updated labels:
+ - acroniscyberprotectconnect/remotix (#664)
+ - acroniscyberprotectconnectagent/remotixagent (#664)
+ - awsvpnclient (#586)
+ - boxtools (#589)
+ - clevershare2 (#664)
+ - coderunner (#664)
+ - colourcontrastanalyser (#664)
+ - cryptomator (#664)
+ - dangerzone (#664)
+ - drawio (#664)
+ - golang (#664)
+ - icons (#664)
+ - insomnia (#664)
+ - knockknock (#664)
+ - libreoffice (#672)
+ - macports
+ - opera (#664)
+ - supportapp (#664)
+ - vmwarehorizonclient (#645, #511)
+- deleted/deactivated labels:
+ - microsoftyammer (#664)
+ - wickrme (#664)
+ - wickrpro (#664)
+
+
+## v10beta1
+
+- [swiftDialog](https://github.com/bartreardon/swiftDialog) integration (#641, #632), many thanks to @bartreardon, [sample scripts](in the MDM folder)
+- added WorkspaceOne option for LOGO (#517)
+- added function for JSON parsing with JXA (#529)
+- updated assemble.sh script to update Labels.txt when script is rebuilt (#540)
+- added a no requisite install script (#493)
+- GitHub lookup now don't use API calls, this should avoid or at least reduce rate limiting (#543)
+- fixed redundant exit codes (#643, #561)
+
+NOTE: some exit codes have changed! see [Installomator Exit Codes](https://github.com/Installomator/Installomator/wiki/Installomator-Exit-Codes) for a list
+
+- new labels:
+ - bluejeanswithaudiodriver (#473)
+ - duodevicehealth (#548)
+ - googlechromeenterprise (#532)
+ - ipswupdater (#545)
+ - mmhmm (#571)
+ - nordlayer (#419)
+ - prune (#538)
+ - whatroute (#560)
+- updated labels:
+ - blender (#535, #622)
+ - camtasia2019 (#547)
+ - clickshare (#565)
+ - egnyte (#500)
+ - googledrive (#563)
+ - grammarly (#576)
+ - marathon, marathon2, marathoninfinity (#544)
+ - miro (#475, #539)
+ - notion (#566)
+ - ringcentralapp (#550)
+ - sublimetext (#593, #578, #567, #623, #626)
+ - talkdeskcallbar (#536)
+ - talkdeskcxcloud (#537)
+ - wireshark (#585)
+
+
## v9.2
**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 `googlechromepkg` and `firefoxpkg` labels instead.
diff --git a/Installomator.sh b/Installomator.sh
index 54d2fbb..025a68c 100755
--- a/Installomator.sh
+++ b/Installomator.sh
@@ -7,7 +7,7 @@ label="" # if no label is sent to the script, this will be used
# 2020-2021 Installomator
#
# inspired by the download scripts from William Smith and Sander Schram
-#
+#
# Contributers:
# Armin Briegel - @scriptingosx
# Isaac Ordonez - @issacatmann
@@ -23,7 +23,7 @@ export PATH=/usr/bin:/bin:/usr/sbin:/sbin
# set to 0 for production, 1 or 2 for debugging
# while debugging, items will be downloaded to the parent directory of this script
# also no actual installation will be performed
-# debug mode 1 will download to the directory the script is run in, but will not check the version
+# debug mode 1 will download to the directory the script is run in, but will not check the version
# debug mode 2 will download to the temp directory, check for blocking processes, check the version, but will not install anything or remove the current version
DEBUG=1
@@ -34,7 +34,6 @@ NOTIFY=success
# - silent no notifications
# - all all notifications (great for Self Service installation)
-
# behavior when blocking processes are found
BLOCKING_PROCESS_ACTION=tell_user
# options:
@@ -140,6 +139,26 @@ IGNORE_DND_APPS=""
# IGNORE_DND_APPS="firefox,Google Chrome,Safari,Microsoft Edge,Opera,Amphetamine,caffeinate"
+# Swift Dialog integration
+
+# These variables will allow Installomator to communicate progress with Swift Dialog
+# https://github.com/bartreardon/swiftDialog
+
+# This requires Swift Dialog 2.11.2 or higher.
+
+DIALOG_CMD_FILE=""
+# When this variable is set, Installomator will write Swift Dialog commands to this path.
+# Installomator will not launch Swift Dialog. The process calling Installomator will have
+# launch and configure Swift Dialog to listen to this file.
+# See `MDM/swiftdialog_example.sh` for an example.
+
+DIALOG_LIST_ITEM_NAME=""
+# When this variable is set, progress for downloads and installs will be sent to this
+# listitem.
+# When the variable is unset, progress will be sent to Swift Dialog's main progress bar.
+
+
+
# NOTE: How labels work
# Each workflow label needs to be listed in the case statement below.
@@ -185,7 +204,7 @@ IGNORE_DND_APPS=""
# How we get version number from app. Possible values:
# - CFBundleShortVersionString
# - CFBundleVersion
-# Not all software titles uses fields the same.
+# Not all software titles uses fields the same.
# See Opera label.
#
# - appCustomVersion(){}: (optional function)
@@ -303,8 +322,8 @@ if [[ $(/usr/bin/arch) == "arm64" ]]; then
rosetta2=no
fi
fi
-VERSION="10.0beta"
-VERSIONDATE="2022-05-19"
+VERSION="10.0beta2"
+VERSIONDATE="2022-09-02"
# MARK: Functions
@@ -322,15 +341,18 @@ cleanupAndExit() { # $1 = exit code, $2 message, $3 level
printlog "Debugging enabled, Deleting tmpDir output was:\n$deleteTmpOut" DEBUG
fi
+
# If we closed any processes, reopen the app again
reopenClosedProcess
if [[ -n $2 && $1 -ne 0 ]]; then
printlog "ERROR: $2" $3
+ updateDialog "fail" "Error ($1; $2)"
else
printlog "$2" $3
+ updateDialog "success" ""
fi
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
1=0 # If only label name should be returned we exit without any errors
@@ -368,8 +390,8 @@ displaydialogContinue() { # $1: message $2: title
displaynotification() { # $1: message $2: title
message=${1:-"Message"}
title=${2:-"Notification"}
- hubcli="/usr/local/bin/hubcli"
manageaction="/Library/Application Support/JAMF/bin/Management Action.app/Contents/MacOS/Management Action"
+ hubcli="/usr/local/bin/hubcli"
if [[ -x "$manageaction" ]]; then
"$manageaction" -message "$message" -title "$title"
@@ -467,14 +489,14 @@ downloadURLFromGit() { # $1 git user name, $2 git repo name
fi
if [ -n "$archiveName" ]; then
- downloadURL=$(curl -L --silent --fail "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" \
- | awk -F '"' "/browser_download_url/ && /$archiveName\"/ { print \$4; exit }")
+ #downloadURL=$(curl -L --silent --fail "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | awk -F '"' "/browser_download_url/ && /$archiveName\"/ { print \$4; exit }")
+ downloadURL=https://github.com$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*$archiveName" | head -1)
else
- downloadURL=$(curl -L --silent --fail "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" \
- | awk -F '"' "/browser_download_url/ && /$filetype\"/ { print \$4; exit }")
+ #downloadURL=$(curl -L --silent --fail "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | awk -F '"' "/browser_download_url/ && /$filetype\"/ { print \$4; exit }")
+ downloadURL=https://github.com$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)
fi
if [ -z "$downloadURL" ]; then
- cleanupAndExit 9 "could not retrieve download URL for $gitusername/$gitreponame" ERROR
+ cleanupAndExit 14 "could not retrieve download URL for $gitusername/$gitreponame" ERROR
else
echo "$downloadURL"
return 0
@@ -487,7 +509,8 @@ versionFromGit() {
gitusername=${1?:"no git user name"}
gitreponame=${2?:"no git repo name"}
- 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')
+ #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')
+ appNewVersion=$(curl -sLI "https://github.com/$gitusername/$gitreponame/releases/latest" | grep -i "^location" | tr "/" "\n" | tail -1 | sed 's/[^0-9\.]//g')
if [ -z "$appNewVersion" ]; then
printlog "could not retrieve version number for $gitusername/$gitreponame" WARN
appNewVersion=""
@@ -510,6 +533,16 @@ xpath() {
fi
}
+# from @Pico: https://macadmins.slack.com/archives/CGXNNJXJ9/p1652222365989229?thread_ts=1651786411.413349&cid=CGXNNJXJ9
+getJSONValue() {
+ # $1: JSON string OR file path to parse (tested to work with up to 1GB string and 2GB file).
+ # $2: JSON key path to look up (using dot or bracket notation).
+ printf '%s' "$1" | /usr/bin/osascript -l 'JavaScript' \
+ -e "let json = $.NSString.alloc.initWithDataEncoding($.NSFileHandle.fileHandleWithStandardInput.readDataToEndOfFile$(/usr/bin/uname -r | /usr/bin/awk -F '.' '($1 > 18) { print "AndReturnError(ObjC.wrap())" }'), $.NSUTF8StringEncoding)" \
+ -e 'if ($.NSFileManager.defaultManager.fileExistsAtPath(json)) json = $.NSString.stringWithContentsOfFileEncodingError(json, $.NSUTF8StringEncoding, ObjC.wrap())' \
+ -e "const value = JSON.parse(json.js)$([ -n "${2%%[.[]*}" ] && echo '.')$2" \
+ -e 'if (typeof value === "object") { JSON.stringify(value, null, 4) } else { value }'
+}
getAppVersion() {
# modified by: Søren Theilgaard (@theilgaard) and Isaac Ordonez
@@ -579,7 +612,7 @@ getAppVersion() {
printlog "Replacing App Store apps, no matter the version" WARN
appversion=0
else
- cleanupAndExit 1 "App previously installed from App Store, and we respect that" ERROR
+ cleanupAndExit 23 "App previously installed from App Store, and we respect that" ERROR
fi
fi
else
@@ -728,6 +761,7 @@ installAppWithPath() { # $1: path to app to install in $targetDir
# verify with spctl
printlog "Verifying: $appPath" INFO
+ updateDialog "wait" "Verifying..."
printlog "App size: $(du -sh "$appPath")" DEBUG
appVerify=$(spctl -a -vv "$appPath" 2>&1 )
appVerifyStatus=$(echo $?)
@@ -776,7 +810,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." ERROR
+ cleanupAndExit 15 "Installed macOS is too old for this app." ERROR
fi
fi
@@ -835,7 +869,7 @@ installAppWithPath() { # $1: path to app to install in $targetDir
deduplicatelogs "$CLIoutput"
if [ $CLIstatus -ne 0 ] ; then
- cleanupAndExit 3 "Error installing $mountname/$CLIInstaller $CLIArguments error:\n$logoutput" ERROR
+ cleanupAndExit 16 "Error installing $mountname/$CLIInstaller $CLIArguments error:\n$logoutput" ERROR
else
printlog "Succesfully ran $mountname/$CLIInstaller $CLIArguments" INFO
fi
@@ -873,6 +907,7 @@ installFromDMG() {
installFromPKG() {
# verify with spctl
printlog "Verifying: $archiveName"
+ updateDialog "wait" "Verifying..."
printlog "File list: $(ls -lh "$archiveName")" DEBUG
printlog "File type: $(file "$archiveName")" DEBUG
spctlOut=$(spctl -a -vv -t install "$archiveName" 2>&1 )
@@ -940,8 +975,29 @@ installFromPKG() {
# install pkg
printlog "Installing $archiveName to $targetDir"
- pkgInstall=$(installer -verbose -dumplog -pkg "$archiveName" -tgt "$targetDir" 2>&1)
- pkgInstallStatus=$(echo $?)
+
+ if [[ $DIALOG_CMD_FILE != "" ]]; then
+ # pipe
+ pipe="$tmpDir/installpipe"
+ # initialise named pipe for installer output
+ initNamedPipe create $pipe
+
+ # run the pipe read in the background
+ readPKGInstallPipe $pipe "$DIALOG_CMD_FILE" & installPipePID=$!
+ printlog "listening to output of installer with pipe $pipe and command file $DIALOG_CMD_FILE on PID $installPipePID" DEBUG
+
+ pkgInstall=$(installer -verboseR -pkg "$archiveName" -tgt "$targetDir" 2>&1 | tee $pipe)
+ pkgInstallStatus=$pipestatus[1]
+ # because we are tee-ing the output, we want the pipe status of the first command in the chain, not the most recent one
+ killProcess $installPipePID
+
+ else
+ pkgInstall=$(installer -verbose -dumplog -pkg "$archiveName" -tgt "$targetDir" 2>&1)
+ pkgInstallStatus=$(echo $?)
+ fi
+
+
+
sleep 1
pkgEndTime=$(date "+$LogDateFormat")
pkgInstall+=$(echo "\nOutput of /var/log/install.log below this line.\n")
@@ -1033,7 +1089,7 @@ installPkgInZip() {
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
+ cleanupAndExit 21 "couldn't find pkg in zip $archiveName" ERROR
fi
# it is now safe to overwrite archiveName for installFromPKG
archiveName="${filearray[1]}"
@@ -1046,7 +1102,7 @@ installPkgInZip() {
findfiles=$(find "$tmpDir" -iname "$pkgName")
filearray=( ${(f)findfiles} )
if [[ ${#filearray} -eq 0 ]]; then
- cleanupAndExit 20 "couldn't find pkg “$pkgName” in zip $archiveName" ERROR
+ cleanupAndExit 21 "couldn't find pkg “$pkgName” in zip $archiveName" ERROR
fi
# it is now safe to overwrite archiveName for installFromPKG
archiveName="${filearray[1]}"
@@ -1069,7 +1125,7 @@ installAppInDmgInZip() {
findfiles=$(find "$tmpDir" -iname "*.dmg" -maxdepth 2 )
filearray=( ${(f)findfiles} )
if [[ ${#filearray} -eq 0 ]]; then
- cleanupAndExit 20 "couldn't find dmg in zip $archiveName" ERROR
+ cleanupAndExit 22 "couldn't find dmg in zip $archiveName" ERROR
fi
archiveName="$(basename ${filearray[1]})"
# it is now safe to overwrite archiveName for installFromDMG
@@ -1121,7 +1177,8 @@ runUpdateTool() {
finishing() {
printlog "Finishing..."
- sleep 10 # wait a moment to let spotlight catch up
+
+ sleep 3 # wait a moment to let spotlight catch up
getAppVersion
if [[ -z $appversion ]]; then
@@ -1169,6 +1226,116 @@ hasDisplaySleepAssertion() {
return 1
}
+initNamedPipe() {
+ # create or delete a named pipe
+ # commands are "create" or "delete"
+
+ local cmd=$1
+ local pipe=$2
+ case $cmd in
+ "create")
+ if [[ -e $pipe ]]; then
+ rm $pipe
+ fi
+ # make named pipe
+ mkfifo -m 644 $pipe
+ ;;
+ "delete")
+ # clean up
+ rm $pipe
+ ;;
+ *)
+ ;;
+ esac
+}
+
+readDownloadPipe() {
+ # reads from a previously created named pipe
+ # output from curl with --progress-bar. % downloaded is read in and then sent to the specified log file
+ local pipe=$1
+ local log=${2:-$DIALOG_CMD_FILE}
+ # set up read from pipe
+ while IFS= read -k 1 -u 0 char; do
+ if [[ $char =~ [0-9] ]]; then
+ keep=1
+ fi
+
+ if [[ $char == % ]]; then
+ updateDialog $progress "Downloading..."
+ progress=""
+ keep=0
+ fi
+
+ if [[ $keep == 1 ]]; then
+ progress="$progress$char"
+ fi
+ done < $pipe
+}
+
+readPKGInstallPipe() {
+ # reads from a previously created named pipe
+ # output from installer with -verboseR. % install status is read in and then sent to the specified log file
+ local pipe=$1
+ local log=${2:-$DIALOG_CMD_FILE}
+ local appname=${3:-$name}
+
+ while read -k 1 -u 0 char; do
+ if [[ $char == % ]]; then
+ keep=1
+ fi
+ if [[ $char =~ [0-9] && $keep == 1 ]]; then
+ progress="$progress$char"
+ fi
+ if [[ $char == . && $keep == 1 ]]; then
+ updateDialog $progress "Installing..."
+ progress=""
+ keep=0
+ fi
+ done < $pipe
+}
+
+killProcess() {
+ # will silently kill the specified PID
+ builtin kill $1 2>/dev/null
+}
+
+updateDialog() {
+ local state=$1
+ local message=$2
+ local listitem=${3:-$DIALOG_LIST_ITEM_NAME}
+ local cmd_file=${4:-$DIALOG_CMD_FILE}
+ local progress=""
+
+ if [[ $state =~ '^[0-9]' \
+ || $state == "reset" \
+ || $state == "increment" \
+ || $state == "complete" \
+ || $state == "indeterminate" ]]; then
+ progress=$state
+ fi
+
+ # when to cmdfile is set, do nothing
+ if [[ $cmd_file == "" ]]; then
+ return
+ fi
+
+ if [[ $listitem == "" ]]; then
+ # no listitem set, update main progress bar and progress text
+ if [[ $progress != "" ]]; then
+ echo "progress: $progress" >> $cmd_file
+ fi
+ if [[ $message != "" ]]; then
+ echo "progresstext: $name - $message" >> $cmd_file
+ fi
+ else
+ # list item has a value, so we update the progress and text in the list
+ if [[ $progress != "" ]]; then
+ echo "listitem: title: $listitem, statustext: $message, progress: $progress" >> $cmd_file
+ else
+ echo "listitem: title: $listitem, statustext: $message, status: $state" >> $cmd_file
+ fi
+ fi
+}
# MARK: check minimal macOS requirement
autoload is-at-least
@@ -1178,6 +1345,7 @@ if ! is-at-least 10.14 $installedOSversion; then
exit 98
fi
+
# MARK: argument parsing
if [[ $# -eq 0 ]]; then
if [[ -z $label ]]; then # check if label is set inside script
@@ -1195,7 +1363,7 @@ fi
while [[ -n $1 ]]; do
if [[ $1 =~ ".*\=.*" ]]; then
# if an argument contains an = character, send it to eval
- printlog "setting variable from argument $1" WARN
+ printlog "setting variable from argument $1" INFO
eval $1
else
# assume it's a label
@@ -1270,6 +1438,16 @@ if [[ "$(whoami)" != "root" && "$DEBUG" -eq 0 ]]; then
cleanupAndExit 6 "not running as root, exiting" ERROR
fi
+
+# check Swift Dialog presence and version
+DIALOG_CMD="/usr/local/bin/dialog"
+
+if [[ ! -x $DIALOG_CMD ]]; then
+ # Swift Dialog is not installed, clear cmd file variable to ignore
+ printlog "SwiftDialog is not installed, clear cmd file var"
+ DIALOG_CMD_FILE=""
+fi
+
# MARK: labels in case statement
case $label in
longversion)
@@ -1347,6 +1525,13 @@ valuesfromarguments)
appNewVersion=$(curl -fs -L https://support.8x8.com/cloud-phone-service/voice/work-desktop/download-8x8-work-for-desktop | grep -m 1 -o "https.*dmg" | sed 's/\"//' | awk '{print $1}' | sed -E 's/.*-v([0-9\.]*)[-\.]*.*/\1/' )
expectedTeamID="FC967L3QRG"
;;
+abetterfinderrename11)
+ name="A Better Finder Rename 11"
+ type="dmg"
+ downloadURL="https://www.publicspace.net/download/ABFRX11.dmg"
+ appNewVersion=$(curl -fs "https://www.publicspace.net/app/signed_abfr11.xml" | xpath '(//rss/channel/item/enclosure/@sparkle:version)' 2>/dev/null | cut -d '"' -f 2)
+ expectedTeamID="7Y9KW4ND8W"
+ ;;
abstract)
name="Abstract"
type="zip"
@@ -1354,6 +1539,25 @@ abstract)
appNewVersion=$( curl -fsIL "${downloadURL}" | grep -i "^location" | awk '{print $2}' | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)\..*/\1/g' )
expectedTeamID="77MZLZE47D"
;;
+acroniscyberprotectconnect|\
+remotix)
+ name="Acronis Cyber Protect Connect"
+ type="dmg"
+ downloadURL="https://go.acronis.com/AcronisCyberProtectConnect_ForMac"
+ versionKey="CFBundleVersion"
+ appNewVersion=$(curl -fsIL "${downloadURL}" | grep -i "^location" | sed -E 's/.*\/[a-zA-Z]*-[0-9.]*-([0-9.]*)\.dmg/\1/g')
+ expectedTeamID="ZU2TV78AA6"
+ ;;
+acroniscyberprotectconnectagent|\
+remotixagent)
+ name="Acronis Cyber Protect Connect Agent"
+ type="pkg"
+ #packageID="com.nulana.rxagentmac"
+ downloadURL="https://go.acronis.com/AcronisCyberProtectConnect_AgentForMac"
+ versionKey="CFBundleVersion"
+ appNewVersion=$(curl -fsIL "${downloadURL}" | grep -i "^location" | sed -E 's/.*\/[a-zA-Z]*-[0-9.]*-([0-9.]*)\.pkg/\1/g')
+ expectedTeamID="H629V387SY"
+ ;;
adobebrackets)
name="Brackets"
type="dmg"
@@ -1375,10 +1579,11 @@ adobecreativeclouddesktop)
name="Adobe Creative Cloud"
#appName="Install.app"
type="dmg"
+ adobeurl="https://helpx.adobe.com/download-install/kb/creative-cloud-desktop-app-download.html"
if [[ $(arch) == "arm64" ]]; then
- downloadURL=$(curl -fs "https://helpx.adobe.com/download-install/kb/creative-cloud-desktop-app-download.html" | grep -o "https*.*macarm64.*dmg" | cut -d '"' -f1 | head -1)
+ downloadURL=$(curl -fs "$adobeurl" | xmllint -html -xpath "string(//a[contains(@href,'osx10')][contains(text(),'Download')]/@href)" - 2> /dev/null)
elif [[ $(arch) == "i386" ]]; then
- downloadURL=$(curl -fs "https://helpx.adobe.com/download-install/kb/creative-cloud-desktop-app-download.html" | grep -o "https*.*osx10.*dmg" | cut -d '"' -f1 | head -1)
+ downloadURL=$(curl -fs "$adobeurl" | xmllint -html -xpath "string(//a[contains(@href,'macarm64')][contains(text(),'Download')]/@href)" - 2> /dev/null)
fi
#downloadURL=$(curl -fs "https://helpx.adobe.com/download-install/kb/creative-cloud-desktop-app-download.html" | grep -o "https*.*dmg" | head -1)
appNewVersion=$(curl -fs "https://helpx.adobe.com/creative-cloud/release-note/cc-release-notes.html" | grep "mandatory" | head -1 | grep -o "Version *.* released" | cut -d " " -f2)
@@ -1677,7 +1882,7 @@ awsvpnclient)
type="pkg"
downloadURL="https://d20adtppz83p9s.cloudfront.net/OSX/latest/AWS_VPN_Client.pkg"
expectedTeamID="94KV3E626L"
- appNewVersion=$(curl -is "https://beta2.communitypatch.com/jamf/v1/ba1efae22ae74a9eb4e915c31fef5dd2/patch/AWSVPNClient" | grep currentVersion | tr ',' '\n' | grep currentVersion | cut -d '"' -f 4)
+ #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"
@@ -1747,7 +1952,11 @@ bitwarden)
blender)
name="blender"
type="dmg"
- downloadURL=$(redirect=$(curl -sfL https://www.blender.org/download/ | sed 's/.*href="//' | sed 's/".*//' | grep .dmg) && curl -sfL "$redirect" | sed 's/.*href="//' | sed 's/".*//' | grep -m1 .dmg)
+ if [[ $(arch) == "arm64" ]]; then
+ downloadURL=$(curl -sfL "https://www.blender.org/download/" | xmllint --html --format - 2>/dev/null | grep -o "https://.*blender.*arm64.*.dmg" | sed '2p;d' | sed 's/www.blender.org\/download/download.blender.org/g')
+ elif [[ $(arch) == "i386" ]]; then
+ downloadURL=$(curl -sfL "https://www.blender.org/download/" | xmllint --html --format - 2>/dev/null | grep -o "https://.*blender.*x64.*.dmg" | sed '2p;d' | sed 's/www.blender.org\/download/download.blender.org/g')
+ fi
appNewVersion=$( echo "${downloadURL}" | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)-.*/\1/g' )
expectedTeamID="68UA947AUU"
;;
@@ -1762,6 +1971,18 @@ bluejeans)
appNewVersion=$(echo $downloadURL | cut -d '/' -f6)
expectedTeamID="HE4P42JBGN"
;;
+bluejeanswithaudiodriver)
+ name="BlueJeans"
+ type="pkg"
+ if [[ $(arch) == "arm64" ]]; then
+ downloadURL=$(curl -fs "https://www.bluejeans.com/downloads" | xmllint --html --format - 2>/dev/null | grep -o "https://.*BlueJeans.*Installer.*arm.*.pkg" )
+ elif [[ $(arch) == "i386" ]]; then
+ downloadURL=$(curl -fs "https://www.bluejeans.com/downloads" | xmllint --html --format - 2>/dev/null | grep -o "https://.*BlueJeansInstaller.*x86.*.dmg" | sed 's/dmg/pkg/g')
+ fi
+ appNewVersion=$(echo $downloadURL | cut -d '/' -f6)
+ choiceChangesXML='attributeSetting1choiceAttributeselectedchoiceIdentifiercom.tatvikmohit.BlueJeans-Audio'
+ expectedTeamID="HE4P42JBGN"
+ ;;
boxdrive)
name="Box"
type="pkg"
@@ -1778,6 +1999,7 @@ boxtools)
name="Box Tools"
type="pkg"
downloadURL="https://box-installers.s3.amazonaws.com/boxedit/mac/currentrelease/BoxToolsInstaller.pkg"
+ packageID="com.box.boxtools.installer.boxedit"
expectedTeamID="M683GB7CPW"
;;
brave)
@@ -1882,6 +2104,13 @@ canva)
fi
expectedTeamID="5HD2ARTBFS"
;;
+carboncopycloner)
+ name="Carbon Copy Cloner"
+ type="zip"
+ downloadURL=$(curl -fsIL "https://bombich.com/software/download_ccc.php?v=latest" | grep -i ^location | sed -E 's/.*(https.*\.zip).*/\1/g')
+ appNewVersion=$(sed -E 's/.*-([0-9.]*)\.zip/\1/g' <<< $downloadURL | sed 's/\.[^.]*$//')
+ expectedTeamID="L4F2DED5Q7"
+ ;;
chatwork)
name="Chatwork"
type="dmg"
@@ -1906,15 +2135,16 @@ citrixworkspace)
clevershare2)
name="Clevershare"
type="dmg"
- downloadURL=$(curl -fs https://www.clevertouch.com/eu/clevershare2g | grep -i -o -E "https.*Mac.*\.dmg")
- appNewVersion=$( echo "${downloadURL}" | sed -E 's/.*\/[a-zA-Z-]*_Mac\.([0-9.]*)\.[0-9]*\.dmg$/\1/g' )
+ printlog "Label for $name broken in test" ERROR
+ downloadURL=$(curl -fs https://www.clevertouch.com/eu/clevershare2g | grep -i -o -E "https.*notarized.*\.dmg")
+ appNewVersion=$(echo "${downloadURL}" | sed -E 's/.*\/([0-9.]*)\/[0-9]*\/.*\.dmg$/\1/')
expectedTeamID="P76M9BE8DQ"
;;
clickshare)
- # credit: Søren Theilgaard (@theilgaard)
name="ClickShare"
type="appInDmgInZip"
- 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)
+ downloadURL="https://www.barco.com$( curl -fs "https://www.barco.com/en/clickshare/app" | grep -A6 -i "macos" | grep -i "FileNumber" | tr '"' "\n" | grep -i "FileNumber" )"
+ appNewVersion="$(eval "$( echo $downloadURL | sed -E 's/.*(MajorVersion.*BuildVersion=[0-9]*).*/\1/' | sed 's/&//g' )" ; ((MajorVersion++)) ; ((MajorVersion--)); ((MinorVersion++)) ; ((MinorVersion--)); ((PatchVersion++)) ; ((PatchVersion--)); ((BuildVersion++)) ; ((BuildVersion--)); echo "${MajorVersion}.${MinorVersion}.${PatchVersion}-b${BuildVersion}")"
expectedTeamID="P6CDJZR997"
;;
clipy)
@@ -1956,6 +2186,20 @@ cluefull)
versionKey="CFBundleVersion"
expectedTeamID="3NX6B9TB2F"
;;
+cocoapods)
+ name="CocoaPods"
+ type="bz2"
+ downloadURL="$(downloadURLFromGit CocoaPods CocoaPods-app)"
+ appNewVersion="$(versionFromGit CocoaPods CocoaPods-app)"
+ expectedTeamID="AX2Q2BH2XR"
+ ;;
+coconutbattery)
+ name="coconutBattery"
+ type="zip"
+ downloadURL="https://coconut-flavour.com/downloads/coconutBattery_latest.zip"
+ appNewVersion=$(curl -fs https://www.coconut-flavour.com/coconutbattery/ | grep "
" | sed -e 's/.*coconutBattery \(.*\) - by coconut-flavour.co.*/\1/')
+ expectedTeamID="R5SC3K86L5"
+ ;;
code42)
name="Code42"
type="pkgInDmg"
@@ -1968,14 +2212,14 @@ code42)
blockingProcesses=( NONE )
;;
coderunner)
- # credit: Erik Stam (@erikstam)
name="CodeRunner"
type="zip"
downloadURL="https://coderunnerapp.com/download"
+ appNewVersion=$(curl -fsIL ${downloadURL} | grep -i "^location" | cut -d " " -f2 | sed -E 's/.*CodeRunner-([0-9.]*).zip/\1/')
expectedTeamID="R4GD98AJF9"
;;
colourcontrastanalyser)
- name="Colour Contrast Analyser (CCA)"
+ name="Colour Contrast Analyser"
type="dmg"
downloadURL=$(downloadURLFromGit ThePacielloGroup CCAe)
appNewVersion=$(versionFromGit ThePacielloGroup CCAe)
@@ -2005,9 +2249,22 @@ craftmanagerforsketch)
appNewVersion=$(curl -fs https://craft-assets.invisionapp.com/CraftManager/production/appcast.xml | xpath '//rss/channel/item[1]/enclosure/@sparkle:shortVersionString' 2>/dev/null | cut -d '"' -f2)
expectedTeamID="VRXQSNCL5W"
;;
+cricutdesignspace)
+ name="Cricut Design Space"
+ type="dmg"
+ appNewVersion=$(getJSONValue "$(curl -fsL https://s3-us-west-2.amazonaws.com/staticcontent.cricut.com/a/software/osx-native/latest.json)" "rolloutVersion")
+ downloadURL=$(getJSONValue $(curl -fsL "https://apis.cricut.com/desktopdownload/InstallerFile?shard=a&operatingSystem=osxnative&fileName=CricutDesignSpace-Install-v${appNewVersion}.dmg") "result")
+ expectedTeamID="25627ZFVT7"
+ ;;
cryptomator)
name="Cryptomator"
type="dmg"
+ if [[ $(arch) == "arm64" ]]; then
+ archiveName="Cryptomator-[0-9.]*-arm64.dmg"
+
+ elif [[ $(arch) == "i386" ]]; then
+ archiveName="Cryptomator-[0-9.]*.dmg"
+ fi
downloadURL=$(downloadURLFromGit cryptomator cryptomator)
appNewVersion=$(versionFromGit cryptomator cryptomator)
expectedTeamID="YZQJQUHA3L"
@@ -2029,8 +2286,8 @@ daisydisk)
dangerzone)
name="Dangerzone"
type="dmg"
- downloadURL="$(downloadURLFromGit firstlookmedia dangerzone)"
- appNewVersion="$(versionFromGit firstlookmedia dangerzone)"
+ downloadURL="$(downloadURLFromGit freedomofpress dangerzone)"
+ appNewVersion="$(versionFromGit freedomofpress dangerzone)"
expectedTeamID="N9B95FDWH4"
;;
darktable)
@@ -2163,7 +2420,7 @@ dockutil)
drawio)
name="draw.io"
type="dmg"
- archiveName="draw.io-universal-[0-9.]*.dmg"
+ archiveName="draw.io-universal-[0-9.]*.dmg$"
downloadURL="$(downloadURLFromGit jgraph drawio-desktop)"
appNewVersion="$(versionFromGit jgraph drawio-desktop)"
expectedTeamID="UZEUFB4N53"
@@ -2193,6 +2450,22 @@ duckduckgo)
appNewVersion=$(curl -fs https://staticcdn.duckduckgo.com/macos-desktop-browser/appcast.xml | xpath '(//rss/channel/item/sparkle:shortVersionString)[1]' 2>/dev/null | cut -d ">" -f2 | cut -d "<" -f1)
expectedTeamID="HKE973VLUW"
;;
+duodevicehealth)
+ name="Duo Device Health"
+ type="pkgInDmg"
+ downloadURL="https://dl.duosecurity.com/DuoDeviceHealth-latest.dmg"
+ appNewVersion=$(curl -fsLIXGET "https://dl.duosecurity.com/DuoDeviceHealth-latest.dmg" | grep -i "^content-disposition" | sed -e 's/.*filename\=\"DuoDeviceHealth\-\(.*\)\.dmg\".*/\1/')
+ appName="Duo Device Health.app"
+ expectedTeamID="FNN8Z5JMFP"
+ ;;
+
+dynalist)
+ name="Dynalist"
+ type="dmg"
+ downloadURL="https://dynalist.io/standalone/download?file=Dynalist.dmg"
+ appNewVersion=""
+ expectedTeamID="6JSW4SJWN9"
+ ;;
easeusdatarecoverywizard)
# credit: Søren Theilgaard (@theilgaard)
name="EaseUS Data Recovery Wizard"
@@ -2213,6 +2486,7 @@ egnyte)
name="Egnyte Connect"
type="pkg"
downloadURL="https://egnyte-cdn.egnyte.com/egnytedrive/mac/en-us/latest/EgnyteConnectMac.pkg"
+ appNewVersion=$(curl -fs "https://egnyte-cdn.egnyte.com/egnytedrive/mac/en-us/versions/default.xml" | xpath '(//rss/channel/item/enclosure/@sparkle:shortVersionString)[1]' | cut -d '"' -f 2)
expectedTeamID="FELUD555VC"
blockingProcesses=( NONE )
;;
@@ -2299,6 +2573,13 @@ favro)
appNewVersion="$(curl -fs https://download.favro.com/FavroDesktop/macOS/x64/Latest.html | cut -d ">" -f1 | cut -d "=" -f 4 | cut -d '"' -f1 | sed -E 's/.*-([0-9.]*)\.dmg/\1/g')"
expectedTeamID="PUA8Q354ZF"
;;
+fellow)
+ name="Fellow"
+ type="dmg"
+ downloadURL="https://cdn.fellow.app/desktop/1.3.11/darwin/stable/universal/Fellow-1.3.11-universal.dmg"
+ appNewVersion=""
+ expectedTeamID="2NF46HY8D8"
+ ;;
ferdi)
name="Ferdi"
type="zip"
@@ -2343,7 +2624,8 @@ firefox)
name="Firefox"
type="dmg"
downloadURL="https://download.mozilla.org/?product=firefox-latest&os=osx&lang=en-US"
- appNewVersion=$(curl -fs https://www.mozilla.org/en-US/firefox/releases/ | grep '/dev/null | cut -d '"' -f 2)
+ downloadURL="https://download-mac.grammarly.com/Grammarly.dmg"
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"
installerTool="Grammarly Installer.app"
CLIInstaller="Grammarly Installer.app/Contents/MacOS/Grammarly Desktop"
@@ -2729,11 +3049,10 @@ ibarcoder)
expectedTeamID="JAXVB9AH9M"
;;
icons)
- # credit: Mischa van der Bent (@mischavdbent)
name="Icons"
type="zip"
- downloadURL=$(downloadURLFromGit sap macOS-icon-generator )
- appNewVersion=$(versionFromGit sap macOS-icon-generator )
+ downloadURL=$(downloadURLFromGit SAP macOS-icon-generator )
+ appNewVersion=$(versionFromGit SAP macOS-icon-generator )
expectedTeamID="7R5ZEU67FQ"
;;
idrive)
@@ -2787,10 +3106,12 @@ inkscape)
expectedTeamID="SW3D6BB6A6"
;;
insomnia)
- name="insomnia"
+ name="Insomnia"
type="dmg"
- downloadURL=$(downloadURLFromGit kong insomnia)
- appNewVersion=$(versionFromGit kong insomnia)
+ #downloadURL=$(downloadURLFromGit kong insomnia)
+ downloadURL=$(curl -fs "https://updates.insomnia.rest/downloads/mac/latest?app=com.insomnia.app&source=website" | grep -o "https.*\.dmg")
+ #appNewVersion=$(versionFromGit kong insomnia)
+ appNewVersion=$(echo "$downloadURL" | sed -E 's/.*\/Insomnia.Core.([0-9.]*)\.dmg/\1/')
expectedTeamID="FX44YY62GV"
;;
installomator|\
@@ -2803,6 +3124,14 @@ installomator_theile)
expectedTeamID="JME5BW3F3R"
blockingProcesses=( NONE )
;;
+ipswupdater)
+ name="IPSW Updater"
+ type="zip"
+ ipswupdaterVersions=$(curl -fs "https://ipsw.app/download/updates.php?current_version=0.9.16")
+ downloadURL=$(getJSONValue "$ipswupdaterVersions" "[0].url")
+ appNewVersion=$(getJSONValue "$ipswupdaterVersions" "[0].version")
+ expectedTeamID="YRW6NUGA63"
+ ;;
istatmenus)
# credit: AP Orlebeke (@apizz)
name="iStat Menus"
@@ -3000,6 +3329,20 @@ jetbrainswebstorm)
appNewVersion=$( curl -fsIL "${downloadURL}" | grep -i "location" | tail -1 | sed -E 's/.*\/[a-zA-Z-]*-([0-9.]*).*[-.].*dmg/\1/g' )
expectedTeamID="2ZEFAR8TH3"
;;
+kap)
+ # credit: Lance Stephens (@pythoninthegrass on MacAdmins Slack)
+ name="Kap"
+ type="dmg"
+ if [[ $(arch) = "i386" ]]; then
+ archiveName="${name}-[0-9.]*-x64.${type}"
+ downloadURL=$(downloadURLFromGit wulkano kap | grep -i x64)
+ else
+ archiveName="${name}-[0-9.]*-arm64.${type}"
+ downloadURL=$(downloadURLFromGit wulkano kap | grep -i arm64)
+ fi
+ appNewVersion=$(versionFromGit wulkano Kap)
+ expectedTeamID="2KEEHXF6R6"
+ ;;
karabinerelements)
# credit: Tadayuki Onishi (@kenchan0130)
name="Karabiner-Elements"
@@ -3020,6 +3363,14 @@ keepassxc)
appNewVersion=$(versionFromGit keepassxreboot keepassxc)
expectedTeamID="G2S7P7J672"
;;
+keepingyouawake)
+ name="KeepingYouAwake"
+ type="zip"
+ downloadURL=$(downloadURLFromGit newmarcel KeepingYouAwake)
+ appNewVersion=$(versionFromGit newmarcel KeepingYouAwake)
+ expectedTeamID="5KESHV9W85"
+ blockingProcesses=( "KeepingYouAwake" )
+ ;;
keka)
name="Keka"
type="dmg"
@@ -3053,8 +3404,8 @@ klokki)
knockknock)
name="KnockKnock"
type="zip"
- downloadURL=$( curl -fs "https://objective-see.com/products/knockknock.html" | grep https | grep "$type" | head -1 | tr '"' "\n" | grep "^http" )
- appNewVersion=$( echo "${downloadURL}" | sed -E 's/.*\/[a-zA-Z]*_([0-9.]*)\..*/\1/g' )
+ downloadURL="$(downloadURLFromGit objective-see KnockKnock)"
+ appNewVersion="$(versionFromGit objective-see KnockKnock)"
expectedTeamID="VBG97UB4TA"
;;
krisp)
@@ -3086,6 +3437,13 @@ launchbar)
appNewVersion=$( echo ${downloadURL} | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)\..*/\1/g' )
expectedTeamID="MLZF7K7B5R"
;;
+lcadvancedvpnclient)
+ name="LANCOM Advanced VPN Client"
+ type="pkgInDmg"
+ appNewVersion=$(curl -fs https://www.ncp-e.com/de/service/download-vpn-client/ | grep -m 1 "NCP Secure Entry macOS Client" -A 1 | grep -i Version | sed "s|.*Version \(.*\) Rev.*|\\1|")
+ downloadURL=$(appShortVersion=`sed 's/[^0-9]//g' <<< $appNewVersion` && echo https://ftp.lancom.de/LANCOM-Releases/LC-VPN-Client/LC-Advanced-VPN-Client-macOS-"${appShortVersion}"-Rel-x86-64.dmg)
+ expectedTeamID="LL3KBL2M3A"
+ ;;
lexarrecoverytool)
name="Lexar Recovery Tool"
type="appInDmgInZip"
@@ -3096,11 +3454,11 @@ libreoffice)
name="LibreOffice"
type="dmg"
if [[ $(arch) == "arm64" ]]; then
- downloadURL="https://download.documentfoundation.org/libreoffice/stable/$(curl -s https://www.libreoffice.org/download/download/ | grep dl_version_number | head -n 1 | cut -d'>' -f3 | cut -d'<' -f1)/mac/aarch64/LibreOffice_$(curl -s https://www.libreoffice.org/download/download/ | grep dl_version_number | head -n 1 | cut -d'>' -f3 | cut -d'<' -f1)_MacOS_aarch64.dmg"
- elif [[ $(arch) == "i386" ]]; then
- downloadURL="https://download.documentfoundation.org/libreoffice/stable/$(curl -s https://www.libreoffice.org/download/download/ | grep dl_version_number | head -n 1 | cut -d'>' -f3 | cut -d'<' -f1)/mac/x86_64/LibreOffice_$(curl -s https://www.libreoffice.org/download/download/ | grep dl_version_number | head -n 1 | cut -d'>' -f3 | cut -d'<' -f1)_MacOS_x86-64.dmg"
+ arch_type="aarch64"
fi
- appNewVersion=$( echo "${downloadURL}" | sed -E 's/.*\/[a-zA-Z]*_([0-9.]*)_.*/\1/g' )
+ libreoffice_latest_version="$(curl -Ls https://www.libreoffice.org/download/download-libreoffice/ | grep dl_version_number | head -n 1 | cut -d'>' -f3 | cut -d'<' -f1)"
+ downloadURL="https://download.documentfoundation.org/libreoffice/stable/${libreoffice_latest_version}/mac/${arch_type:-x86_64}/LibreOffice_${libreoffice_latest_version}_MacOS_${arch_type:-x86-64}.dmg"
+ appNewVersion=$(echo "${downloadURL}" | sed -E 's/.*\/[a-zA-Z]*_([0-9.]*)_.*/\1/g')
expectedTeamID="7P5S3ZLCN7"
blockingProcesses=( soffice )
;;
@@ -3225,7 +3583,7 @@ macports)
archiveName="Catalina.pkg"
;;
*)
- cleanupAndExit 1 "macOS 10.14 or earlier not supported by Installomator."
+ cleanupAndExit 98 "macOS 10.14 or earlier not supported by Installomator."
;;
esac
downloadURL=$(downloadURLFromGit macports macports-base)
@@ -3244,6 +3602,7 @@ marathon)
name="Marathon"
type="dmg"
archiveName="Marathon-[0-9.]*-Mac.dmg"
+ versionKey="CFBundleVersion"
downloadURL="$(downloadURLFromGit Aleph-One-Marathon alephone)"
appNewVersion="$(versionFromGit Aleph-One-Marathon alephone)"
expectedTeamID="E8K89CXZE7"
@@ -3252,6 +3611,7 @@ marathon2)
name="Marathon 2"
type="dmg"
archiveName="Marathon2-[0-9.]*-Mac.dmg"
+ versionKey="CFBundleVersion"
downloadURL="$(downloadURLFromGit Aleph-One-Marathon alephone)"
appNewVersion="$(versionFromGit Aleph-One-Marathon alephone)"
expectedTeamID="E8K89CXZE7"
@@ -3260,10 +3620,17 @@ marathoninfinity)
name="Marathon Infinity"
type="dmg"
archiveName="MarathonInfinity-[0-9.]*-Mac.dmg"
+ versionKey="CFBundleVersion"
downloadURL="$(downloadURLFromGit Aleph-One-Marathon alephone)"
appNewVersion="$(versionFromGit Aleph-One-Marathon alephone)"
expectedTeamID="E8K89CXZE7"
;;
+masv)
+ name="MASV"
+ type="dmg"
+ downloadURL="https://dl.massive.io/MASV.dmg"
+ expectedTeamID="VHKX7RCAY7"
+ ;;
mattermost)
name="Mattermost"
type="dmg"
@@ -3280,6 +3647,13 @@ menumeters)
appNewVersion=$(versionFromGit yujitach MenuMeters )
expectedTeamID="95AQ7YKR5A"
;;
+merlinproject)
+ name="Merlin Project"
+ type="zip"
+ downloadURL="https://www.projectwizards.net/downloads/MerlinProject.zip"
+ appNewVersion="$(curl -fs "https://www.projectwizards.net/de/support/release-notes" | grep Version | head -n 6 | tail -n 1 | sed 's/[^0-9.]*//g')"
+ expectedTeamID="9R6P9VZV27"
+ ;;
microsoftautoupdate)
name="Microsoft AutoUpdate"
type="pkg"
@@ -3541,16 +3915,6 @@ microsoftword)
updateTool="/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate"
updateToolArguments=( --install --apps MSWD2019 )
;;
-microsoftyammer)
- name="Yammer"
- type="dmg"
- downloadURL="https://aka.ms/yammer_desktop_mac"
- #appNewVersion=$(curl -fs https://macadmins.software/latest.xml | xpath '//latest/oldpackage[id="com.microsoft.yammer.standalone"]/cfbundleshortversionstring' 2>/dev/null | sed -E 's/([0-9.]*)<.*/\1/')
- appNewVersion=$(curl -fsIL "$downloadURL" | grep -i location: | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)\..*/\1/g')
- expectedTeamID="UBF8T346G9"
- #updateTool="/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate --list; /Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate"
- #updateToolArguments=( --install --apps ?????? )
- ;;
mightymike)
name="Mighty Mike"
type="dmg"
@@ -3569,9 +3933,21 @@ miro)
# credit: @matins
name="Miro"
type="dmg"
- downloadURL="https://desktop.miro.com/platforms/darwin/Miro.dmg"
+ if [[ $(arch) == arm64 ]]; then
+ downloadURL="https://desktop.miro.com/platforms/darwin-arm64/Miro.dmg"
+ elif [[ $(arch) == i386 ]]; then
+ downloadURL="https://desktop.miro.com/platforms/darwin/Miro.dmg"
+ fi
expectedTeamID="M3GM7MFY7U"
;;
+mmhmm)
+ name="mmhmm"
+ type="pkg"
+ downloadURL="https://updates.mmhmm.app/mac/mmhmm.pkg"
+ curlOptions=( -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Safari/605.1.15" )
+ appNewVersion=$(curl -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" -fs "https://help.mmhmm.app/hc/en-us/articles/4420969712151-mmhmm-for-Mac" | grep 'The latest version of mmhmm for Mac is *' | sed -e 's/.*\\(.*\)\.\<\/strong\>.*/\1/')
+ expectedTeamID="M3KUT44L48"
+ ;;
mobikinassistantforandroid)
name="MobiKin Assistant for Android"
type="dmg"
@@ -3660,6 +4036,14 @@ mochatn5250)
appNewVersion=""
expectedTeamID="RR9F5EPNVW"
;;
+mongodbcompass)
+ name="MongoDB Compass"
+ type="dmg"
+ archiveName="mongodb-compass-[0-9.]*-darwin-x64.dmg"
+ downloadURL="$(downloadURLFromGit mongodb-js compass)"
+ appNewVersion="$(versionFromGit mongodb-js compass)"
+ expectedTeamID="4XWMY46275"
+ ;;
montereyblocker)
name="montereyblocker"
type="pkg"
@@ -3705,6 +4089,13 @@ netnewswire)
appNewVersion=$(curl -fs https://ranchero.com/downloads/netnewswire-release.xml | xpath '//rss/channel/item[1]/enclosure/@sparkle:shortVersionString' 2>/dev/null | cut -d '"' -f 2)
expectedTeamID="M8L2WTLA8W"
;;
+netspot)
+ name="NetSpot"
+ type="dmg"
+ downloadURL="https://cdn.netspotapp.com/download/NetSpot.dmg"
+ appNewVersion=$(curl -fs "https://www.netspotapp.com/updates/netspot2-appcast.xml" | xpath '(//rss/channel/item/enclosure/@sparkle:version)' 2>/dev/null | cut -d '"' -f 2)
+ expectedTeamID="5QLDY8TU83"
+ ;;
nextcloud)
name="nextcloud"
type="pkg"
@@ -3724,6 +4115,7 @@ nomad)
downloadURL="https://files.nomad.menu/NoMAD.pkg"
appNewVersion=$(curl -fs https://nomad.menu/support/ | grep "NoMAD Downloads" | sed -E 's/.*Current Version ([0-9\.]*)<.*/\1/g')
expectedTeamID="VRPY9KHGX6"
+ blockingProcesses=( NONE )
;;
nomadlogin)
# credit: Søren Theilgaard (@theilgaard)
@@ -3733,16 +4125,24 @@ nomadlogin)
appNewVersion=$(curl -fs https://nomad.menu/support/ | grep "NoMAD Login AD Downloads" | sed -E 's/.*Current Version ([0-9\.]*)<.*/\1/g')
expectedTeamID="AAPZK3CB24"
;;
+nordlayer)
+ # credit: Taboc741 (https://github.com/taboc741)
+ name="NordLayer"
+ type="pkg"
+ downloadURL="https://downloads.nordlayer.com/mac/latest/NordLayer.pkg"
+ expectedTeamID="W5W395V82Y"
+ ;;
notion)
# credit: Søren Theilgaard (@theilgaard)
name="Notion"
type="dmg"
if [[ $(arch) == "arm64" ]]; then
downloadURL="https://www.notion.so/desktop/apple-silicon/download"
+ appNewVersion=$( curl -fsIL "https://www.notion.so/desktop/apple-silicon/download" | grep -i "^location" | awk '{print $2}' | sed -e 's/.*Notion\-\(.*\)\-arm64.dmg.*/\1/' )
elif [[ $(arch) == "i386" ]]; then
downloadURL="https://www.notion.so/desktop/mac/download"
+ appNewVersion=$( curl -fsIL "https://www.notion.so/desktop/mac/download" | grep -i "^location" | awk '{print $2}' | sed -e 's/.*Notion\-\(.*\).dmg.*/\1/' )
fi
- appNewVersion=$( curl -fsIL "${downloadURL}" | grep -i "^location" | awk '{print $2}' | tr -d '\r\n' | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)\..*/\1/g' )
expectedTeamID="LBQJ96FQ8D"
;;
nudge)
@@ -3878,8 +4278,8 @@ openvpnconnectv3)
opera)
name="Opera"
type="dmg"
- downloadURL=$(curl -fsIL "$(curl -fs "$(curl -fsIL "https://download.opera.com/download/get/?partner=www&opsys=MacOS" | grep -i "^location" | cut -d " " -f2 | tail -1 | tr -d '\r')" | grep download.opera.com | grep -io "https.*yes" | sed 's/\&/\&/g')" | grep -i "^location" | cut -d " " -f2 | tr -d '\r')
- appNewVersion="$(curl -fs "https://get.geo.opera.com/ftp/pub/opera/desktop/" | grep "href=\"\d" | sort -V | tail -1 | tr '"' '\n' | grep "/" | head -1 | tr -d '/')"
+ downloadURL="$(curl -fsIL "$(curl -fs "$(curl -fsL "https://download.opera.com/download/get/?partner=www&opsys=MacOS" | tr '"' "\n" | grep -e "www.opera.com.*thanks.*opera" | sed 's/\&\;/\&/g')" | tr '"' "\n" | grep "download.opera.com" | sed 's/\&\;/\&/g')" | grep -i "^location" | grep -io "https.*dmg")"
+ appNewVersion="$(printf "$downloadURL" | sed -E 's/https.*\/([0-9.]*)\/mac\/.*/\1/')"
versionKey="CFBundleVersion"
expectedTeamID="A2P9LX4JPN"
;;
@@ -4062,6 +4462,13 @@ proxyman)
appNewVersion="$(versionFromGit ProxymanApp Proxyman)"
expectedTeamID="3X57WP8E8V"
;;
+prune)
+ name="Prune"
+ type="zip"
+ downloadURL=$(downloadURLFromGit BIG-RAT Prune)
+ appNewVersion=$(versionFromGit BIG-RAT Prune)
+ expectedTeamID="PS2F6S478M"
+;;
pymol)
name="PyMOL"
type="dmg"
@@ -4118,6 +4525,13 @@ redeye)
appNewVersion=$( curl -fs "https://www.hexedbits.com/redeye/" | grep "Latest version" | sed -E 's/.*Latest version ([0-9.]*),.*/\1/g' )
expectedTeamID="5VRJU68BZ5"
;;
+relatel)
+ name="Relatel"
+ type="dmg"
+ downloadURL="https://cdn.rela.tel/www/public/junotron/Relatel.dmg"
+ appNewVersion="$(curl -fs "https://cdn.firmafon.dk/www/public/junotron/latest-mac.yml" | grep -i "version" | cut -w -f2)"
+ expectedTeamID="B9358QF55B"
+ ;;
remotedesktopmanagerenterprise)
name="Remote Desktop Manager"
type="dmg"
@@ -4133,21 +4547,6 @@ remotedesktopmanagerfree)
appNewVersion=$(echo "$downloadURL" | sed -E 's/.*\.Mac\.([0-9.]*)\.dmg/\1/g')
expectedTeamID="N592S9ASDB"
;;
-remotix)
- name="Remotix"
- type="dmg"
- downloadURL="https://remotix.com/downloads/latest-remotix-mac/"
- appNewVersion=$( curl -fsIL "${downloadURL}" | grep -i "^location" | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)-.*\.dmg/\1/g' )
- expectedTeamID="K293Y6CVN4"
- ;;
-remotixagent)
- name="RemotixAgent"
- type="pkg"
- packageID="com.nulana.rxagentmac"
- downloadURL="https://remotix.com/downloads/latest-agent-mac/"
- appNewVersion=$( curl -fsIL "${downloadURL}" | grep -i "^location" | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)-.*\.pkg/\1/g' )
- expectedTeamID="K293Y6CVN4"
- ;;
resiliosynchome)
name="Resilio Sync"
type="dmg"
@@ -4170,7 +4569,7 @@ ricohpsprinters)
;;
ringcentralapp)
# credit: Isaac Ordonez, Mann consulting (@mannconsulting)
- name="Ringcentral"
+ name="RingCentral"
type="pkg"
if [[ $(arch) != "i386" ]]; then
downloadURL="https://app.ringcentral.com/download/RingCentral-arm64.pkg"
@@ -4178,7 +4577,7 @@ ringcentralapp)
downloadURL="https://app.ringcentral.com/download/RingCentral.pkg"
fi
expectedTeamID="M932RC5J66"
- blockingProcesses=( "Ringcentral" )
+ blockingProcesses=( "RingCentral" )
;;
ringcentralclassicapp)
name="Glip"
@@ -4248,6 +4647,7 @@ santa)
downloadURL=$(downloadURLFromGit google santa)
appNewVersion=$(versionFromGit google santa)
expectedTeamID="EQHXZ8M8AV"
+ blockingProcesses=( NONE )
;;
scaleft)
name="ScaleFT"
@@ -4440,6 +4840,13 @@ snapgeneviewer)
appNewVersion=$( curl -fsIL "${downloadURL}" | grep -i "^location" | awk '{print $2}' | tr '/' '\n' | grep -i "dmg" | sed -E 's/[a-zA-Z_]*_([0-9.]*)_mac\.dmg/\1/g' )
expectedTeamID="WVCV9Q8Y78"
;;
+sonicvisualiser)
+ name="Sonic Visualiser"
+ type="dmg"
+ downloadURL="$(downloadURLFromGit sonic-visualiser sonic-visualiser)"
+ appNewVersion="$(versionFromGit sonic-visualiser sonic-visualiser)"
+ expectedTeamID="73F996B92S"
+ ;;
sonobus)
name="Sonobus"
type="pkgInDmg"
@@ -4508,6 +4915,15 @@ steelseriesengine)
appNewVersion="$(curl -fsIL "$downloadURL" | grep -i "^location" | sed -E 's/.*SteelSeriesGG([0-9.]*)\.pkg/\1/')"
expectedTeamID="6WGL6CHFH2"
;;
+strongdm)
+ name="strongDM"
+ type="dmg"
+ downloadURL="https://app.strongdm.com/downloads/client/darwin"
+ appNewVersion=$(curl -fsLIXGET "https://app.strongdm.com/downloads/client/darwin" | grep -i "^content-disposition" | sed -e 's/.*filename\=\"SDM\-\(.*\)\.dmg\".*/\1/')
+ appName="SDM.app"
+ blockingProcesses=( "SDM" )
+ expectedTeamID="W5HSYBBJGA"
+ ;;
strongsync)
name="Strongsync"
type="dmg"
@@ -4521,7 +4937,7 @@ sublimetext)
# credit: Søren Theilgaard (@theilgaard)
name="Sublime Text"
type="zip"
- downloadURL="$(curl -fs https://www.sublimetext.com/download | grep -io "https://download.*_mac.zip")"
+ downloadURL="$(curl -fs "https://www.sublimetext.com/download_thanks?target=mac#direct-downloads" | grep -io "https://download.*_mac.zip" | head -1)"
appNewVersion=$(curl -fs https://www.sublimetext.com/download | grep -i -A 4 "id.*changelog" | grep -io "Build [0-9]*")
expectedTeamID="Z6D26JE4Y4"
;;
@@ -4543,8 +4959,7 @@ supportapp)
downloadURL=$(downloadURLFromGit root3nl SupportApp)
appNewVersion=$(versionFromGit root3nl SupportApp)
expectedTeamID="98LJ4XBGYK"
- uid=$(id -u "$currentUser")
- launchctl bootout gui/${uid} "/Library/LaunchAgents/nl.root3.support.plist"
+ blockingProcesses=( NONE )
;;
suspiciouspackage)
# credit: Mischa van der Bent (@mischavdbent)
@@ -4568,6 +4983,22 @@ sync)
appNewVersion="$(curl -fs "https://www.sync.com/blog/category/desktop/feed/" | xpath '(//channel/item/title)[1]' 2>/dev/null | sed -E 's/^.* ([0-9.]*) .*$/\1/g')"
expectedTeamID="7QR39CMJ3W"
;;
+synologyassistant)
+ name="SynologyAssistant"
+ type="dmg"
+ packageID="com.synology.DSAssistant"
+ appNewVersion="$(curl -sf https://archive.synology.com/download/Utility/Assistant | grep -m 1 /download/Utility/Assistant/ | sed "s|.*>\(.*\)<.*|\\1|")"
+ downloadURL="https://global.download.synology.com/download/Utility/Assistant/${appNewVersion}/Mac/synology-assistant-${appNewVersion}.dmg"
+ expectedTeamID="X85BAK35Y4"
+ ;;
+synologydriveclient)
+ name="Synology Drive Client"
+ type="pkgInDmg"
+ packageID="com.synology.CloudStation"
+ downloadURL=$(appVersion=`curl -sf https://archive.synology.com/download/Utility/SynologyDriveClient | grep -m 1 /download/Utility/SynologyDriveClient/ | sed "s|.*>\(.*\)<.*|\\1|"` && appShortVersion=`sed 's#.*-\(\)#\1#' <<< $appVersion` && echo https://global.download.synology.com/download/Utility/SynologyDriveClient/"$appVersion"/Mac/Installer/synology-drive-client-"${appShortVersion}".dmg)
+ appNewVersion=$(appVersionP1=`curl -sf https://archive.synology.com/download/Utility/SynologyDriveClient | grep -m 1 /download/Utility/SynologyDriveClient/ | sed "s|.*>\(.*\)-.*|\\1|"` && sed 's/\(.\{0\}\)./\17/' <<< $appVersionP1)
+ expectedTeamID="X85BAK35Y4"
+ ;;
tableaudesktop)
name="Tableau Desktop"
type="pkgInDmg"
@@ -4600,14 +5031,16 @@ tageditor)
talkdeskcallbar)
name="Callbar"
type="dmg"
- appNewVersion=$(curl -fsL https://downloadcallbar.talkdesk.com/release_metadata.json | sed -n 's/^.*"version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*$/\1/p')
+ talkdeskcallbarVersions=$(curl -fsL "https://downloadcallbar.talkdesk.com/release_metadata.json")
+ appNewVersion=$(getJSONValue "$talkdeskcallbarVersions" "version")
downloadURL=https://downloadcallbar.talkdesk.com/Callbar-${appNewVersion}.dmg
expectedTeamID="YGGJX44TB8"
;;
talkdeskcxcloud)
name="Talkdesk"
type="dmg"
- appNewVersion=$(curl -fs https://td-infra-prd-us-east-1-s3-atlaselectron.s3.amazonaws.com/talkdesk-latest-metadata.json | sed -n -e 's/^.*"version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*$/\1/p' | head -n 1)
+ talkdeskcxcloudVersions=$(curl -fs "https://td-infra-prd-us-east-1-s3-atlaselectron.s3.amazonaws.com/talkdesk-latest-metadata.json")
+ appNewVersion=$(getJSONValue "$talkdeskcxcloudVersions" "[0].version")
downloadURL="https://td-infra-prd-us-east-1-s3-atlaselectron.s3.amazonaws.com/talkdesk-${appNewVersion}.dmg"
expectedTeamID="YGGJX44TB8"
;;
@@ -4666,6 +5099,21 @@ tembo)
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"
;;
+tencentmeeting)
+ name="TencentMeeting"
+ type="dmg"
+ if [[ $(arch) == "arm64" ]]; then
+ downloadURL="$(curl -fs 'https://meeting.tencent.com/web-service/query-download-info?q=%5B%7B%22package-type%22%3A%22app%22%2C%22channel%22%3A%220300000000%22%2C%22platform%22%3A%22mac%22%2C%22arch%22%3A%22arm64%22%7D%5D&c_os=web&c_os_version=1&c_os_model=web&c_timestamp=1653366550252&c_instance_id=5&c_nonce=DcaDam4y&c_app_id=1400143280&c_app_version=1&c_lang=zh-cn&c_district=0&nonce=miwSceJNQaSZttma' -H 'authority: meeting.tencent.com' -H 'referer: https://meeting.tencent.com/download-mac.html?from=1000&fromSource=1&macType=apple' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Safari/605.1.15' | grep -o "https://updatecdn.meeting.qq.com[^']*\.publish.arm64.dmg")"
+ appNewVersion=$(curl -fs 'https://meeting.tencent.com/web-service/query-download-info?q=%5B%7B%22package-type%22%3A%22app%22%2C%22channel%22%3A%220300000000%22%2C%22platform%22%3A%22mac%22%2C%22arch%22%3A%22arm64%22%7D%5D&c_os=web&c_os_version=1&c_os_model=web&c_timestamp=1653366550252&c_instance_id=5&c_nonce=DcaDam4y&c_app_id=1400143280&c_app_version=1&c_lang=zh-cn&c_district=0&nonce=miwSceJNQaSZttma' -H 'authority: meeting.tencent.com' -H 'referer: https://meeting.tencent.com/download-mac.html?from=1000&fromSource=1&macType=apple' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Safari/605.1.15' | grep -o "https://updatecdn.meeting.qq.com[^']*\.publish.arm64.dmg" | sed -e 's/.*TencentMeeting\_0300000000\_\(.*\)\.publish\.arm64\.dmg.*/\1/')
+ elif [[ $(arch) == "i386" ]]; then
+ downloadURL="$(curl -fs 'https://meeting.tencent.com/web-service/query-download-info?q=%5B%7B%22package-type%22%3A%22app%22%2C%22channel%22%3A%220300000000%22%2C%22platform%22%3A%22mac%22%2C%22arch%22%3A%22x86_64%22%7D%5D&c_os=web&c_os_version=1&c_os_model=web&c_timestamp=1653366500890&c_instance_id=5&c_nonce=jA4P4JPY&c_app_id=1400143280&c_app_version=1&c_lang=zh-cn&c_district=0&nonce=tF6Bm4FYHJwdPeGH' -H 'authority: meeting.tencent.com' -H 'referer: https://meeting.tencent.com/download-mac.html?from=1000&fromSource=1' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Safari/605.1.15' | grep -o "https://updatecdn.meeting.qq.com[^']*\.publish.x86_64.dmg")"
+ appNewVersion=$(curl -fs 'https://meeting.tencent.com/web-service/query-download-info?q=%5B%7B%22package-type%22%3A%22app%22%2C%22channel%22%3A%220300000000%22%2C%22platform%22%3A%22mac%22%2C%22arch%22%3A%22x86_64%22%7D%5D&c_os=web&c_os_version=1&c_os_model=web&c_timestamp=1653366500890&c_instance_id=5&c_nonce=jA4P4JPY&c_app_id=1400143280&c_app_version=1&c_lang=zh-cn&c_district=0&nonce=tF6Bm4FYHJwdPeGH' -H 'authority: meeting.tencent.com' -H 'referer: https://meeting.tencent.com/download-mac.html?from=1000&fromSource=1' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Safari/605.1.15' | grep -o "https://updatecdn.meeting.qq.com[^']*\.publish.x86_64.dmg" | sed -e 's/.*TencentMeeting\_0300000000\_\(.*\)\.publish\.x86_64\.dmg.*/\1/')
+ fi
+ curlOptions=( -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Safari/605.1.15" )
+ appCustomVersion() { echo "$(defaults read /Applications/TencentMeeting.app/Contents/Info.plist CFBundleShortVersionString)$(echo ".")$(defaults read /Applications/TencentMeeting.app/Contents/Info.plist CFBundleVersion)" }
+ expectedTeamID="88L2Q4487U"
+ ;;
+
textexpander)
name="TextExpander"
type="dmg"
@@ -4776,6 +5224,13 @@ tunnelblick)
downloadURL=$(downloadURLFromGit TunnelBlick Tunnelblick )
expectedTeamID="Z2SG5H3HC8"
;;
+typinator)
+ name="Typinator"
+ type="zip"
+ downloadURL=https://update.ergonis.com/downloads/products/typinator/Typinator.app.zip
+ appNewVersion="$(curl -fs https://update.ergonis.com/vck/typinator.xml | grep -i Program_Version | sed "s|.*>\(.*\)<.*|\\1|")"
+ expectedTeamID="TU7D9Y7GTQ"
+ ;;
typora)
name="Typora"
type="dmg"
@@ -4898,9 +5353,10 @@ vlc)
vmwarehorizonclient)
name="VMware Horizon Client"
type="dmg"
- downloadURL=$(curl -fsL "https://my.vmware.com/channel/public/api/v1.0/dlg/details?locale=en_US&downloadGroup=CART21FQ2_MAC_800&productId=1027&rPId=48989" | grep -o 'Url.*..dmg"' | cut -d '"' -f3)
- appNewVersion=$(curl -fsL "https://my.vmware.com/channel/public/api/v1.0/dlg/details?locale=en_US&downloadGroup=CART21FQ2_MAC_800&productId=1027&rPId=48989" | sed 's/.*-\(.*\)-.*/\1/')
- expectedTeamID="EG7KH642X6"
+ downloadGroup=$(curl -fsL "https://my.vmware.com/channel/public/api/v1.0/products/getRelatedDLGList?locale=en_US&category=desktop_end_user_computing&product=vmware_horizon_clients&version=horizon_8&dlgType=PRODUCT_BINARY" | grep -o '[^"]*_MAC_[^"]*')
+ fileName=$(curl -fsL "https://my.vmware.com/channel/public/api/v1.0/dlg/details?locale=en_US&category=desktop_end_user_computing&product=vmware_horizon_clients&dlgType=PRODUCT_BINARY&downloadGroup=${downloadGroup}" | grep -o '"fileName":"[^"]*"' | cut -d: -f2 | sed 's/"//g')
+ downloadURL="https://download3.vmware.com/software/$downloadGroup/${fileName}"
+ appNewVersion=$(curl -fsL "https://my.vmware.com/channel/public/api/v1.0/dlg/details?locale=en_US&downloadGroup=${downloadGroup}" | grep -o '[^"]*\.dmg[^"]*' | sed 's/.*-\(.*\)-.*/\1/') expectedTeamID="EG7KH642X6"
;;
vscodium)
name="VSCodium"
@@ -4955,37 +5411,28 @@ wechat)
downloadURL="https://dldir1.qq.com/weixin/mac/WeChatMac.dmg"
expectedTeamID="5A4RE8SF68"
;;
+whatroute)
+ name="WhatRoute"
+ type="zip"
+ downloadURL="$(curl -fs https://www.whatroute.net/whatroute2appcast.xml | xpath '(//rss/channel/item/enclosure/@url)[1]' 2>/dev/null | cut -d '"' -f2)"
+ appNewVersion="$(curl -fs https://www.whatroute.net/whatroute2appcast.xml | xpath '(//rss/channel/item/enclosure/@sparkle:shortVersionString)[1]' 2>/dev/null | cut -d '"' -f2)"
+ expectedTeamID="H5879E8LML"
+ ;;
whatsapp)
name="WhatsApp"
type="dmg"
downloadURL="https://web.whatsapp.com/desktop/mac/files/WhatsApp.dmg"
expectedTeamID="57T9237FN3"
;;
-wickrme)
- # credit: Søren Theilgaard (@theilgaard)
- name="WickrMe"
- type="dmg"
- downloadURL=$( curl -fs https://me-download.wickr.com/api/download/me/download/mac | tr '"' '\n' | grep -e '^https://' )
- appNewVersion=$( echo ${downloadURL} | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)\..*/\1/g' )
- expectedTeamID="W8RC3R952A"
- ;;
-wickrpro)
- # credit: Søren Theilgaard (@theilgaard)
- name="WickrPro"
- type="dmg"
- downloadURL=$( curl -fs https://me-download.wickr.com/api/download/pro/download/mac | tr '"' '\n' | grep -e '^https://' )
- appNewVersion=$( echo ${downloadURL} | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)\..*/\1/g' )
- expectedTeamID="W8RC3R952A"
- ;;
wireshark)
name="Wireshark"
type="dmg"
- if [[ $(arch) == i386 ]]; then
- downloadURL="https://1.as.dl.wireshark.org/osx/Wireshark%20Latest%20Intel%2064.dmg"
- elif [[ $(arch) == arm64 ]]; then
- downloadURL="https://1.as.dl.wireshark.org/osx/Wireshark%20Latest%20Arm%2064.dmg"
- fi
appNewVersion=$(curl -fs https://www.wireshark.org/download.html | grep -i "href.*_stable" | sed -E 's/.*\(([0-9.]*)\).*/\1/g')
+ if [[ $(arch) == i386 ]]; then
+ downloadURL="https://1.as.dl.wireshark.org/osx/Wireshark%20$appNewVersion%20Intel%2064.dmg"
+ elif [[ $(arch) == arm64 ]]; then
+ downloadURL="https://1.as.dl.wireshark.org/osx/Wireshark%20$appNewVersion%20Arm%2064.dmg"
+ fi
expectedTeamID="7Z6EMTD2C6"
;;
wordservice)
@@ -5004,6 +5451,17 @@ wwdc)
appNewVersion=$(versionFromGit insidegui WWDC)
expectedTeamID="8C7439RJLG"
;;
+xcreds)
+ name="XCreds"
+ #type="pkgInZip"
+ #packageID="com.twocanoes.pkg.secureremoteaccess"
+ #downloadURL=$(curl -fs "https://twocanoes.com/products/mac/xcreds/" | grep -ioE "https://.*\.zip" | head -1)
+ #appNewVersion=$(curl -fs "https://twocanoes.com/products/mac/xcreds/" | grep -io "Current Version:.*" | sed -E 's/.*XCreds *([0-9.]*)<.*/\1/g')
+ type="pkg"
+ downloadURL="$(downloadURLFromGit twocanoes xcreds)"
+ appNewVersion="$(versionFromGit twocanoes xcreds)"
+ expectedTeamID="UXP6YEHSPW"
+ ;;
xeroxphaser7800)
name="XeroxPhaser"
type="pkgInDmg"
@@ -5223,10 +5681,33 @@ fi
# MARK: application download and installation starts here
+# Debug output of all variables in a label
+printlog "name=${name}" DEBUG
+printlog "appName=${appName}" DEBUG
+printlog "type=${type}" DEBUG
+printlog "archiveName=${archiveName}" DEBUG
+printlog "downloadURL=${downloadURL}" DEBUG
+printlog "curlOptions=${curlOptions}" DEBUG
+printlog "appNewVersion=${appNewVersion}" DEBUG
+printlog "appCustomVersion function: $(if type 'appCustomVersion' 2>/dev/null | grep -q 'function'; then echo "Defined. ${appCustomVersion}"; else; echo "Not defined"; fi)" DEBUG
+printlog "versionKey=${versionKey}" DEBUG
+printlog "packageID=${packageID}" DEBUG
+printlog "pkgName=${pkgName}" DEBUG
+printlog "choiceChangesXML=${choiceChangesXML}" DEBUG
+printlog "expectedTeamID=${expectedTeamID}" DEBUG
+printlog "blockingProcesses=${blockingProcesses}" DEBUG
+printlog "installerTool=${installerTool}" DEBUG
+printlog "CLIInstaller=${CLIInstaller}" DEBUG
+printlog "CLIArguments=${CLIArguments}" DEBUG
+printlog "updateTool=${updateTool}" DEBUG
+printlog "updateToolArguments=${updateToolArguments}" DEBUG
+printlog "updateToolRunAsCurrentUser=${updateToolRunAsCurrentUser}" DEBUG
+#printlog "Company=${Company}" DEBUG # Not used
+
if [[ ${INTERRUPT_DND} = "no" ]]; then
# Check if a fullscreen app is active
if hasDisplaySleepAssertion; then
- cleanupAndExit 1 "active display sleep assertion detected, aborting" ERROR
+ cleanupAndExit 24 "active display sleep assertion detected, aborting" ERROR
fi
fi
@@ -5269,7 +5750,7 @@ case $LOGO in
if [[ -z $MDMProfileName ]]; then; MDMProfileName="Management Profile"; fi
;;
ws1)
- # Workspace ONE
+ # Workspace ONE (AirWatch)
LOGO="/Applications/Workspace ONE Intelligent Hub.app/Contents/Resources/AppIcon.icns"
if [[ -z $MDMProfileName ]]; then; MDMProfileName="Device Manager"; fi
;;
@@ -5288,7 +5769,7 @@ printlog "Label type: $type" INFO
# MARK: extract info from data
if [ -z "$archiveName" ]; then
case $type in
- dmg|pkg|zip|tbz)
+ dmg|pkg|zip|tbz|bz2)
archiveName="${name}.$type"
;;
pkgInDmg)
@@ -5314,7 +5795,7 @@ fi
if [ -z "$targetDir" ]; then
case $type in
- dmg|zip|tbz|app*)
+ dmg|zip|tbz|bz2|app*)
targetDir="/Applications"
;;
pkg*)
@@ -5345,7 +5826,7 @@ fi
# MARK: change directory to temporary working directory
printlog "Changing directory to $tmpDir" DEBUG
if ! cd "$tmpDir"; then
- cleanupAndExit 1 "error changing directory $tmpDir" ERROR
+ cleanupAndExit 13 "error changing directory $tmpDir" ERROR
fi
# MARK: get installed version
@@ -5381,6 +5862,8 @@ fi
# MARK: check if this is an Update and we can use updateTool
if [[ (-n $appversion && -n "$updateTool") || "$type" == "updateronly" ]]; then
printlog "appversion & updateTool"
+ updateDialog "wait" "Updating..."
+
if [[ $DEBUG -ne 1 ]]; then
if runUpdateTool; then
finishing
@@ -5407,8 +5890,28 @@ else
displaynotification "Downloading new $name" "Download in progress …"
fi
fi
- curlDownload=$(curl -v -fsL --show-error ${curlOptions} "$downloadURL" -o "$archiveName" 2>&1)
- curlDownloadStatus=$(echo $?)
+
+ if [[ $DIALOG_CMD_FILE != "" ]]; then
+ # pipe
+ pipe="$tmpDir/downloadpipe"
+ # initialise named pipe for curl output
+ initNamedPipe create $pipe
+
+ # run the pipe read in the background
+ readDownloadPipe $pipe "$DIALOG_CMD_FILE" & downloadPipePID=$!
+ printlog "listening to output of curl with pipe $pipe and command file $DIALOG_CMD_FILE on PID $downloadPipePID" DEBUG
+
+ curlDownload=$(curl -fL -# --show-error ${curlOptions} "$downloadURL" -o "$archiveName" 2>&1 | tee $pipe)
+ # because we are tee-ing the output, we want the pipe status of the first command in the chain, not the most recent one
+ curlDownloadStatus=$(echo $pipestatus[1])
+ killProcess $downloadPipePID
+
+ else
+ printlog "No Dialog connection, just download" DEBUG
+ curlDownload=$(curl -v -fsL --show-error ${curlOptions} "$downloadURL" -o "$archiveName" 2>&1)
+ curlDownloadStatus=$(echo $?)
+ fi
+
deduplicatelogs "$curlDownload"
if [[ $curlDownloadStatus -ne 0 ]]; then
#if ! curl --location --fail --silent "$downloadURL" -o "$archiveName"; then
@@ -5450,8 +5953,10 @@ if [[ $currentUser != "loginwindow" && $NOTIFY == "all" ]]; then
printlog "notifying"
if [[ $updateDetected == "YES" ]]; then
displaynotification "Updating $name" "Installation in progress …"
+ updateDialog "wait" "Updating..."
else
displaynotification "Installing $name" "Installation in progress …"
+ updateDialog "wait" "Installing..."
fi
fi
@@ -5471,7 +5976,7 @@ case $type in
zip)
installFromZIP
;;
- tbz)
+ tbz|bz2)
installFromTBZ
;;
pkgInDmg)
@@ -5488,6 +5993,8 @@ case $type in
;;
esac
+updateDialog "wait" "Finishing..."
+
# MARK: Finishing — print installed application location and version
finishing
diff --git a/Labels.txt b/Labels.txt
index e294113..c0de3d3 100644
--- a/Labels.txt
+++ b/Labels.txt
@@ -3,7 +3,10 @@
1passwordcli
4kvideodownloader
8x8
+abetterfinderrename11
abstract
+acroniscyberprotectconnect
+acroniscyberprotectconnectagent
adobebrackets
adobeconnect
adobecreativeclouddesktop
@@ -56,6 +59,7 @@ bettertouchtool
bitwarden
blender
bluejeans
+bluejeanswithaudiodriver
boxdrive
boxsync
boxtools
@@ -71,6 +75,7 @@ camtasia2019
camtasia2020
camtasia2021
canva
+carboncopycloner
chatwork
cisdem-documentreader
citrixworkspace
@@ -81,12 +86,15 @@ closeio
cloudya
clue
cluefull
+cocoapods
+coconutbattery
code42
coderunner
colourcontrastanalyser
cormorant
craftmanager
craftmanagerforsketch
+cricutdesignspace
cryptomator
cyberduck
daisydisk
@@ -110,6 +118,8 @@ drawio
drift
dropbox
duckduckgo
+duodevicehealth
+dynalist
easeusdatarecoverywizard
easyfind
egnyte
@@ -124,6 +134,7 @@ exifrenamer
fantastical
fastscripts
favro
+fellow
ferdi
figma
filezilla
@@ -136,6 +147,7 @@ firefoxesr_intl
firefoxesrpkg
firefoxpkg
firefoxpkg_intl
+flexoptixapp
flowjo
flux
flycut
@@ -145,7 +157,9 @@ fsmonitor
gimp
githubdesktop
golang
+googleadseditor
googlechrome
+googlechromeenterprise
googlechromepkg
googledrive
googledrivebackupandsync
@@ -181,6 +195,7 @@ insomnia
installomator
installomator_theile
intellijideace
+ipswupdater
istatmenus
iterm2
itsycal
@@ -200,8 +215,10 @@ jetbrainspycharmce
jetbrainsrubymine
jetbrainstoolbox
jetbrainswebstorm
+kap
karabinerelements
keepassxc
+keepingyouawake
keka
keybase
keyboardmaestro
@@ -211,6 +228,7 @@ krisp
krita
lastpass
launchbar
+lcadvancedvpnclient
lexarrecoverytool
libreoffice
linear
@@ -230,8 +248,10 @@ malwarebytes
marathon
marathon2
marathoninfinity
+masv
mattermost
menumeters
+merlinproject
microsoftautoupdate
microsoftazuredatastudio
microsoftazurestorageexplorer
@@ -255,25 +275,28 @@ microsoftskypeforbusiness
microsoftteams
microsoftvisualstudiocode
microsoftword
-microsoftyammer
mightymike
mindmanager
miro
+mmhmm
mobikinassistantforandroid
mochakeyboard
mochatelnet
mochatn3270
mochatn3812
mochatn5250
+mongodbcompass
montereyblocker
mowgliiitsycal
musescore
muzzle
nanosaur
netnewswire
+netspot
nextcloud
nomad
nomadlogin
+nordlayer
notion
nudge
nvivo
@@ -317,6 +340,7 @@ promiseutilityr
propresenter7
protonvpn
proxyman
+prune
pycharmce
pymol
qgis-pr
@@ -325,6 +349,7 @@ ramboxce
rancherdesktop
rectangle
redeye
+relatel
remotedesktopmanagerenterprise
remotedesktopmanagerfree
remotix
@@ -369,6 +394,7 @@ snagit2020
snagit2021
snagit2022
snapgeneviewer
+sonicvisualiser
sonobus
sonos
sonoss1
@@ -379,6 +405,7 @@ spotify
sqlpropostgres
sqlprostudio
steelseriesengine
+strongdm
strongsync
sublimetext
superhuman
@@ -387,6 +414,8 @@ suspiciouspackage
swiftdialog
swiftruntimeforcommandlinetools
sync
+synologyassistant
+synologydriveclient
tableaudesktop
tableaupublic
tableaureader
@@ -400,6 +429,7 @@ teamviewerqs
techsmithcapture
telegram
tembo
+tencentmeeting
textexpander
textmate
theunarchiver
@@ -413,6 +443,7 @@ torbrowser
trex
tunnelbear
tunnelblick
+typinator
typora
ultimakercura
umbrellaroamingclient
@@ -437,12 +468,12 @@ webex
webexmeetings
webexteams
wechat
+whatroute
whatsapp
-wickrme
-wickrpro
wireshark
wordservice
wwdc
+xcreds
xeroxphaser7800
xeroxworkcentre7800
xink
diff --git a/MDM/App script.sh b/MDM/App script.sh
deleted file mode 100755
index c7b4a10..0000000
--- a/MDM/App script.sh
+++ /dev/null
@@ -1,185 +0,0 @@
-#!/bin/zsh
-# Installation using Installomator
-what="brave" # enter the software to install
-
-# To be used as a script sent out from a MDM.
-# Fill the variable "what" above with a label.
-# Script will run this label.
-LOGO="appstore" # or "addigy", "microsoft", "mosyleb", "mosylem"
-######################################################################
-# Parameters for reinstall/initial install (owner root:wheel):
-# "BLOCKING_PROCESS_ACTION=quit_kill INSTALL=force IGNORE_APP_STORE_APPS=yes SYSTEMOWNER=1"
-# Parameters for Self Service installed app:
-# "BLOCKING_PROCESS_ACTION=prompt_user NOTIFY=all"
-# Parameters for security important apps, like browsers (run automaticaly every day):
-# "BLOCKING_PROCESS_ACTION=tell_user_then_kill"
-# Update of service apps (run automatically):
-# "BLOCKING_PROCESS_ACTION=quit_kill NOTIFY=silent"
-parameters="BLOCKING_PROCESS_ACTION=tell_user_then_kill NOTIFY=all"
-###############################################
-
-# Verify that Installomator has been installed
-destFile="/usr/local/Installomator/Installomator.sh"
-if [ ! -e "${destFile}" ]; then
- echo "Installomator not found here:"
- echo "${destFile}"
- echo "Exiting."
- exit 99
-fi
-
-# No sleeping
-/usr/bin/caffeinate -d -i -m -u &
-caffeinatepid=$!
-caffexit () {
- kill "$caffeinatepid"
- pkill caffeinate
- exit $1
-}
-
-cmdOutput="$(${destFile} ${what} LOGO=$LOGO $parameters LOGGING=WARN || true)"
-# Check result
-exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
-if [[ ${exitStatus} -ne 0 ]] ; then
- echo -e "Error installing ${what}. Exit code ${exitStatus}"
- #echo "$cmdOutput"
- errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
- echo "$errorOutput"
- echo "Error installing ${what}. Exit code $?"
- caffexit $?
-fi
-
-echo "[$(DATE)][LOG-END]"
-
-caffexit 0
-
-# notify behavior
-# NOTIFY=success
-# options:
-# - success notify the user on success
-# - silent no notifications
-# - all all notifications (great for Self Service installation)
-
-
-# behavior when blocking processes are found
-# BLOCKING_PROCESS_ACTION=tell_user
-# options:
-# - ignore continue even when blocking processes are found
-# - quit app will be told to quit nicely, if running
-# - quit_kill told to quit twice, then it will be killed
-# Could be great for service apps, if they do not respawn
-# - silent_fail exit script without prompt or installation
-# - prompt_user show a user dialog for each blocking process found
-# abort after three attempts to quit
-# (only if user accepts to quit the apps, otherwise
-# the update is cancelled).
-# - prompt_user_then_kill
-# show a user dialog for each blocking process found,
-# attempt to quit two times, kill the process finally
-# - prompt_user_loop
-# Like prompt-user, but clicking "Not Now", will just wait an hour,
-# and then it will ask again.
-# WARNING! It might block the MDM agent on the machine, as
-# the scripts gets stuct in waiting until the hour has passed,
-# possibly blocking for other management actions in this time.
-# - tell_user User will be showed a notification about the important update,
-# but user is only allowed to quit and continue, and then we
-# ask the app to quit.
-# - tell_user_then_kill
-# Show dialog 2 times, and if the quitting fails, the
-# blocking processes will be killed.
-# - kill kill process without prompting or giving the user a chance to save
-
-
-# logo-icon used in dialog boxes if app is blocking
-# LOGO=appstore
-# options:
-# - appstore Icon is Apple App Store (default)
-# - jamf JAMF Pro
-# - mosyleb Mosyle Business
-# - mosylem Mosyle Manager (Education)
-# - addigy Addigy
-# 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).
-
-
-# App Store apps handling
-# IGNORE_APP_STORE_APPS=no
-# options:
-# - no If installed app is from App Store (which include VPP installed apps)
-# it will not be touched, no matter it's version (default)
-# - yes Replace App Store (and VPP) version of app and handle future
-# updates using Installomator, even if latest version.
-# Shouldn’t give any problems for the user in most cases.
-# Known bad example: Slack will loose all settings.
-
-
-# install behavior
-# INSTALL=""
-# options:
-# - When not set, software will only be installed
-# if it is newer/different in version
-# - force Install even if it’s the same version
-
-
-# Re-opening of closed app
-# REOPEN="yes"
-# options:
-# - yes App wil be reopened if it was closed
-# - no App not reopened
-
-
-########################
-# Often used labels:
-########################
-
-# firefox
-# firefox_intl
-# brave
-# torbrowser
-# googlechrome
-# netnewswire
-
-# adobereaderdc
-# textmate
-
-# cyberduck
-# keka
-# theunarchiver
-
-# vlc
-# handbrake
-
-# inkscape
-
-# signal
-# telegram
-# whatsapp
-
-# hazel
-# devonthink
-
-# teamviewerqs
-# zoom
-
-# malwarebytes
-# githubdesktop
-# sublimetext
-# textmate
-# visualstudiocode
-
-# microsoftskypeforbusiness
-# microsoftteams
-# microsoftyammer
-# microsoftedgeenterprisestable
-# microsoftedgeconsumerstable
-# microsoftsharepointplugin
-# microsoftdefenderatp
-
-# googledrivefilestream
-
-# cdef
-# desktoppr
-# supportapp
-# xink
-# wwdc
diff --git a/MDM/App-install SS with swiftDialog and dockutil/App VFA SS github.sh b/MDM/App-install SS with swiftDialog and dockutil/App VFA SS github.sh
new file mode 100755
index 0000000..a235945
--- /dev/null
+++ b/MDM/App-install SS with swiftDialog and dockutil/App VFA SS github.sh
@@ -0,0 +1,346 @@
+#!/bin/sh
+
+# Installation using Installomator with Dialog showing progress (and posibility of adding to the Dock)
+# Installation of software using `valuesfromarguments` to install a custom software using Installomator through GitHub
+
+LOGO="" # "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
+
+#item="gfxcardstatus" # enter the software to install (if it has a label in future version of Installomator)
+
+# Label variables below
+
+# GitHub functions
+downloadURLFromGit() { # $1 git user name, $2 git repo name
+ gitusername=${1?:"no git user name"}
+ gitreponame=${2?:"no git repo name"}
+
+ if [[ $type == "pkgInDmg" ]]; then
+ filetype="dmg"
+ elif [[ $type == "pkgInZip" ]]; then
+ filetype="zip"
+ else
+ filetype=$type
+ fi
+
+ if [ -n "$archiveName" ]; then
+ downloadURL=https://github.com$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*$archiveName" | head -1 || true)
+ if [[ "$(echo $downloadURL | grep -ioE "https.*$archiveName" || true)" == "" ]]; then
+ #printlog "Trying GitHub API for download URL."
+ downloadURL=$(curl -sfL "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | awk -F '"' "/browser_download_url/ && /$archiveName\"/ { print \$4; exit }" || true)
+ fi
+ else
+ downloadURL=https://github.com$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1 || true)
+ if [[ "$(echo $downloadURL | grep -ioE "https.*.$filetype" || true)" == "" ]]; then
+ #printlog "Trying GitHub API for download URL."
+ downloadURL=$(curl -sfL "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | awk -F '"' "/browser_download_url/ && /$filetype\"/ { print \$4; exit }" || true)
+ fi
+ fi
+ if [ -z "$downloadURL" ]; then
+ echo "could not retrieve download URL for $gitusername/$gitreponame"
+ exit 1
+ else
+ echo "$downloadURL"
+ return 0
+ fi
+}
+versionFromGit() {
+ # credit: Søren Theilgaard (@theilgaard)
+ # $1 git user name, $2 git repo name
+ gitusername=${1?:"no git user name"}
+ gitreponame=${2?:"no git repo name"}
+
+ #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' || true)
+ appNewVersion=$(curl -sLI "https://github.com/$gitusername/$gitreponame/releases/latest" | grep -i "^location" | tr "/" "\n" | tail -1 | sed 's/[^0-9\.]//g' || true)
+ if [ -z "$appNewVersion" ]; then
+ #echo "could not retrieve version number for $gitusername/$gitreponame"
+ appNewVersion=""
+ else
+ echo "$appNewVersion"
+ return 0
+ fi
+}
+
+# Variables for label
+name="gfxCardStatus"
+type="zip"
+packageID=""
+downloadURL="$(downloadURLFromGit codykrieger gfxCardStatus)"
+appNewVersion="$(versionFromGit codykrieger gfxCardStatus)"
+versionKey=""
+expectedTeamID="LF22FTQC25"
+
+# Dialog icon
+icon=""
+# icon should be a file system path or an URL to an online PNG.
+# In Mosyle an URL can be found by copy picture address from a Custom Command icon.
+
+# dockutil variables
+addToDock="1" # with dockutil after installation (0 if not)
+appPath="/Applications/$name.app"
+
+# Other variables
+dialog_command_file="/var/tmp/dialog.log"
+dialogApp="/Library/Application Support/Dialog/Dialog.app"
+dockutil="/usr/local/bin/dockutil"
+
+installomatorOptions="BLOCKING_PROCESS_ACTION=prompt_user DIALOG_CMD_FILE=${dialog_command_file}" # Separated by space
+
+# Other installomatorOptions:
+# LOGGING=REQ
+# LOGGING=DEBUG
+# LOGGING=WARN
+# BLOCKING_PROCESS_ACTION=ignore
+# BLOCKING_PROCESS_ACTION=tell_user
+# BLOCKING_PROCESS_ACTION=tell_user_then_quit
+# BLOCKING_PROCESS_ACTION=prompt_user
+# BLOCKING_PROCESS_ACTION=prompt_user_loop
+# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
+# BLOCKING_PROCESS_ACTION=quit
+# BLOCKING_PROCESS_ACTION=kill
+# NOTIFY=all
+# NOTIFY=success
+# NOTIFY=silent
+# IGNORE_APP_STORE_APPS=yes
+# INSTALL=force
+######################################################################
+# To be used as a script sent out from a MDM.
+# Fill the variable "item" above with a label.
+# Script will run this label through Installomator.
+######################################################################
+# v. 10.0.2 : Improved icon checks and failovers
+# v. 10.0.1 : github-functions added. Improved appIcon handling. Can add the app to Dock using dockutil.
+# v. 10.0 : Integration with Dialog and Installomator v. 10
+# v. 9.2.1 : Better logging handling and installomatorOptions fix.
+######################################################################
+
+# Mark: Script
+# PATH declaration
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+echo "$(date +%F\ %T) [LOG-BEGIN] $item"
+
+dialogUpdate() {
+ # $1: dialog command
+ local dcommand="$1"
+
+ if [[ -n $dialog_command_file ]]; then
+ echo "$dcommand" >> "$dialog_command_file"
+ echo "Dialog: $dcommand"
+ fi
+}
+checkCmdOutput () {
+ # $1: cmdOutput
+ local cmdOutput="$1"
+ exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
+ if [[ ${exitStatus} -eq 0 ]] ; then
+ echo "${item} succesfully installed."
+ warnOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "warn" || true )"
+ echo "$warnOutput"
+ else
+ echo "ERROR installing ${item}. Exit code ${exitStatus}"
+ echo "$cmdOutput"
+ #errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
+ #echo "$errorOutput"
+ fi
+}
+
+# Check the currently logged in user
+currentUser=$(stat -f "%Su" /dev/console)
+if [ -z "$currentUser" ] || [ "$currentUser" = "loginwindow" ] || [ "$currentUser" = "_mbsetupuser" ] || [ "$currentUser" = "root" ]; then
+ echo "ERROR. Logged in user is $currentUser! Cannot proceed."
+ exit 97
+fi
+# Get the current user's UID for dockutil
+uid=$(id -u "$currentUser")
+# Find the home folder of the user
+userHome="$(dscl . -read /users/${currentUser} NFSHomeDirectory | awk '{print $2}')"
+
+# Verify that Installomator has been installed
+destFile="/usr/local/Installomator/Installomator.sh"
+if [ ! -e "${destFile}" ]; then
+ echo "Installomator not found here:"
+ echo "${destFile}"
+ echo "Exiting."
+ exit 99
+fi
+
+# No sleeping
+/usr/bin/caffeinate -d -i -m -u &
+caffeinatepid=$!
+caffexit () {
+ kill "$caffeinatepid"
+ pkill caffeinate
+ exit $1
+}
+
+# Mark: Installation begins
+installomatorVersion="$(${destFile} version | cut -d "." -f1 || true)"
+
+if [[ $installomatorVersion -lt 10 ]] || [[ $(sw_vers -buildVersion) < "20A" ]]; then
+ echo "Installomator should be at least version 10 to support Dialog. Installed version $installomatorVersion."
+ echo "And macOS 11 Big Sur (build 20A) is required for Dialog. Installed build $(sw_vers -buildVersion)."
+ installomatorNotify="NOTIFY=all"
+else
+ installomatorNotify="NOTIFY=silent"
+ # check for Swift Dialog
+ if [[ ! -d $dialogApp ]]; then
+ echo "Cannot find dialog at $dialogApp"
+ # Install using Installlomator
+ cmdOutput="$(${destFile} dialog LOGO=$LOGO BLOCKING_PROCESS_ACTION=ignore LOGGING=REQ NOTIFY=silent || true)"
+ checkCmdOutput $cmdOutput
+ fi
+
+ # Configure and display swiftDialog
+ itemName=$( ${destFile} ${item} RETURN_LABEL_NAME=1 LOGGING=REQ INSTALL=force | tail -1 || true )
+ if [[ "$itemName" != "#" ]]; then
+ message="Installing ${itemName}…"
+ else
+ message="Installing ${item}…"
+ fi
+ echo "$item $itemName"
+
+ #Check icon (expecting beginning with “http” to be web-link and “/” to be disk file)
+ echo "icon before check: $icon"
+ if [[ "$(echo ${icon} | grep -iE "^(http|ftp).*")" != "" ]]; then
+ echo "icon looks to be web-link"
+ if ! curl -sfL --output /dev/null -r 0-0 "${icon}" ; then
+ echo "ERROR: Cannot download link. Reset icon."
+ icon=""
+ fi
+ elif [[ "$(echo ${icon} | grep -iE "^\/.*")" != "" ]]; then
+ echo "icon looks to be a file"
+ if [[ ! -a "${icon}" ]]; then
+ echo "ERROR: Cannot find file. Reset icon."
+ icon=""
+ fi
+ else
+ echo "ERROR: Cannot figure out icon. Reset icon."
+ icon=""
+ fi
+ echo "icon after first check: $icon"
+ # If no icon defined we are trying to search for installed app icon
+ if [[ "$icon" == "" ]]; then
+ appPath=$(mdfind "kind:application AND name:$itemName" | head -1 || true)
+ appIcon=$(defaults read "${appPath}/Contents/Info.plist" CFBundleIconFile || true)
+ if [[ "$(echo "$appIcon" | grep -io ".icns")" == "" ]]; then
+ appIcon="${appIcon}.icns"
+ fi
+ icon="${appPath}/Contents/Resources/${appIcon}"
+ echo "Icon before file check: ${icon}"
+ if [ ! -f "${icon}" ]; then
+ # Using LOGO variable to show logo in swiftDialog
+ case $LOGO in
+ appstore)
+ # Apple App Store on Mac
+ if [[ $(sw_vers -buildVersion) > "19" ]]; then
+ LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ else
+ LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ fi
+ ;;
+ jamf)
+ # Jamf Pro
+ LOGO_PATH="/Library/Application Support/JAMF/Jamf.app/Contents/Resources/AppIcon.icns"
+ ;;
+ mosyleb)
+ # Mosyle Business
+ LOGO_PATH="/Applications/Self-Service.app/Contents/Resources/AppIcon.icns"
+ ;;
+ mosylem)
+ # Mosyle Manager (education)
+ LOGO_PATH="/Applications/Manager.app/Contents/Resources/AppIcon.icns"
+ ;;
+ addigy)
+ # Addigy
+ LOGO_PATH="/Library/Addigy/macmanage/MacManage.app/Contents/Resources/atom.icns"
+ ;;
+ microsoft)
+ # Microsoft Endpoint Manager (Intune)
+ LOGO_PATH="/Library/Intune/Microsoft Intune Agent.app/Contents/Resources/AppIcon.icns"
+ ;;
+ ws1)
+ # Workspace ONE (AirWatch)
+ LOGO="/Applications/Workspace ONE Intelligent Hub.app/Contents/Resources/AppIcon.icns"
+ ;;
+ esac
+ if [[ ! -a "${LOGO_PATH}" ]]; then
+ printlog "ERROR in LOGO_PATH '${LOGO_PATH}', setting Mac App Store."
+ if [[ $(/usr/bin/sw_vers -buildVersion) > "19" ]]; then
+ LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ else
+ LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ fi
+ fi
+ icon="${LOGO_PATH}"
+ fi
+ fi
+ echo "LOGO: $LOGO"
+ echo "icon: ${icon}"
+
+ # display first screen
+ open -a "$dialogApp" --args \
+ --title none \
+ --icon "$icon" \
+ --message "$message" \
+ --mini \
+ --progress 100 \
+ --position bottomright \
+ --movable \
+ --commandfile "$dialog_command_file"
+
+ # give everything a moment to catch up
+ sleep 0.1
+fi
+
+# Install software using Installomator with valuesfromarguments
+cmdOutput="$(${destFile} valuesfromarguments LOGO=$LOGO \
+ name=${name} \
+ type=${type} \
+ packageID=${packageID} \
+ downloadURL=\"$downloadURL\" \
+ appNewVersion=${appNewVersion} \
+ versionKey=${versionKey} \
+ expectedTeamID=${expectedTeamID} \
+ ${installomatorOptions} ${installomatorNotify} || true)"
+
+checkCmdOutput $cmdOutput
+
+# Mark: dockutil stuff
+if [[ $addToDock -eq 1 ]]; then
+ dialogUpdate "progresstext: Adding to Dock"
+ if [[ ! -d $dockutil ]]; then
+ echo "Cannot find dockutil at $dockutil, trying installation"
+ # Install using Installlomator
+ cmdOutput="$(${destFile} dockutil LOGO=$LOGO BLOCKING_PROCESS_ACTION=ignore LOGGING=REQ NOTIFY=silent || true)"
+ checkCmdOutput $cmdOutput
+ fi
+ echo "Adding to Dock"
+ $dockutil --add "${appPath}" "${userHome}/Library/Preferences/com.apple.dock.plist" || true
+ sleep 1
+else
+ echo "Not adding to Dock."
+fi
+
+# Mark: Ending
+if [[ $installomatorVersion -lt 10 ]]; then
+ echo "Again skipping Dialog stuff."
+else
+ # close and quit dialog
+ dialogUpdate "progress: complete"
+ dialogUpdate "progresstext: Done"
+
+ # pause a moment
+ sleep 0.5
+
+ dialogUpdate "quit:"
+
+ # let everything catch up
+ sleep 0.5
+
+ # just to be safe
+ #killall "Dialog" 2>/dev/null || true
+fi
+
+echo "[$(DATE)][LOG-END]"
+
+caffexit $exitStatus
diff --git a/MDM/App-install SS with swiftDialog and dockutil/App VFA SS.sh b/MDM/App-install SS with swiftDialog and dockutil/App VFA SS.sh
new file mode 100755
index 0000000..2089f9b
--- /dev/null
+++ b/MDM/App-install SS with swiftDialog and dockutil/App VFA SS.sh
@@ -0,0 +1,293 @@
+#!/bin/sh
+
+# Installation using Installomator with Dialog showing progress (and posibility of adding to the Dock)
+# Installation of software using `valuesfromarguments` to install a custom software using Installomator
+
+LOGO="" # "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
+
+#item="" # enter the software to install (if it has a label in future version of Installomator)
+
+# Variables for label
+name="ClickShare"
+type="appInDmgInZip"
+packageID=""
+downloadURL="https://www.barco.com$( curl -fs "https://www.barco.com/en/clickshare/app" | grep -A6 -i "macos" | grep -i "FileNumber" | tr '"' "\n" | grep -i "FileNumber" )"
+appNewVersion="$(eval "$( echo $downloadURL | sed -E 's/.*(MajorVersion.*BuildVersion=[0-9]*).*/\1/' | sed 's/&//g' )" ; ((MajorVersion++)) ; ((MajorVersion--)); ((MinorVersion++)) ; ((MinorVersion--)); ((PatchVersion++)) ; ((PatchVersion--)); ((BuildVersion++)) ; ((BuildVersion--)); echo "${MajorVersion}.${MinorVersion}.${PatchVersion}-b${BuildVersion}")"
+versionKey=""
+expectedTeamID="P6CDJZR997"
+
+# Dialog icon
+icon=""
+# icon should be a file system path or an URL to an online PNG.
+# In Mosyle an URL can be found by copy picture address from a Custom Command icon.
+
+# dockutil variables
+addToDock="1" # with dockutil after installation (0 if not)
+appPath="/Applications/$name.app"
+
+# Other variables
+dialog_command_file="/var/tmp/dialog.log"
+dialogApp="/Library/Application Support/Dialog/Dialog.app"
+dockutil="/usr/local/bin/dockutil"
+
+installomatorOptions="BLOCKING_PROCESS_ACTION=prompt_user DIALOG_CMD_FILE=${dialog_command_file}" # Separated by space
+
+# Other installomatorOptions:
+# LOGGING=REQ
+# LOGGING=DEBUG
+# LOGGING=WARN
+# BLOCKING_PROCESS_ACTION=ignore
+# BLOCKING_PROCESS_ACTION=tell_user
+# BLOCKING_PROCESS_ACTION=tell_user_then_quit
+# BLOCKING_PROCESS_ACTION=prompt_user
+# BLOCKING_PROCESS_ACTION=prompt_user_loop
+# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
+# BLOCKING_PROCESS_ACTION=quit
+# BLOCKING_PROCESS_ACTION=kill
+# NOTIFY=all
+# NOTIFY=success
+# NOTIFY=silent
+# IGNORE_APP_STORE_APPS=yes
+# INSTALL=force
+######################################################################
+# To be used as a script sent out from a MDM.
+# Fill the variable "item" above with a label.
+# Script will run this label through Installomator.
+######################################################################
+# v. 10.0.2 : Improved icon checks and failovers
+# v. 10.0.1 : Improved appIcon handling. Can add the app to Dock using dockutil
+# v. 10.0 : Integration with Dialog and Installomator v. 10
+# v. 9.2.1 : Better logging handling and installomatorOptions fix.
+######################################################################
+
+# Mark: Script
+# PATH declaration
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+echo "$(date +%F\ %T) [LOG-BEGIN] $item"
+
+dialogUpdate() {
+ # $1: dialog command
+ local dcommand="$1"
+
+ if [[ -n $dialog_command_file ]]; then
+ echo "$dcommand" >> "$dialog_command_file"
+ echo "Dialog: $dcommand"
+ fi
+}
+checkCmdOutput () {
+ # $1: cmdOutput
+ local cmdOutput="$1"
+ exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
+ if [[ ${exitStatus} -eq 0 ]] ; then
+ echo "${item} succesfully installed."
+ warnOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "warn" || true )"
+ echo "$warnOutput"
+ else
+ echo "ERROR installing ${item}. Exit code ${exitStatus}"
+ echo "$cmdOutput"
+ #errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
+ #echo "$errorOutput"
+ fi
+}
+
+# Check the currently logged in user
+currentUser=$(stat -f "%Su" /dev/console)
+if [ -z "$currentUser" ] || [ "$currentUser" = "loginwindow" ] || [ "$currentUser" = "_mbsetupuser" ] || [ "$currentUser" = "root" ]; then
+ echo "ERROR. Logged in user is $currentUser! Cannot proceed."
+ exit 97
+fi
+# Get the current user's UID for dockutil
+uid=$(id -u "$currentUser")
+# Find the home folder of the user
+userHome="$(dscl . -read /users/${currentUser} NFSHomeDirectory | awk '{print $2}')"
+
+# Verify that Installomator has been installed
+destFile="/usr/local/Installomator/Installomator.sh"
+if [ ! -e "${destFile}" ]; then
+ echo "Installomator not found here:"
+ echo "${destFile}"
+ echo "Exiting."
+ exit 99
+fi
+
+# No sleeping
+/usr/bin/caffeinate -d -i -m -u &
+caffeinatepid=$!
+caffexit () {
+ kill "$caffeinatepid"
+ pkill caffeinate
+ exit $1
+}
+
+# Mark: Installation begins
+installomatorVersion="$(${destFile} version | cut -d "." -f1 || true)"
+
+if [[ $installomatorVersion -lt 10 ]] || [[ $(sw_vers -buildVersion) < "20A" ]]; then
+ echo "Installomator should be at least version 10 to support Dialog. Installed version $installomatorVersion."
+ echo "And macOS 11 Big Sur (build 20A) is required for Dialog. Installed build $(sw_vers -buildVersion)."
+ installomatorNotify="NOTIFY=all"
+else
+ installomatorNotify="NOTIFY=silent"
+ # check for Swift Dialog
+ if [[ ! -d $dialogApp ]]; then
+ echo "Cannot find dialog at $dialogApp"
+ # Install using Installlomator
+ cmdOutput="$(${destFile} dialog LOGO=$LOGO BLOCKING_PROCESS_ACTION=ignore LOGGING=REQ NOTIFY=silent || true)"
+ checkCmdOutput $cmdOutput
+ fi
+
+ # Configure and display swiftDialog
+ itemName=$( ${destFile} ${item} RETURN_LABEL_NAME=1 LOGGING=REQ INSTALL=force | tail -1 || true )
+ if [[ "$itemName" != "#" ]]; then
+ message="Installing ${itemName}…"
+ else
+ message="Installing ${item}…"
+ fi
+ echo "$item $itemName"
+
+ #Check icon (expecting beginning with “http” to be web-link and “/” to be disk file)
+ echo "icon before check: $icon"
+ if [[ "$(echo ${icon} | grep -iE "^(http|ftp).*")" != "" ]]; then
+ echo "icon looks to be web-link"
+ if ! curl -sfL --output /dev/null -r 0-0 "${icon}" ; then
+ echo "ERROR: Cannot download link. Reset icon."
+ icon=""
+ fi
+ elif [[ "$(echo ${icon} | grep -iE "^\/.*")" != "" ]]; then
+ echo "icon looks to be a file"
+ if [[ ! -a "${icon}" ]]; then
+ echo "ERROR: Cannot find file. Reset icon."
+ icon=""
+ fi
+ else
+ echo "ERROR: Cannot figure out icon. Reset icon."
+ icon=""
+ fi
+ echo "icon after first check: $icon"
+ # If no icon defined we are trying to search for installed app icon
+ if [[ "$icon" == "" ]]; then
+ appPath=$(mdfind "kind:application AND name:$itemName" | head -1 || true)
+ appIcon=$(defaults read "${appPath}/Contents/Info.plist" CFBundleIconFile || true)
+ if [[ "$(echo "$appIcon" | grep -io ".icns")" == "" ]]; then
+ appIcon="${appIcon}.icns"
+ fi
+ icon="${appPath}/Contents/Resources/${appIcon}"
+ echo "Icon before file check: ${icon}"
+ if [ ! -f "${icon}" ]; then
+ # Using LOGO variable to show logo in swiftDialog
+ case $LOGO in
+ appstore)
+ # Apple App Store on Mac
+ if [[ $(sw_vers -buildVersion) > "19" ]]; then
+ LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ else
+ LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ fi
+ ;;
+ jamf)
+ # Jamf Pro
+ LOGO_PATH="/Library/Application Support/JAMF/Jamf.app/Contents/Resources/AppIcon.icns"
+ ;;
+ mosyleb)
+ # Mosyle Business
+ LOGO_PATH="/Applications/Self-Service.app/Contents/Resources/AppIcon.icns"
+ ;;
+ mosylem)
+ # Mosyle Manager (education)
+ LOGO_PATH="/Applications/Manager.app/Contents/Resources/AppIcon.icns"
+ ;;
+ addigy)
+ # Addigy
+ LOGO_PATH="/Library/Addigy/macmanage/MacManage.app/Contents/Resources/atom.icns"
+ ;;
+ microsoft)
+ # Microsoft Endpoint Manager (Intune)
+ LOGO_PATH="/Library/Intune/Microsoft Intune Agent.app/Contents/Resources/AppIcon.icns"
+ ;;
+ ws1)
+ # Workspace ONE (AirWatch)
+ LOGO="/Applications/Workspace ONE Intelligent Hub.app/Contents/Resources/AppIcon.icns"
+ ;;
+ esac
+ if [[ ! -a "${LOGO_PATH}" ]]; then
+ printlog "ERROR in LOGO_PATH '${LOGO_PATH}', setting Mac App Store."
+ if [[ $(/usr/bin/sw_vers -buildVersion) > "19" ]]; then
+ LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ else
+ LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ fi
+ fi
+ icon="${LOGO_PATH}"
+ fi
+ fi
+ echo "LOGO: $LOGO"
+ echo "icon: ${icon}"
+
+ # display first screen
+ open -a "$dialogApp" --args \
+ --title none \
+ --icon "$icon" \
+ --message "$message" \
+ --mini \
+ --progress 100 \
+ --position bottomright \
+ --movable \
+ --commandfile "$dialog_command_file"
+
+ # give everything a moment to catch up
+ sleep 0.1
+fi
+
+# Install software using Installomator with valuesfromarguments
+cmdOutput="$(${destFile} valuesfromarguments LOGO=$LOGO \
+ name=${name} \
+ type=${type} \
+ packageID=${packageID} \
+ downloadURL=\"$downloadURL\" \
+ appNewVersion=${appNewVersion} \
+ versionKey=${versionKey} \
+ expectedTeamID=${expectedTeamID} \
+ ${installomatorOptions} ${installomatorNotify} || true)"
+
+checkCmdOutput $cmdOutput
+
+# Mark: dockutil stuff
+if [[ $addToDock -eq 1 ]]; then
+ dialogUpdate "progresstext: Adding to Dock"
+ if [[ ! -d $dockutil ]]; then
+ echo "Cannot find dockutil at $dockutil, trying installation"
+ # Install using Installlomator
+ cmdOutput="$(${destFile} dockutil LOGO=$LOGO BLOCKING_PROCESS_ACTION=ignore LOGGING=REQ NOTIFY=silent || true)"
+ checkCmdOutput $cmdOutput
+ fi
+ echo "Adding to Dock"
+ $dockutil --add "${appPath}" "${userHome}/Library/Preferences/com.apple.dock.plist" || true
+ sleep 1
+else
+ echo "Not adding to Dock."
+fi
+
+# Mark: Ending
+if [[ $installomatorVersion -lt 10 ]]; then
+ echo "Again skipping Dialog stuff."
+else
+ # close and quit dialog
+ dialogUpdate "progress: complete"
+ dialogUpdate "progresstext: Done"
+
+ # pause a moment
+ sleep 0.5
+
+ dialogUpdate "quit:"
+
+ # let everything catch up
+ sleep 0.5
+
+ # just to be safe
+ #killall "Dialog" 2>/dev/null || true
+fi
+
+echo "[$(DATE)][LOG-END]"
+
+caffexit $exitStatus
diff --git a/MDM/App-install SS with swiftDialog and dockutil/App browser-security SS.sh b/MDM/App-install SS with swiftDialog and dockutil/App browser-security SS.sh
new file mode 100755
index 0000000..8e59aba
--- /dev/null
+++ b/MDM/App-install SS with swiftDialog and dockutil/App browser-security SS.sh
@@ -0,0 +1,275 @@
+#!/bin/sh
+
+# Installation using Installomator with Dialog showing progress (and posibility of adding to the Dock)
+
+LOGO="" # "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
+
+item="" # enter the software to install
+# Examples: brave, duckduckgo, firefoxpkg, googlechromepkg, microsoftedge, opera
+
+# Dialog icon
+icon=""
+# icon should be a file system path or an URL to an online PNG.
+# In Mosyle an URL can be found by copy picture address from a Custom Command icon.
+
+# dockutil variables
+addToDock="1" # with dockutil after installation (0 if not)
+appPath="/Applications/Firefox.app"
+
+# Other variables
+dialog_command_file="/var/tmp/dialog.log"
+dialogApp="/Library/Application Support/Dialog/Dialog.app"
+dockutil="/usr/local/bin/dockutil"
+
+installomatorOptions="BLOCKING_PROCESS_ACTION=tell_user_then_quit DIALOG_CMD_FILE=${dialog_command_file}" # Separated by space
+
+# Other installomatorOptions:
+# LOGGING=REQ
+# LOGGING=DEBUG
+# LOGGING=WARN
+# BLOCKING_PROCESS_ACTION=ignore
+# BLOCKING_PROCESS_ACTION=tell_user
+# BLOCKING_PROCESS_ACTION=tell_user_then_quit
+# BLOCKING_PROCESS_ACTION=prompt_user
+# BLOCKING_PROCESS_ACTION=prompt_user_loop
+# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
+# BLOCKING_PROCESS_ACTION=quit
+# BLOCKING_PROCESS_ACTION=kill
+# NOTIFY=all
+# NOTIFY=success
+# NOTIFY=silent
+# IGNORE_APP_STORE_APPS=yes
+# INSTALL=force
+######################################################################
+# To be used as a script sent out from a MDM.
+# Fill the variable "item" above with a label.
+# Script will run this label through Installomator.
+######################################################################
+# v. 10.0.2 : Improved icon checks and failovers
+# v. 10.0.1 : Improved appIcon handling. Can add the app to Dock using dockutil
+# v. 10.0 : Integration with Dialog and Installomator v. 10
+# v. 9.2.1 : Better logging handling and installomatorOptions fix.
+######################################################################
+
+# Mark: Script
+# PATH declaration
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+echo "$(date +%F\ %T) [LOG-BEGIN] $item"
+
+dialogUpdate() {
+ # $1: dialog command
+ local dcommand="$1"
+
+ if [[ -n $dialog_command_file ]]; then
+ echo "$dcommand" >> "$dialog_command_file"
+ echo "Dialog: $dcommand"
+ fi
+}
+checkCmdOutput () {
+ # $1: cmdOutput
+ local cmdOutput="$1"
+ exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
+ if [[ ${exitStatus} -eq 0 ]] ; then
+ echo "${item} succesfully installed."
+ warnOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "warn" || true )"
+ echo "$warnOutput"
+ else
+ echo "ERROR installing ${item}. Exit code ${exitStatus}"
+ echo "$cmdOutput"
+ #errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
+ #echo "$errorOutput"
+ fi
+}
+
+# Check the currently logged in user
+currentUser=$(stat -f "%Su" /dev/console)
+if [ -z "$currentUser" ] || [ "$currentUser" = "loginwindow" ] || [ "$currentUser" = "_mbsetupuser" ] || [ "$currentUser" = "root" ]; then
+ echo "ERROR. Logged in user is $currentUser! Cannot proceed."
+ exit 97
+fi
+# Get the current user's UID for dockutil
+uid=$(id -u "$currentUser")
+# Find the home folder of the user
+userHome="$(dscl . -read /users/${currentUser} NFSHomeDirectory | awk '{print $2}')"
+
+# Verify that Installomator has been installed
+destFile="/usr/local/Installomator/Installomator.sh"
+if [ ! -e "${destFile}" ]; then
+ echo "Installomator not found here:"
+ echo "${destFile}"
+ echo "Exiting."
+ exit 99
+fi
+
+# No sleeping
+/usr/bin/caffeinate -d -i -m -u &
+caffeinatepid=$!
+caffexit () {
+ kill "$caffeinatepid"
+ pkill caffeinate
+ exit $1
+}
+
+# Mark: Installation begins
+installomatorVersion="$(${destFile} version | cut -d "." -f1 || true)"
+
+if [[ $installomatorVersion -lt 10 ]] || [[ $(sw_vers -buildVersion) < "20A" ]]; then
+ echo "Installomator should be at least version 10 to support Dialog. Installed version $installomatorVersion."
+ echo "And macOS 11 Big Sur (build 20A) is required for Dialog. Installed build $(sw_vers -buildVersion)."
+ installomatorNotify="NOTIFY=all"
+else
+ installomatorNotify="NOTIFY=silent"
+ # check for Swift Dialog
+ if [[ ! -d $dialogApp ]]; then
+ echo "Cannot find dialog at $dialogApp"
+ # Install using Installlomator
+ cmdOutput="$(${destFile} dialog LOGO=$LOGO BLOCKING_PROCESS_ACTION=ignore LOGGING=REQ NOTIFY=silent || true)"
+ checkCmdOutput $cmdOutput
+ fi
+
+ # Configure and display swiftDialog
+ itemName=$( ${destFile} ${item} RETURN_LABEL_NAME=1 LOGGING=REQ INSTALL=force | tail -1 || true )
+ if [[ "$itemName" != "#" ]]; then
+ message="Installing ${itemName}…"
+ else
+ message="Installing ${item}…"
+ fi
+ echo "$item $itemName"
+
+ #Check icon (expecting beginning with “http” to be web-link and “/” to be disk file)
+ echo "icon before check: $icon"
+ if [[ "$(echo ${icon} | grep -iE "^(http|ftp).*")" != "" ]]; then
+ echo "icon looks to be web-link"
+ if ! curl -sfL --output /dev/null -r 0-0 "${icon}" ; then
+ echo "ERROR: Cannot download link. Reset icon."
+ icon=""
+ fi
+ elif [[ "$(echo ${icon} | grep -iE "^\/.*")" != "" ]]; then
+ echo "icon looks to be a file"
+ if [[ ! -a "${icon}" ]]; then
+ echo "ERROR: Cannot find file. Reset icon."
+ icon=""
+ fi
+ else
+ echo "ERROR: Cannot figure out icon. Reset icon."
+ icon=""
+ fi
+ echo "icon after first check: $icon"
+ # If no icon defined we are trying to search for installed app icon
+ if [[ "$icon" == "" ]]; then
+ appPath=$(mdfind "kind:application AND name:$itemName" | head -1 || true)
+ appIcon=$(defaults read "${appPath}/Contents/Info.plist" CFBundleIconFile || true)
+ if [[ "$(echo "$appIcon" | grep -io ".icns")" == "" ]]; then
+ appIcon="${appIcon}.icns"
+ fi
+ icon="${appPath}/Contents/Resources/${appIcon}"
+ echo "Icon before file check: ${icon}"
+ if [ ! -f "${icon}" ]; then
+ # Using LOGO variable to show logo in swiftDialog
+ case $LOGO in
+ appstore)
+ # Apple App Store on Mac
+ if [[ $(sw_vers -buildVersion) > "19" ]]; then
+ LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ else
+ LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ fi
+ ;;
+ jamf)
+ # Jamf Pro
+ LOGO_PATH="/Library/Application Support/JAMF/Jamf.app/Contents/Resources/AppIcon.icns"
+ ;;
+ mosyleb)
+ # Mosyle Business
+ LOGO_PATH="/Applications/Self-Service.app/Contents/Resources/AppIcon.icns"
+ ;;
+ mosylem)
+ # Mosyle Manager (education)
+ LOGO_PATH="/Applications/Manager.app/Contents/Resources/AppIcon.icns"
+ ;;
+ addigy)
+ # Addigy
+ LOGO_PATH="/Library/Addigy/macmanage/MacManage.app/Contents/Resources/atom.icns"
+ ;;
+ microsoft)
+ # Microsoft Endpoint Manager (Intune)
+ LOGO_PATH="/Library/Intune/Microsoft Intune Agent.app/Contents/Resources/AppIcon.icns"
+ ;;
+ ws1)
+ # Workspace ONE (AirWatch)
+ LOGO="/Applications/Workspace ONE Intelligent Hub.app/Contents/Resources/AppIcon.icns"
+ ;;
+ esac
+ if [[ ! -a "${LOGO_PATH}" ]]; then
+ printlog "ERROR in LOGO_PATH '${LOGO_PATH}', setting Mac App Store."
+ if [[ $(/usr/bin/sw_vers -buildVersion) > "19" ]]; then
+ LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ else
+ LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ fi
+ fi
+ icon="${LOGO_PATH}"
+ fi
+ fi
+ echo "LOGO: $LOGO"
+ echo "icon: ${icon}"
+
+ # display first screen
+ open -a "$dialogApp" --args \
+ --title none \
+ --icon "$icon" \
+ --message "$message" \
+ --mini \
+ --progress 100 \
+ --position bottomright \
+ --movable \
+ --commandfile "$dialog_command_file"
+
+ # give everything a moment to catch up
+ sleep 0.1
+fi
+
+# Install software using Installomator
+cmdOutput="$(${destFile} ${item} LOGO=$LOGO ${installomatorOptions} ${installomatorNotify} || true)"
+checkCmdOutput $cmdOutput
+
+# Mark: dockutil stuff
+if [[ $addToDock -eq 1 ]]; then
+ dialogUpdate "progresstext: Adding to Dock"
+ if [[ ! -d $dockutil ]]; then
+ echo "Cannot find dockutil at $dockutil, trying installation"
+ # Install using Installlomator
+ cmdOutput="$(${destFile} dockutil LOGO=$LOGO BLOCKING_PROCESS_ACTION=ignore LOGGING=REQ NOTIFY=silent || true)"
+ checkCmdOutput $cmdOutput
+ fi
+ echo "Adding to Dock"
+ $dockutil --add "${appPath}" "${userHome}/Library/Preferences/com.apple.dock.plist" || true
+ sleep 1
+else
+ echo "Not adding to Dock."
+fi
+
+# Mark: Ending
+if [[ $installomatorVersion -lt 10 ]]; then
+ echo "Again skipping Dialog stuff."
+else
+ # close and quit dialog
+ dialogUpdate "progress: complete"
+ dialogUpdate "progresstext: Done"
+
+ # pause a moment
+ sleep 0.5
+
+ dialogUpdate "quit:"
+
+ # let everything catch up
+ sleep 0.5
+
+ # just to be safe
+ #killall "Dialog" 2>/dev/null || true
+fi
+
+echo "[$(DATE)][LOG-END]"
+
+caffexit $exitStatus
diff --git a/MDM/App-install SS with swiftDialog and dockutil/App normal SS multi-app.sh b/MDM/App-install SS with swiftDialog and dockutil/App normal SS multi-app.sh
new file mode 100644
index 0000000..0cc2af9
--- /dev/null
+++ b/MDM/App-install SS with swiftDialog and dockutil/App normal SS multi-app.sh
@@ -0,0 +1,278 @@
+#!/bin/sh
+
+# Installation using Installomator with Dialog showing progress (and posibility of adding to the Dock)
+
+LOGO="" # "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
+
+item="microsoftoffice365" # enter the software to install
+# Examples: microsoftofficebusinesspro, microsoftoffice365
+
+# Dialog icon
+icon=""
+# icon should be a file system path or an URL to an online PNG.
+# In Mosyle an URL can be found by copy picture address from a Custom Command icon.
+
+# dockutil variables
+addToDock="1" # with dockutil after installation (0 if not)
+appPaths=("/Applications/Microsoft Outlook.app" "/Applications/Microsoft Word.app" "/Applications/Microsoft Excel.app" "/Applications/Microsoft PowerPoint.app" "/Applications/Microsoft OneNote.app")
+
+# Other variables
+dialog_command_file="/var/tmp/dialog.log"
+dialogApp="/Library/Application Support/Dialog/Dialog.app"
+dockutil="/usr/local/bin/dockutil"
+
+installomatorOptions="BLOCKING_PROCESS_ACTION=prompt_user DIALOG_CMD_FILE=${dialog_command_file}" # Separated by space
+
+# Other installomatorOptions:
+# LOGGING=REQ
+# LOGGING=DEBUG
+# LOGGING=WARN
+# BLOCKING_PROCESS_ACTION=ignore
+# BLOCKING_PROCESS_ACTION=tell_user
+# BLOCKING_PROCESS_ACTION=tell_user_then_quit
+# BLOCKING_PROCESS_ACTION=prompt_user
+# BLOCKING_PROCESS_ACTION=prompt_user_loop
+# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
+# BLOCKING_PROCESS_ACTION=quit
+# BLOCKING_PROCESS_ACTION=kill
+# NOTIFY=all
+# NOTIFY=success
+# NOTIFY=silent
+# IGNORE_APP_STORE_APPS=yes
+# INSTALL=force
+######################################################################
+# To be used as a script sent out from a MDM.
+# Fill the variable "item" above with a label.
+# Script will run this label through Installomator.
+######################################################################
+# v. 10.0.2 : Improved icon checks and failovers
+# v. 10.0.1 : Improved appIcon handling. Can add the app to Dock using dockutil
+# v. 10.0 : Integration with Dialog and Installomator v. 10
+# v. 9.2.1 : Better logging handling and installomatorOptions fix.
+######################################################################
+
+# Mark: Script
+# PATH declaration
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+echo "$(date +%F\ %T) [LOG-BEGIN] $item"
+
+dialogUpdate() {
+ # $1: dialog command
+ local dcommand="$1"
+
+ if [[ -n $dialog_command_file ]]; then
+ echo "$dcommand" >> "$dialog_command_file"
+ echo "Dialog: $dcommand"
+ fi
+}
+checkCmdOutput () {
+ # $1: cmdOutput
+ local cmdOutput="$1"
+ exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
+ if [[ ${exitStatus} -eq 0 ]] ; then
+ echo "${item} succesfully installed."
+ warnOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "warn" || true )"
+ echo "$warnOutput"
+ else
+ echo "ERROR installing ${item}. Exit code ${exitStatus}"
+ echo "$cmdOutput"
+ #errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
+ #echo "$errorOutput"
+ fi
+}
+
+# Check the currently logged in user
+currentUser=$(stat -f "%Su" /dev/console)
+if [ -z "$currentUser" ] || [ "$currentUser" = "loginwindow" ] || [ "$currentUser" = "_mbsetupuser" ] || [ "$currentUser" = "root" ]; then
+ echo "ERROR. Logged in user is $currentUser! Cannot proceed."
+ exit 97
+fi
+# Get the current user's UID for dockutil
+uid=$(id -u "$currentUser")
+# Find the home folder of the user
+userHome="$(dscl . -read /users/${currentUser} NFSHomeDirectory | awk '{print $2}')"
+
+# Verify that Installomator has been installed
+destFile="/usr/local/Installomator/Installomator.sh"
+if [ ! -e "${destFile}" ]; then
+ echo "Installomator not found here:"
+ echo "${destFile}"
+ echo "Exiting."
+ exit 99
+fi
+
+# No sleeping
+/usr/bin/caffeinate -d -i -m -u &
+caffeinatepid=$!
+caffexit () {
+ kill "$caffeinatepid"
+ pkill caffeinate
+ exit $1
+}
+
+# Mark: Installation begins
+installomatorVersion="$(${destFile} version | cut -d "." -f1 || true)"
+
+if [[ $installomatorVersion -lt 10 ]] || [[ $(sw_vers -buildVersion) < "20A" ]]; then
+ echo "Installomator should be at least version 10 to support Dialog. Installed version $installomatorVersion."
+ echo "And macOS 11 Big Sur (build 20A) is required for Dialog. Installed build $(sw_vers -buildVersion)."
+ installomatorNotify="NOTIFY=all"
+else
+ installomatorNotify="NOTIFY=silent"
+ # check for Swift Dialog
+ if [[ ! -d $dialogApp ]]; then
+ echo "Cannot find dialog at $dialogApp"
+ # Install using Installlomator
+ cmdOutput="$(${destFile} dialog LOGO=$LOGO BLOCKING_PROCESS_ACTION=ignore LOGGING=REQ NOTIFY=silent || true)"
+ checkCmdOutput $cmdOutput
+ fi
+
+ # Configure and display swiftDialog
+ itemName=$( ${destFile} ${item} RETURN_LABEL_NAME=1 LOGGING=REQ INSTALL=force | tail -1 || true )
+ if [[ "$itemName" != "#" ]]; then
+ message="Installing ${itemName}…"
+ else
+ message="Installing ${item}…"
+ fi
+ echo "$item $itemName"
+
+ #Check icon (expecting beginning with “http” to be web-link and “/” to be disk file)
+ echo "icon before check: $icon"
+ if [[ "$(echo ${icon} | grep -iE "^(http|ftp).*")" != "" ]]; then
+ echo "icon looks to be web-link"
+ if ! curl -sfL --output /dev/null -r 0-0 "${icon}" ; then
+ echo "ERROR: Cannot download link. Reset icon."
+ icon=""
+ fi
+ elif [[ "$(echo ${icon} | grep -iE "^\/.*")" != "" ]]; then
+ echo "icon looks to be a file"
+ if [[ ! -a "${icon}" ]]; then
+ echo "ERROR: Cannot find file. Reset icon."
+ icon=""
+ fi
+ else
+ echo "ERROR: Cannot figure out icon. Reset icon."
+ icon=""
+ fi
+ echo "icon after first check: $icon"
+ # If no icon defined we are trying to search for installed app icon
+ if [[ "$icon" == "" ]]; then
+ appPath=$(mdfind "kind:application AND name:$itemName" | head -1 || true)
+ appIcon=$(defaults read "${appPath}/Contents/Info.plist" CFBundleIconFile || true)
+ if [[ "$(echo "$appIcon" | grep -io ".icns")" == "" ]]; then
+ appIcon="${appIcon}.icns"
+ fi
+ icon="${appPath}/Contents/Resources/${appIcon}"
+ echo "Icon before file check: ${icon}"
+ if [ ! -f "${icon}" ]; then
+ # Using LOGO variable to show logo in swiftDialog
+ case $LOGO in
+ appstore)
+ # Apple App Store on Mac
+ if [[ $(sw_vers -buildVersion) > "19" ]]; then
+ LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ else
+ LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ fi
+ ;;
+ jamf)
+ # Jamf Pro
+ LOGO_PATH="/Library/Application Support/JAMF/Jamf.app/Contents/Resources/AppIcon.icns"
+ ;;
+ mosyleb)
+ # Mosyle Business
+ LOGO_PATH="/Applications/Self-Service.app/Contents/Resources/AppIcon.icns"
+ ;;
+ mosylem)
+ # Mosyle Manager (education)
+ LOGO_PATH="/Applications/Manager.app/Contents/Resources/AppIcon.icns"
+ ;;
+ addigy)
+ # Addigy
+ LOGO_PATH="/Library/Addigy/macmanage/MacManage.app/Contents/Resources/atom.icns"
+ ;;
+ microsoft)
+ # Microsoft Endpoint Manager (Intune)
+ LOGO_PATH="/Library/Intune/Microsoft Intune Agent.app/Contents/Resources/AppIcon.icns"
+ ;;
+ ws1)
+ # Workspace ONE (AirWatch)
+ LOGO="/Applications/Workspace ONE Intelligent Hub.app/Contents/Resources/AppIcon.icns"
+ ;;
+ esac
+ if [[ ! -a "${LOGO_PATH}" ]]; then
+ printlog "ERROR in LOGO_PATH '${LOGO_PATH}', setting Mac App Store."
+ if [[ $(/usr/bin/sw_vers -buildVersion) > "19" ]]; then
+ LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ else
+ LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ fi
+ fi
+ icon="${LOGO_PATH}"
+ fi
+ fi
+ echo "LOGO: $LOGO"
+ echo "icon: ${icon}"
+
+ # display first screen
+ open -a "$dialogApp" --args \
+ --title none \
+ --icon "$icon" \
+ --message "$message" \
+ --mini \
+ --progress 100 \
+ --position bottomright \
+ --movable \
+ --commandfile "$dialog_command_file"
+
+ # give everything a moment to catch up
+ sleep 0.1
+fi
+
+# Install software using Installomator
+cmdOutput="$(${destFile} ${item} LOGO=$LOGO ${installomatorOptions} ${installomatorNotify} || true)"
+checkCmdOutput $cmdOutput
+
+# Mark: dockutil stuff
+if [[ $addToDock -eq 1 ]]; then
+ dialogUpdate "progresstext: Adding to Dock"
+ if [[ ! -d $dockutil ]]; then
+ echo "Cannot find dockutil at $dockutil, trying installation"
+ # Install using Installlomator
+ cmdOutput="$(${destFile} dockutil LOGO=$LOGO BLOCKING_PROCESS_ACTION=ignore LOGGING=REQ NOTIFY=silent || true)"
+ checkCmdOutput $cmdOutput
+ fi
+ echo "Adding to Dock"
+ for appPath in "${appPaths[@]}"; do
+ $dockutil --add "${appPath}" "${userHome}/Library/Preferences/com.apple.dock.plist" --no-restart || true
+ done
+ $dockutil --add "/AppThatDoesNotExistAnywhereOnDiskButMakingDockutilRestartTheDock" "${userHome}/Library/Preferences/com.apple.dock.plist" || true
+ sleep 1
+else
+ echo "Not adding to Dock."
+fi
+
+# Mark: Ending
+if [[ $installomatorVersion -lt 10 ]]; then
+ echo "Again skipping Dialog stuff."
+else
+ # close and quit dialog
+ dialogUpdate "progress: complete"
+ dialogUpdate "progresstext: Done"
+
+ # pause a moment
+ sleep 0.5
+
+ dialogUpdate "quit:"
+
+ # let everything catch up
+ sleep 0.5
+
+ # just to be safe
+ #killall "Dialog" 2>/dev/null || true
+fi
+
+echo "[$(DATE)][LOG-END]"
+
+caffexit $exitStatus
diff --git a/MDM/App-install SS with swiftDialog and dockutil/App normal SS.sh b/MDM/App-install SS with swiftDialog and dockutil/App normal SS.sh
new file mode 100644
index 0000000..77f7add
--- /dev/null
+++ b/MDM/App-install SS with swiftDialog and dockutil/App normal SS.sh
@@ -0,0 +1,272 @@
+#!/bin/sh
+
+# Installation using Installomator with Dialog showing progress (and posibility of adding to the Dock)
+
+LOGO="" # "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
+
+item="" # enter the software to install
+# Examples: adobecreativeclouddesktop, canva, cyberduck, handbrake, inkscape, textmate, vlc
+
+# Dialog icon
+icon=""
+# icon should be a file system path or an URL to an online PNG, so beginning with either “/” or “http”.
+# In Mosyle an URL can be found by copy picture address from a Custom Command icon.
+
+# dockutil variables
+addToDock="0" # with dockutil after installation (0 if not)
+appPath="/Applications/Cyberduck.app"
+
+# Other variables
+dialog_command_file="/var/tmp/dialog.log"
+dialogApp="/Library/Application Support/Dialog/Dialog.app"
+dockutil="/usr/local/bin/dockutil"
+
+installomatorOptions="BLOCKING_PROCESS_ACTION=prompt_user DIALOG_CMD_FILE=${dialog_command_file}" # Separated by space
+
+# Other installomatorOptions:
+# LOGGING=REQ
+# LOGGING=DEBUG
+# LOGGING=WARN
+# BLOCKING_PROCESS_ACTION=ignore
+# BLOCKING_PROCESS_ACTION=tell_user
+# BLOCKING_PROCESS_ACTION=tell_user_then_quit
+# BLOCKING_PROCESS_ACTION=prompt_user
+# BLOCKING_PROCESS_ACTION=prompt_user_loop
+# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
+# BLOCKING_PROCESS_ACTION=quit
+# BLOCKING_PROCESS_ACTION=kill
+# IGNORE_APP_STORE_APPS=yes
+# INSTALL=force
+######################################################################
+# To be used as a script sent out from a MDM.
+# Fill the variable "item" above with a label.
+# Script will run this label through Installomator.
+######################################################################
+# v. 10.0.2 : Improved icon checks and failovers
+# v. 10.0.1 : Improved appIcon handling. Can add the app to Dock using dockutil
+# v. 10.0 : Integration with Dialog and Installomator v. 10
+# v. 9.2.1 : Better logging handling and installomatorOptions fix.
+######################################################################
+
+# Mark: Script
+# PATH declaration
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+echo "$(date +%F\ %T) [LOG-BEGIN] $item"
+
+dialogUpdate() {
+ # $1: dialog command
+ local dcommand="$1"
+
+ if [[ -n $dialog_command_file ]]; then
+ echo "$dcommand" >> "$dialog_command_file"
+ echo "Dialog: $dcommand"
+ fi
+}
+checkCmdOutput () {
+ # $1: cmdOutput
+ local cmdOutput="$1"
+ exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
+ if [[ ${exitStatus} -eq 0 ]] ; then
+ echo "${item} succesfully installed."
+ warnOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "warn" || true )"
+ echo "$warnOutput"
+ else
+ echo "ERROR installing ${item}. Exit code ${exitStatus}"
+ echo "$cmdOutput"
+ #errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
+ #echo "$errorOutput"
+ fi
+}
+
+# Check the currently logged in user
+currentUser=$(stat -f "%Su" /dev/console)
+if [ -z "$currentUser" ] || [ "$currentUser" = "loginwindow" ] || [ "$currentUser" = "_mbsetupuser" ] || [ "$currentUser" = "root" ]; then
+ echo "ERROR. Logged in user is $currentUser! Cannot proceed."
+ exit 97
+fi
+# Get the current user's UID for dockutil
+uid=$(id -u "$currentUser")
+# Find the home folder of the user
+userHome="$(dscl . -read /users/${currentUser} NFSHomeDirectory | awk '{print $2}')"
+
+# Verify that Installomator has been installed
+destFile="/usr/local/Installomator/Installomator.sh"
+if [ ! -e "${destFile}" ]; then
+ echo "Installomator not found here:"
+ echo "${destFile}"
+ echo "Exiting."
+ exit 99
+fi
+
+# No sleeping
+/usr/bin/caffeinate -d -i -m -u &
+caffeinatepid=$!
+caffexit () {
+ kill "$caffeinatepid"
+ pkill caffeinate
+ exit $1
+}
+
+# Mark: Installation begins
+installomatorVersion="$(${destFile} version | cut -d "." -f1 || true)"
+
+if [[ $installomatorVersion -lt 10 ]] || [[ $(sw_vers -buildVersion) < "20A" ]]; then
+ echo "Installomator should be at least version 10 to support Dialog. Installed version $installomatorVersion."
+ echo "And macOS 11 Big Sur (build 20A) is required for Dialog. Installed build $(sw_vers -buildVersion)."
+ installomatorNotify="NOTIFY=all"
+else
+ installomatorNotify="NOTIFY=silent"
+ # check for Swift Dialog
+ if [[ ! -d $dialogApp ]]; then
+ echo "Cannot find dialog at $dialogApp"
+ # Install using Installlomator
+ cmdOutput="$(${destFile} dialog LOGO=$LOGO BLOCKING_PROCESS_ACTION=ignore LOGGING=REQ NOTIFY=silent || true)"
+ checkCmdOutput $cmdOutput
+ fi
+
+ # Configure and display swiftDialog
+ itemName=$( ${destFile} ${item} RETURN_LABEL_NAME=1 LOGGING=REQ INSTALL=force | tail -1 || true )
+ if [[ "$itemName" != "#" ]]; then
+ message="Installing ${itemName}…"
+ else
+ message="Installing ${item}…"
+ fi
+ echo "$item $itemName"
+
+ #Check icon (expecting beginning with “http” to be web-link and “/” to be disk file)
+ echo "icon before check: $icon"
+ if [[ "$(echo ${icon} | grep -iE "^(http|ftp).*")" != "" ]]; then
+ echo "icon looks to be web-link"
+ if ! curl -sfL --output /dev/null -r 0-0 "${icon}" ; then
+ echo "ERROR: Cannot download link. Reset icon."
+ icon=""
+ fi
+ elif [[ "$(echo ${icon} | grep -iE "^\/.*")" != "" ]]; then
+ echo "icon looks to be a file"
+ if [[ ! -a "${icon}" ]]; then
+ echo "ERROR: Cannot find file. Reset icon."
+ icon=""
+ fi
+ else
+ echo "ERROR: Cannot figure out icon. Reset icon."
+ icon=""
+ fi
+ echo "icon after first check: $icon"
+ # If no icon defined we are trying to search for installed app icon
+ if [[ "$icon" == "" ]]; then
+ appPath=$(mdfind "kind:application AND name:$itemName" | head -1 || true)
+ appIcon=$(defaults read "${appPath}/Contents/Info.plist" CFBundleIconFile || true)
+ if [[ "$(echo "$appIcon" | grep -io ".icns")" == "" ]]; then
+ appIcon="${appIcon}.icns"
+ fi
+ icon="${appPath}/Contents/Resources/${appIcon}"
+ echo "Icon before file check: ${icon}"
+ if [ ! -f "${icon}" ]; then
+ # Using LOGO variable to show logo in swiftDialog
+ case $LOGO in
+ appstore)
+ # Apple App Store on Mac
+ if [[ $(sw_vers -buildVersion) > "19" ]]; then
+ LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ else
+ LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ fi
+ ;;
+ jamf)
+ # Jamf Pro
+ LOGO_PATH="/Library/Application Support/JAMF/Jamf.app/Contents/Resources/AppIcon.icns"
+ ;;
+ mosyleb)
+ # Mosyle Business
+ LOGO_PATH="/Applications/Self-Service.app/Contents/Resources/AppIcon.icns"
+ ;;
+ mosylem)
+ # Mosyle Manager (education)
+ LOGO_PATH="/Applications/Manager.app/Contents/Resources/AppIcon.icns"
+ ;;
+ addigy)
+ # Addigy
+ LOGO_PATH="/Library/Addigy/macmanage/MacManage.app/Contents/Resources/atom.icns"
+ ;;
+ microsoft)
+ # Microsoft Endpoint Manager (Intune)
+ LOGO_PATH="/Library/Intune/Microsoft Intune Agent.app/Contents/Resources/AppIcon.icns"
+ ;;
+ ws1)
+ # Workspace ONE (AirWatch)
+ LOGO="/Applications/Workspace ONE Intelligent Hub.app/Contents/Resources/AppIcon.icns"
+ ;;
+ esac
+ if [[ ! -a "${LOGO_PATH}" ]]; then
+ printlog "ERROR in LOGO_PATH '${LOGO_PATH}', setting Mac App Store."
+ if [[ $(/usr/bin/sw_vers -buildVersion) > "19" ]]; then
+ LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ else
+ LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ fi
+ fi
+ icon="${LOGO_PATH}"
+ fi
+ fi
+ echo "LOGO: $LOGO"
+ echo "icon: ${icon}"
+
+ # display first screen
+ open -a "$dialogApp" --args \
+ --title none \
+ --icon "$icon" \
+ --message "$message" \
+ --mini \
+ --progress 100 \
+ --position bottomright \
+ --movable \
+ --commandfile "$dialog_command_file"
+
+ # give everything a moment to catch up
+ sleep 0.1
+fi
+
+# Install software using Installomator
+cmdOutput="$(${destFile} ${item} LOGO=$LOGO ${installomatorOptions} ${installomatorNotify} || true)"
+checkCmdOutput $cmdOutput
+
+# Mark: dockutil stuff
+if [[ $addToDock -eq 1 ]]; then
+ dialogUpdate "progresstext: Adding to Dock"
+ if [[ ! -d $dockutil ]]; then
+ echo "Cannot find dockutil at $dockutil, trying installation"
+ # Install using Installlomator
+ cmdOutput="$(${destFile} dockutil LOGO=$LOGO BLOCKING_PROCESS_ACTION=ignore LOGGING=REQ NOTIFY=silent || true)"
+ checkCmdOutput $cmdOutput
+ fi
+ echo "Adding to Dock"
+ $dockutil --add "${appPath}" "${userHome}/Library/Preferences/com.apple.dock.plist" || true
+ sleep 1
+else
+ echo "Not adding to Dock."
+fi
+
+# Mark: Ending
+if [[ $installomatorVersion -lt 10 ]]; then
+ echo "Again skipping Dialog stuff."
+else
+ # close and quit dialog
+ dialogUpdate "progress: complete"
+ dialogUpdate "progresstext: Done"
+
+ # pause a moment
+ sleep 0.5
+
+ dialogUpdate "quit:"
+
+ # let everything catch up
+ sleep 0.5
+
+ # just to be safe
+ #killall "Dialog" 2>/dev/null || true
+fi
+
+echo "[$(DATE)][LOG-END]"
+
+caffexit $exitStatus
diff --git a/MDM/App-install SS with swiftDialog and dockutil/App service SS.sh b/MDM/App-install SS with swiftDialog and dockutil/App service SS.sh
new file mode 100644
index 0000000..67d1f56
--- /dev/null
+++ b/MDM/App-install SS with swiftDialog and dockutil/App service SS.sh
@@ -0,0 +1,275 @@
+#!/bin/sh
+
+# Installation using Installomator
+
+LOGO="" # "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
+
+item="" # enter the software to install
+# Examples: applenyfonts, applesfarabic, applesfcompact, applesfmono, applesfpro, applesfsymbols, desktoppr, dialog, dockutil, knockknock, lulu, nomad, nudge, shield, supportapp, wordservice, xcreds, xink
+
+# Dialog icon
+icon=""
+# icon should be a file system path or an URL to an online PNG.
+# In Mosyle an URL can be found by copy picture address from a Custom Command icon.
+
+# dockutil variables
+addToDock="1" # with dockutil after installation (0 if not)
+appPath="/Applications/Xink.app"
+
+# Other variables
+dialog_command_file="/var/tmp/dialog.log"
+dialogApp="/Library/Application Support/Dialog/Dialog.app"
+dockutil="/usr/local/bin/dockutil"
+
+installomatorOptions="BLOCKING_PROCESS_ACTION=ignore NOTIFY=silent DIALOG_CMD_FILE=${dialog_command_file}" # Separated by space
+
+# Other installomatorOptions:
+# LOGGING=REQ
+# LOGGING=DEBUG
+# LOGGING=WARN
+# BLOCKING_PROCESS_ACTION=ignore
+# BLOCKING_PROCESS_ACTION=tell_user
+# BLOCKING_PROCESS_ACTION=tell_user_then_quit
+# BLOCKING_PROCESS_ACTION=prompt_user
+# BLOCKING_PROCESS_ACTION=prompt_user_loop
+# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
+# BLOCKING_PROCESS_ACTION=quit
+# BLOCKING_PROCESS_ACTION=kill
+# NOTIFY=all
+# NOTIFY=success
+# NOTIFY=silent
+# IGNORE_APP_STORE_APPS=yes
+# INSTALL=force
+######################################################################
+# To be used as a script sent out from a MDM.
+# Fill the variable "item" above with a label.
+# Script will run this label through Installomator.
+######################################################################
+# v. 10.0.2 : Improved icon checks and failovers
+# v. 10.0.1 : Can add the app to Dock using dockutil
+# v. 10.0 : Integration with Dialog and Installomator v. 10
+# v. 9.2.1 : Better logging handling and installomatorOptions fix.
+######################################################################
+
+# Mark: Script
+# PATH declaration
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+echo "$(date +%F\ %T) [LOG-BEGIN] $item"
+
+dialogUpdate() {
+ # $1: dialog command
+ local dcommand="$1"
+
+ if [[ -n $dialog_command_file ]]; then
+ echo "$dcommand" >> "$dialog_command_file"
+ echo "Dialog: $dcommand"
+ fi
+}
+checkCmdOutput () {
+ # $1: cmdOutput
+ local cmdOutput="$1"
+ exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
+ if [[ ${exitStatus} -eq 0 ]] ; then
+ echo "${item} succesfully installed."
+ warnOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "warn" || true )"
+ echo "$warnOutput"
+ else
+ echo "ERROR installing ${item}. Exit code ${exitStatus}"
+ echo "$cmdOutput"
+ #errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
+ #echo "$errorOutput"
+ fi
+}
+
+# Check the currently logged in user
+currentUser=$(stat -f "%Su" /dev/console)
+if [ -z "$currentUser" ] || [ "$currentUser" = "loginwindow" ] || [ "$currentUser" = "_mbsetupuser" ] || [ "$currentUser" = "root" ]; then
+ echo "ERROR. Logged in user is $currentUser! Cannot proceed."
+ exit 97
+fi
+# Get the current user's UID for dockutil
+uid=$(id -u "$currentUser")
+# Find the home folder of the user
+userHome="$(dscl . -read /users/${currentUser} NFSHomeDirectory | awk '{print $2}')"
+
+# Verify that Installomator has been installed
+destFile="/usr/local/Installomator/Installomator.sh"
+if [ ! -e "${destFile}" ]; then
+ echo "Installomator not found here:"
+ echo "${destFile}"
+ echo "Exiting."
+ exit 99
+fi
+
+# No sleeping
+/usr/bin/caffeinate -d -i -m -u &
+caffeinatepid=$!
+caffexit () {
+ kill "$caffeinatepid"
+ pkill caffeinate
+ exit $1
+}
+
+# Mark: Installation begins
+installomatorVersion="$(${destFile} version | cut -d "." -f1 || true)"
+
+if [[ $installomatorVersion -lt 10 ]] || [[ $(sw_vers -buildVersion) < "20A" ]]; then
+ echo "Installomator should be at least version 10 to support Dialog. Installed version $installomatorVersion."
+ echo "And macOS 11 Big Sur (build 20A) is required for Dialog. Installed build $(sw_vers -buildVersion)."
+ installomatorNotify="NOTIFY=all"
+else
+ installomatorNotify="NOTIFY=silent"
+ # check for Swift Dialog
+ if [[ ! -d $dialogApp ]]; then
+ echo "Cannot find dialog at $dialogApp"
+ # Install using Installlomator
+ cmdOutput="$(${destFile} dialog LOGO=$LOGO BLOCKING_PROCESS_ACTION=ignore LOGGING=REQ NOTIFY=silent || true)"
+ checkCmdOutput $cmdOutput
+ fi
+
+ # Configure and display swiftDialog
+ itemName=$( ${destFile} ${item} RETURN_LABEL_NAME=1 LOGGING=REQ INSTALL=force | tail -1 || true )
+ if [[ "$itemName" != "#" ]]; then
+ message="Installing ${itemName}…"
+ else
+ message="Installing ${item}…"
+ fi
+ echo "$item $itemName"
+
+ #Check icon (expecting beginning with “http” to be web-link and “/” to be disk file)
+ echo "icon before check: $icon"
+ if [[ "$(echo ${icon} | grep -iE "^(http|ftp).*")" != "" ]]; then
+ echo "icon looks to be web-link"
+ if ! curl -sfL --output /dev/null -r 0-0 "${icon}" ; then
+ echo "ERROR: Cannot download link. Reset icon."
+ icon=""
+ fi
+ elif [[ "$(echo ${icon} | grep -iE "^\/.*")" != "" ]]; then
+ echo "icon looks to be a file"
+ if [[ ! -a "${icon}" ]]; then
+ echo "ERROR: Cannot find file. Reset icon."
+ icon=""
+ fi
+ else
+ echo "ERROR: Cannot figure out icon. Reset icon."
+ icon=""
+ fi
+ echo "icon after first check: $icon"
+ # If no icon defined we are trying to search for installed app icon
+ if [[ "$icon" == "" ]]; then
+ appPath=$(mdfind "kind:application AND name:$itemName" | head -1 || true)
+ appIcon=$(defaults read "${appPath}/Contents/Info.plist" CFBundleIconFile || true)
+ if [[ "$(echo "$appIcon" | grep -io ".icns")" == "" ]]; then
+ appIcon="${appIcon}.icns"
+ fi
+ icon="${appPath}/Contents/Resources/${appIcon}"
+ echo "Icon before file check: ${icon}"
+ if [ ! -f "${icon}" ]; then
+ # Using LOGO variable to show logo in swiftDialog
+ case $LOGO in
+ appstore)
+ # Apple App Store on Mac
+ if [[ $(sw_vers -buildVersion) > "19" ]]; then
+ LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ else
+ LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ fi
+ ;;
+ jamf)
+ # Jamf Pro
+ LOGO_PATH="/Library/Application Support/JAMF/Jamf.app/Contents/Resources/AppIcon.icns"
+ ;;
+ mosyleb)
+ # Mosyle Business
+ LOGO_PATH="/Applications/Self-Service.app/Contents/Resources/AppIcon.icns"
+ ;;
+ mosylem)
+ # Mosyle Manager (education)
+ LOGO_PATH="/Applications/Manager.app/Contents/Resources/AppIcon.icns"
+ ;;
+ addigy)
+ # Addigy
+ LOGO_PATH="/Library/Addigy/macmanage/MacManage.app/Contents/Resources/atom.icns"
+ ;;
+ microsoft)
+ # Microsoft Endpoint Manager (Intune)
+ LOGO_PATH="/Library/Intune/Microsoft Intune Agent.app/Contents/Resources/AppIcon.icns"
+ ;;
+ ws1)
+ # Workspace ONE (AirWatch)
+ LOGO="/Applications/Workspace ONE Intelligent Hub.app/Contents/Resources/AppIcon.icns"
+ ;;
+ esac
+ if [[ ! -a "${LOGO_PATH}" ]]; then
+ printlog "ERROR in LOGO_PATH '${LOGO_PATH}', setting Mac App Store."
+ if [[ $(/usr/bin/sw_vers -buildVersion) > "19" ]]; then
+ LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ else
+ LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ fi
+ fi
+ icon="${LOGO_PATH}"
+ fi
+ fi
+ echo "LOGO: $LOGO"
+ echo "icon: ${icon}"
+
+ # display first screen
+ open -a "$dialogApp" --args \
+ --title none \
+ --icon "$icon" \
+ --message "$message" \
+ --mini \
+ --progress 100 \
+ --position bottomright \
+ --movable \
+ --commandfile "$dialog_command_file"
+
+ # give everything a moment to catch up
+ sleep 0.1
+fi
+
+# Install software using Installomator
+cmdOutput="$(${destFile} ${item} LOGO=$LOGO ${installomatorOptions} ${installomatorNotify} || true)"
+checkCmdOutput $cmdOutput
+
+# Mark: dockutil stuff
+if [[ $addToDock -eq 1 ]]; then
+ dialogUpdate "progresstext: Adding to Dock"
+ if [[ ! -d $dockutil ]]; then
+ echo "Cannot find dockutil at $dockutil, trying installation"
+ # Install using Installlomator
+ cmdOutput="$(${destFile} dockutil LOGO=$LOGO BLOCKING_PROCESS_ACTION=ignore LOGGING=REQ NOTIFY=silent || true)"
+ checkCmdOutput $cmdOutput
+ fi
+ echo "Adding to Dock"
+ $dockutil --add "${appPath}" "${userHome}/Library/Preferences/com.apple.dock.plist" || true
+ sleep 1
+else
+ echo "Not adding to Dock."
+fi
+
+# Mark: Ending
+if [[ $installomatorVersion -lt 10 ]]; then
+ echo "Again skipping Dialog stuff."
+else
+ # close and quit dialog
+ dialogUpdate "progress: complete"
+ dialogUpdate "progresstext: Done"
+
+ # pause a moment
+ sleep 0.5
+
+ dialogUpdate "quit:"
+
+ # let everything catch up
+ sleep 0.5
+
+ # just to be safe
+ #killall "Dialog" 2>/dev/null || true
+fi
+
+echo "[$(DATE)][LOG-END]"
+
+caffexit $exitStatus
diff --git a/MDM/App-install/App VFA.sh b/MDM/App-install/App VFA.sh
new file mode 100755
index 0000000..3162a67
--- /dev/null
+++ b/MDM/App-install/App VFA.sh
@@ -0,0 +1,98 @@
+#!/bin/sh
+
+# Installation using Installomator
+# Installation of software using valuesfromarguments to install a custom software using Installomator
+
+LOGO="" # "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
+
+#item="" # enter the software to install (if it has a label in future version of Installomator)
+
+# Variables for label
+name="ClickShare"
+type="appInDmgInZip"
+packageID=""
+downloadURL="https://www.barco.com$( curl -fs "https://www.barco.com/en/clickshare/app" | grep -A6 -i "macos" | grep -i "FileNumber" | tr '"' "\n" | grep -i "FileNumber" )"
+appNewVersion="$(eval "$( echo $downloadURL | sed -E 's/.*(MajorVersion.*BuildVersion=[0-9]*).*/\1/' | sed 's/&//g' )" ; ((MajorVersion++)) ; ((MajorVersion--)); ((MinorVersion++)) ; ((MinorVersion--)); ((PatchVersion++)) ; ((PatchVersion--)); ((BuildVersion++)) ; ((BuildVersion--)); echo "${MajorVersion}.${MinorVersion}.${PatchVersion}-b${BuildVersion}")"
+versionKey=""
+expectedTeamID="P6CDJZR997"
+
+installomatorOptions="BLOCKING_PROCESS_ACTION=prompt_user LOGGING=INFO NOTIFY=all" # Separated by space
+
+# Other installomatorOptions:
+# LOGGING=REQ
+# LOGGING=DEBUG
+# LOGGING=WARN
+# BLOCKING_PROCESS_ACTION=ignore
+# BLOCKING_PROCESS_ACTION=tell_user
+# BLOCKING_PROCESS_ACTION=tell_user_then_quit
+# BLOCKING_PROCESS_ACTION=prompt_user
+# BLOCKING_PROCESS_ACTION=prompt_user_loop
+# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
+# BLOCKING_PROCESS_ACTION=quit
+# BLOCKING_PROCESS_ACTION=kill
+# NOTIFY=all
+# NOTIFY=success
+# NOTIFY=silent
+# IGNORE_APP_STORE_APPS=yes
+# INSTALL=force
+######################################################################
+# To be used as a script sent out from a MDM.
+# Fill the variable "what" above with a label.
+# Script will run this label through Installomator.
+######################################################################
+# v. 9.2.1 : Better logging handling and installomatorOptions fix.
+######################################################################
+
+# Mark: Script
+# PATH declaration
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+echo "$(date +%F\ %T) [LOG-BEGIN] $what"
+
+# Verify that Installomator has been installed
+destFile="/usr/local/Installomator/Installomator.sh"
+if [ ! -e "${destFile}" ]; then
+ echo "Installomator not found here:"
+ echo "${destFile}"
+ echo "Exiting."
+ exit 99
+fi
+
+# No sleeping
+/usr/bin/caffeinate -d -i -m -u &
+caffeinatepid=$!
+caffexit () {
+ kill "$caffeinatepid"
+ pkill caffeinate
+ exit $1
+}
+
+# Install software using Installomator with valuesfromarguments
+cmdOutput="$(${destFile} valuesfromarguments LOGO=$LOGO \
+ name=\"${name}\" \
+ type=${type} \
+ packageID=${packageID} \
+ downloadURL=\"$downloadURL\" \
+ appNewVersion=${appNewVersion} \
+ versionKey=${versionKey} \
+ expectedTeamID=${expectedTeamID} \
+ blockingProcesses=\"NONE\" \
+ ${installomatorOptions} || true)"
+
+
+# Check result
+exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
+if [[ ${exitStatus} -eq 0 ]] ; then
+ echo "${what} succesfully installed."
+ warnOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "warn" || true )"
+ echo "$warnOutput"
+else
+ echo "ERROR installing ${what}. Exit code ${exitStatus}"
+ echo "$cmdOutput"
+ #errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
+ #echo "$errorOutput"
+fi
+
+echo "[$(DATE)][LOG-END]"
+
+caffexit $exitStatus
diff --git a/MDM/App-install/App browser-security Auto-install.sh b/MDM/App-install/App browser-security Auto-install.sh
new file mode 100644
index 0000000..c45b568
--- /dev/null
+++ b/MDM/App-install/App browser-security Auto-install.sh
@@ -0,0 +1,79 @@
+#!/bin/sh
+
+# Installation using Installomator
+
+LOGO="" # "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
+
+item="firefoxpkg" # enter the software to install
+# Examples: brave, duckduckgo, firefoxpkg, googlechromepkg, microsoftedge, opera
+
+installomatorOptions="BLOCKING_PROCESS_ACTION=tell_user_then_quit" # Separated by space
+
+# Other installomatorOptions:
+# LOGGING=REQ
+# LOGGING=DEBUG
+# LOGGING=WARN
+# BLOCKING_PROCESS_ACTION=ignore
+# BLOCKING_PROCESS_ACTION=tell_user
+# BLOCKING_PROCESS_ACTION=tell_user_then_quit
+# BLOCKING_PROCESS_ACTION=prompt_user
+# BLOCKING_PROCESS_ACTION=prompt_user_loop
+# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
+# BLOCKING_PROCESS_ACTION=quit
+# BLOCKING_PROCESS_ACTION=kill
+# NOTIFY=all
+# NOTIFY=success
+# NOTIFY=silent
+# IGNORE_APP_STORE_APPS=yes
+# INSTALL=force
+######################################################################
+# To be used as a script sent out from a MDM.
+# Fill the variable "item" above with a label.
+# Script will run this label through Installomator.
+######################################################################
+# v. 9.2.1 : Better logging handling and installomatorOptions fix.
+######################################################################
+
+# Mark: Script
+# PATH declaration
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+echo "$(date +%F\ %T) [LOG-BEGIN] $item"
+
+# Verify that Installomator has been installed
+destFile="/usr/local/Installomator/Installomator.sh"
+if [ ! -e "${destFile}" ]; then
+ echo "Installomator not found here:"
+ echo "${destFile}"
+ echo "Exiting."
+ exit 99
+fi
+
+# No sleeping
+/usr/bin/caffeinate -d -i -m -u &
+caffeinatepid=$!
+caffexit () {
+ kill "$caffeinatepid"
+ pkill caffeinate
+ exit $1
+}
+
+# Install software using Installomator
+cmdOutput="$(${destFile} ${item} LOGO=$LOGO ${installomatorOptions} || true)"
+
+# Check result
+exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
+if [[ ${exitStatus} -eq 0 ]] ; then
+ echo "${item} succesfully installed."
+ warnOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "warn" || true )"
+ echo "$warnOutput"
+else
+ echo "ERROR installing ${item}. Exit code ${exitStatus}"
+ echo "$cmdOutput"
+ #errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
+ #echo "$errorOutput"
+fi
+
+echo "[$(DATE)][LOG-END]"
+
+caffexit $exitStatus
diff --git a/MDM/App-install/App browser-security SS.sh b/MDM/App-install/App browser-security SS.sh
new file mode 100644
index 0000000..83c8b12
--- /dev/null
+++ b/MDM/App-install/App browser-security SS.sh
@@ -0,0 +1,79 @@
+#!/bin/sh
+
+# Installation using Installomator
+
+LOGO="" # "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
+
+item="" # enter the software to install
+# Examples: brave, duckduckgo, firefoxpkg, googlechromepkg, microsoftedge, opera
+
+installomatorOptions="BLOCKING_PROCESS_ACTION=tell_user_then_quit NOTIFY=all" # Separated by space
+
+# Other installomatorOptions:
+# LOGGING=REQ
+# LOGGING=DEBUG
+# LOGGING=WARN
+# BLOCKING_PROCESS_ACTION=ignore
+# BLOCKING_PROCESS_ACTION=tell_user
+# BLOCKING_PROCESS_ACTION=tell_user_then_quit
+# BLOCKING_PROCESS_ACTION=prompt_user
+# BLOCKING_PROCESS_ACTION=prompt_user_loop
+# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
+# BLOCKING_PROCESS_ACTION=quit
+# BLOCKING_PROCESS_ACTION=kill
+# NOTIFY=all
+# NOTIFY=success
+# NOTIFY=silent
+# IGNORE_APP_STORE_APPS=yes
+# INSTALL=force
+######################################################################
+# To be used as a script sent out from a MDM.
+# Fill the variable "what" above with a label.
+# Script will run this label through Installomator.
+######################################################################
+# v. 9.2.1 : Better logging handling and installomatorOptions fix.
+######################################################################
+
+# Mark: Script
+# PATH declaration
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+echo "$(date +%F\ %T) [LOG-BEGIN] $what"
+
+# Verify that Installomator has been installed
+destFile="/usr/local/Installomator/Installomator.sh"
+if [ ! -e "${destFile}" ]; then
+ echo "Installomator not found here:"
+ echo "${destFile}"
+ echo "Exiting."
+ exit 99
+fi
+
+# No sleeping
+/usr/bin/caffeinate -d -i -m -u &
+caffeinatepid=$!
+caffexit () {
+ kill "$caffeinatepid"
+ pkill caffeinate
+ exit $1
+}
+
+# Install software using Installomator
+cmdOutput="$(${destFile} ${what} LOGO=$LOGO ${installomatorOptions} || true)"
+
+# Check result
+exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
+if [[ ${exitStatus} -eq 0 ]] ; then
+ echo "${what} succesfully installed."
+ warnOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "warn" || true )"
+ echo "$warnOutput"
+else
+ echo "ERROR installing ${what}. Exit code ${exitStatus}"
+ echo "$cmdOutput"
+ #errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
+ #echo "$errorOutput"
+fi
+
+echo "[$(DATE)][LOG-END]"
+
+caffexit $exitStatus
diff --git a/MDM/App-install/App normal Auto-install.sh b/MDM/App-install/App normal Auto-install.sh
new file mode 100644
index 0000000..986b054
--- /dev/null
+++ b/MDM/App-install/App normal Auto-install.sh
@@ -0,0 +1,79 @@
+#!/bin/sh
+
+# Installation using Installomator
+
+LOGO="" # "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
+
+item="" # enter the software to install
+# Examples: adobecreativeclouddesktop, textmate, vlc
+
+installomatorOptions="BLOCKING_PROCESS_ACTION=tell_user" # Separated by space
+
+# Other installomatorOptions:
+# LOGGING=REQ
+# LOGGING=DEBUG
+# LOGGING=WARN
+# BLOCKING_PROCESS_ACTION=ignore
+# BLOCKING_PROCESS_ACTION=tell_user
+# BLOCKING_PROCESS_ACTION=tell_user_then_quit
+# BLOCKING_PROCESS_ACTION=prompt_user
+# BLOCKING_PROCESS_ACTION=prompt_user_loop
+# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
+# BLOCKING_PROCESS_ACTION=quit
+# BLOCKING_PROCESS_ACTION=kill
+# NOTIFY=all
+# NOTIFY=success
+# NOTIFY=silent
+# IGNORE_APP_STORE_APPS=yes
+# INSTALL=force
+######################################################################
+# To be used as a script sent out from a MDM.
+# Fill the variable "item" above with a label.
+# Script will run this label through Installomator.
+######################################################################
+# v. 9.2.1 : Better logging handling and installomatorOptions fix.
+######################################################################
+
+# Mark: Script
+# PATH declaration
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+echo "$(date +%F\ %T) [LOG-BEGIN] $item"
+
+# Verify that Installomator has been installed
+destFile="/usr/local/Installomator/Installomator.sh"
+if [ ! -e "${destFile}" ]; then
+ echo "Installomator not found here:"
+ echo "${destFile}"
+ echo "Exiting."
+ exit 99
+fi
+
+# No sleeping
+/usr/bin/caffeinate -d -i -m -u &
+caffeinatepid=$!
+caffexit () {
+ kill "$caffeinatepid"
+ pkill caffeinate
+ exit $1
+}
+
+# Install software using Installomator
+cmdOutput="$(${destFile} ${item} LOGO=$LOGO ${installomatorOptions} || true)"
+
+# Check result
+exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
+if [[ ${exitStatus} -eq 0 ]] ; then
+ echo "${item} succesfully installed."
+ warnOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "warn" || true )"
+ echo "$warnOutput"
+else
+ echo "ERROR installing ${item}. Exit code ${exitStatus}"
+ echo "$cmdOutput"
+ #errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
+ #echo "$errorOutput"
+fi
+
+echo "[$(DATE)][LOG-END]"
+
+caffexit $exitStatus
diff --git a/MDM/App-install/App normal SS.sh b/MDM/App-install/App normal SS.sh
new file mode 100644
index 0000000..06f7c04
--- /dev/null
+++ b/MDM/App-install/App normal SS.sh
@@ -0,0 +1,80 @@
+#!/bin/sh
+
+# Installation using Installomator
+
+LOGO="" # "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
+
+item="" # enter the software to install
+# Examples: adobecreativeclouddesktop, canva, cyberduck, handbrake, inkscape, textmate, vlc
+
+
+installomatorOptions="BLOCKING_PROCESS_ACTION=prompt_user NOTIFY=all" # Separated by space
+
+# Other installomatorOptions:
+# LOGGING=REQ
+# LOGGING=DEBUG
+# LOGGING=WARN
+# BLOCKING_PROCESS_ACTION=ignore
+# BLOCKING_PROCESS_ACTION=tell_user
+# BLOCKING_PROCESS_ACTION=tell_user_then_quit
+# BLOCKING_PROCESS_ACTION=prompt_user
+# BLOCKING_PROCESS_ACTION=prompt_user_loop
+# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
+# BLOCKING_PROCESS_ACTION=quit
+# BLOCKING_PROCESS_ACTION=kill
+# NOTIFY=all
+# NOTIFY=success
+# NOTIFY=silent
+# IGNORE_APP_STORE_APPS=yes
+# INSTALL=force
+######################################################################
+# To be used as a script sent out from a MDM.
+# Fill the variable "item" above with a label.
+# Script will run this label through Installomator.
+######################################################################
+# v. 9.2.1 : Better logging handling and installomatorOptions fix.
+######################################################################
+
+# Mark: Script
+# PATH declaration
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+echo "$(date +%F\ %T) [LOG-BEGIN] $item"
+
+# Verify that Installomator has been installed
+destFile="/usr/local/Installomator/Installomator.sh"
+if [ ! -e "${destFile}" ]; then
+ echo "Installomator not found here:"
+ echo "${destFile}"
+ echo "Exiting."
+ exit 99
+fi
+
+# No sleeping
+/usr/bin/caffeinate -d -i -m -u &
+caffeinatepid=$!
+caffexit () {
+ kill "$caffeinatepid"
+ pkill caffeinate
+ exit $1
+}
+
+# Install software using Installomator
+cmdOutput="$(${destFile} ${item} LOGO=$LOGO ${installomatorOptions} || true)"
+
+# Check result
+exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
+if [[ ${exitStatus} -eq 0 ]] ; then
+ echo "${item} succesfully installed."
+ warnOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "warn" || true )"
+ echo "$warnOutput"
+else
+ echo "ERROR installing ${item}. Exit code ${exitStatus}"
+ echo "$cmdOutput"
+ #errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
+ #echo "$errorOutput"
+fi
+
+echo "[$(DATE)][LOG-END]"
+
+caffexit $exitStatus
diff --git a/MDM/App-install/App service Auto-install.sh b/MDM/App-install/App service Auto-install.sh
new file mode 100644
index 0000000..aa7165e
--- /dev/null
+++ b/MDM/App-install/App service Auto-install.sh
@@ -0,0 +1,79 @@
+#!/bin/sh
+
+# Installation using Installomator
+
+LOGO="" # "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
+
+item="dockutil" # enter the software to install
+# Examples: applenyfonts, applesfarabic, applesfcompact, applesfmono, applesfpro, applesfsymbols, desktoppr, dialog, dockutil, knockknock, lulu, nomad, nudge, shield, supportapp, wordservice, xcreds, xink
+
+installomatorOptions="BLOCKING_PROCESS_ACTION=ignore NOTIFY=silent" # Separated by space
+
+# Other installomatorOptions:
+# LOGGING=REQ
+# LOGGING=DEBUG
+# LOGGING=WARN
+# BLOCKING_PROCESS_ACTION=ignore
+# BLOCKING_PROCESS_ACTION=tell_user
+# BLOCKING_PROCESS_ACTION=tell_user_then_quit
+# BLOCKING_PROCESS_ACTION=prompt_user
+# BLOCKING_PROCESS_ACTION=prompt_user_loop
+# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
+# BLOCKING_PROCESS_ACTION=quit
+# BLOCKING_PROCESS_ACTION=kill
+# NOTIFY=all
+# NOTIFY=success
+# NOTIFY=silent
+# IGNORE_APP_STORE_APPS=yes
+# INSTALL=force
+######################################################################
+# To be used as a script sent out from a MDM.
+# Fill the variable "item" above with a label.
+# Script will run this label through Installomator.
+######################################################################
+# v. 9.2.1 : Better logging handling and installomatorOptions fix.
+######################################################################
+
+# Mark: Script
+# PATH declaration
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+echo "$(date +%F\ %T) [LOG-BEGIN] $item"
+
+# Verify that Installomator has been installed
+destFile="/usr/local/Installomator/Installomator.sh"
+if [ ! -e "${destFile}" ]; then
+ echo "Installomator not found here:"
+ echo "${destFile}"
+ echo "Exiting."
+ exit 99
+fi
+
+# No sleeping
+/usr/bin/caffeinate -d -i -m -u &
+caffeinatepid=$!
+caffexit () {
+ kill "$caffeinatepid"
+ pkill caffeinate
+ exit $1
+}
+
+# Install software using Installomator
+cmdOutput="$(${destFile} ${item} LOGO=$LOGO ${installomatorOptions} || true)"
+
+# Check result
+exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
+if [[ ${exitStatus} -eq 0 ]] ; then
+ echo "${item} succesfully installed."
+ warnOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "warn" || true )"
+ echo "$warnOutput"
+else
+ echo "ERROR installing ${item}. Exit code ${exitStatus}"
+ echo "$cmdOutput"
+ #errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
+ #echo "$errorOutput"
+fi
+
+echo "[$(DATE)][LOG-END]"
+
+caffexit $exitStatus
diff --git a/MDM/App-loop script.sh b/MDM/App-loop script.sh
deleted file mode 100755
index 8fb33e7..0000000
--- a/MDM/App-loop script.sh
+++ /dev/null
@@ -1,193 +0,0 @@
-#!/bin/zsh
-# Installation using Installomator
-whatList="microsoftteams microsoftyammer firefox bravebrowser cyberduck vlc signal" # enter the software to install separated with spaces
-
-# To be used as a script sent out from a MDM.
-# Fill the variable "whatList" above with labels separated by space " ".
-# Script will loop through these labels.
-LOGO="appstore" # or "addigy", "microsoft", "mosyleb", "mosylem"
-######################################################################
-# Parameters for reinstall/initial install (owner root:wheel):
-# "BLOCKING_PROCESS_ACTION=quit_kill INSTALL=force IGNORE_APP_STORE_APPS=yes SYSTEMOWNER=1"
-# Parameters for Self Service installed app:
-# "BLOCKING_PROCESS_ACTION=prompt_user NOTIFY=all"
-# Parameters for security important apps, like browsers (run automaticaly every day):
-# "BLOCKING_PROCESS_ACTION=tell_user_then_kill"
-# Update of service apps (run automatically):
-# "BLOCKING_PROCESS_ACTION=quit_kill NOTIFY=silent"
-parameters="BLOCKING_PROCESS_ACTION=tell_user NOTIFY=all"
-######################################################################
-
-# Verify that Installomator has been installed
-destFile="/usr/local/Installomator/Installomator.sh"
-if [ ! -e "${destFile}" ]; then
- echo "Installomator not found here:"
- echo "${destFile}"
- echo "Exiting."
- exit 99
-fi
-
-# No sleeping
-/usr/bin/caffeinate -d -i -m -u &
-caffeinatepid=$!
-caffexit () {
- kill "$caffeinatepid"
- pkill caffeinate
- exit $1
-}
-
-# Count errors
-errorCount=0
-
-for what in $whatList; do
- #echo $what
- # Install software using Installomator
- cmdOutput="$(${destFile} ${what} LOGO=$LOGO $parameters LOGGING=WARN || true)"
- # Check result
- exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
- if [[ ${exitStatus} -ne 0 ]] ; then
- echo -e "Error installing ${what}. Exit code ${exitStatus}"
- #echo "$cmdOutput"
- errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
- echo "$errorOutput"
- let errorCount++
- fi
-done
-
-echo
-echo "Errors: $errorCount"
-echo "[$(DATE)][LOG-END]"
-
-caffexit $errorCount
-
-# notify behavior
-# NOTIFY=success
-# options:
-# - success notify the user on success
-# - silent no notifications
-# - all all notifications (great for Self Service installation)
-
-
-# behavior when blocking processes are found
-# BLOCKING_PROCESS_ACTION=tell_user
-# options:
-# - ignore continue even when blocking processes are found
-# - quit app will be told to quit nicely, if running
-# - quit_kill told to quit twice, then it will be killed
-# Could be great for service apps, if they do not respawn
-# - silent_fail exit script without prompt or installation
-# - prompt_user show a user dialog for each blocking process found
-# abort after three attempts to quit
-# (only if user accepts to quit the apps, otherwise
-# the update is cancelled).
-# - prompt_user_then_kill
-# show a user dialog for each blocking process found,
-# attempt to quit two times, kill the process finally
-# - prompt_user_loop
-# Like prompt-user, but clicking "Not Now", will just wait an hour,
-# and then it will ask again.
-# WARNING! It might block the MDM agent on the machine, as
-# the scripts gets stuct in waiting until the hour has passed,
-# possibly blocking for other management actions in this time.
-# - tell_user User will be showed a notification about the important update,
-# but user is only allowed to quit and continue, and then we
-# ask the app to quit.
-# - tell_user_then_kill
-# Show dialog 2 times, and if the quitting fails, the
-# blocking processes will be killed.
-# - kill kill process without prompting or giving the user a chance to save
-
-
-# logo-icon used in dialog boxes if app is blocking
-# LOGO=appstore
-# options:
-# - appstore Icon is Apple App Store (default)
-# - jamf JAMF Pro
-# - mosyleb Mosyle Business
-# - mosylem Mosyle Manager (Education)
-# - addigy Addigy
-# 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).
-
-
-# App Store apps handling
-# IGNORE_APP_STORE_APPS=no
-# options:
-# - no If installed app is from App Store (which include VPP installed apps)
-# it will not be touched, no matter it's version (default)
-# - yes Replace App Store (and VPP) version of app and handle future
-# updates using Installomator, even if latest version.
-# Shouldn’t give any problems for the user in most cases.
-# Known bad example: Slack will loose all settings.
-
-
-# install behavior
-# INSTALL=""
-# options:
-# - When not set, software will only be installed
-# if it is newer/different in version
-# - force Install even if it’s the same version
-
-
-# Re-opening of closed app
-# REOPEN="yes"
-# options:
-# - yes App wil be reopened if it was closed
-# - no App not reopened
-
-
-########################
-# Often used labels:
-########################
-
-# firefox
-# firefox_intl
-# brave
-# torbrowser
-# googlechrome
-# netnewswire
-
-# adobereaderdc
-# textmate
-
-# cyberduck
-# keka
-# theunarchiver
-
-# vlc
-# handbrake
-
-# inkscape
-
-# signal
-# telegram
-# whatsapp
-
-# hazel
-# devonthink
-
-# teamviewerqs
-# zoom
-
-# malwarebytes
-# githubdesktop
-# sublimetext
-# textmate
-# visualstudiocode
-
-# microsoftskypeforbusiness
-# microsoftteams
-# microsoftyammer
-# microsoftedgeenterprisestable
-# microsoftedgeconsumerstable
-# microsoftsharepointplugin
-# microsoftdefenderatp
-
-# googledrivefilestream
-
-# cdef
-# desktoppr
-# supportapp
-# xink
-# wwdc
diff --git a/MDM/App-update/App browser-security Auto-install.sh b/MDM/App-update/App browser-security Auto-install.sh
new file mode 100644
index 0000000..211e564
--- /dev/null
+++ b/MDM/App-update/App browser-security Auto-install.sh
@@ -0,0 +1,92 @@
+#!/bin/sh
+
+# Update with Installomator if app exist
+
+LOGO="" # "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
+
+item="microsoftedge" # enter the software to install
+# Examples: brave, duckduckgo, firefoxpkg, googlechromepkg, microsoftedge, opera
+appPath="/Applications/Microsoft Edge.app"
+# Examples: Microsoft Edge.app, Brave Browser.app, DuckDuckGo.app, Google Chrome.app, Firefox.app, Opera.app
+
+installomatorOptions="BLOCKING_PROCESS_ACTION=tell_user_then_quit" # Separated by space
+
+# Other installomatorOptions:
+# LOGGING=REQ
+# LOGGING=DEBUG
+# LOGGING=WARN
+# BLOCKING_PROCESS_ACTION=ignore
+# BLOCKING_PROCESS_ACTION=tell_user
+# BLOCKING_PROCESS_ACTION=tell_user_then_quit
+# BLOCKING_PROCESS_ACTION=prompt_user
+# BLOCKING_PROCESS_ACTION=prompt_user_loop
+# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
+# BLOCKING_PROCESS_ACTION=quit
+# BLOCKING_PROCESS_ACTION=kill
+# NOTIFY=all
+# NOTIFY=success
+# NOTIFY=silent
+# IGNORE_APP_STORE_APPS=yes
+# INSTALL=force
+######################################################################
+# To be used as a script sent out from a MDM.
+# Fill the variable "item" above with a label.
+# Script will run this label through Installomator.
+######################################################################
+# v. 9.2.1 : Better logging handling and installomatorOptions fix.
+######################################################################
+
+# Mark: Script
+# PATH declaration
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+echo "$(date +%F\ %T) [LOG-BEGIN] $item"
+
+# Check if app is installed
+# We only want this to run if it's already installed
+if [ ! -e "${appPath}" ]; then
+ echo "App not found here:"
+ echo "${appPath}"
+ echo "Exiting."
+ exit 98
+fi
+echo "${appPath} Found!"
+
+# Verify that Installomator has been installed
+destFile="/usr/local/Installomator/Installomator.sh"
+if [ ! -e "${destFile}" ]; then
+ echo "Installomator not found here:"
+ echo "${destFile}"
+ echo "Exiting."
+ exit 99
+fi
+
+# No sleeping
+/usr/bin/caffeinate -d -i -m -u &
+caffeinatepid=$!
+caffexit () {
+ kill "$caffeinatepid"
+ pkill caffeinate
+ exit $1
+}
+
+# Install software using Installomator
+cmdOutput="$(${destFile} ${item} LOGO=$LOGO ${installomatorOptions} || true)"
+
+# Check result
+exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
+if [[ ${exitStatus} -eq 0 ]] ; then
+ echo "${item} succesfully installed."
+ warnOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "warn" || true )"
+ echo "$warnOutput"
+else
+ echo "ERROR installing ${item}. Exit code ${exitStatus}"
+ echo "$cmdOutput"
+ #errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
+ #echo "$errorOutput"
+fi
+
+echo "[$(DATE)][LOG-END]"
+
+caffexit $exitStatus
+
diff --git a/MDM/App-update/App normal Auto-install.sh b/MDM/App-update/App normal Auto-install.sh
new file mode 100644
index 0000000..c2ac671
--- /dev/null
+++ b/MDM/App-update/App normal Auto-install.sh
@@ -0,0 +1,92 @@
+#!/bin/sh
+
+# Update with Installomator if app exist
+
+LOGO="" # "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
+
+item="" # enter the software to install
+# Examples: cyberduck, handbrake, textmate, vlc
+appPath="/Applications/Cyberduck.app"
+# Examples: Cyberduck.app, Handbrake.app, Textmate.app, VLC.app
+
+installomatorOptions="BLOCKING_PROCESS_ACTION=prompt_user" # Separated by space
+
+# Other installomatorOptions:
+# LOGGING=REQ
+# LOGGING=DEBUG
+# LOGGING=WARN
+# BLOCKING_PROCESS_ACTION=ignore
+# BLOCKING_PROCESS_ACTION=tell_user
+# BLOCKING_PROCESS_ACTION=tell_user_then_quit
+# BLOCKING_PROCESS_ACTION=prompt_user
+# BLOCKING_PROCESS_ACTION=prompt_user_loop
+# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
+# BLOCKING_PROCESS_ACTION=quit
+# BLOCKING_PROCESS_ACTION=kill
+# NOTIFY=all
+# NOTIFY=success
+# NOTIFY=silent
+# IGNORE_APP_STORE_APPS=yes
+# INSTALL=force
+######################################################################
+# To be used as a script sent out from a MDM.
+# Fill the variable "item" above with a label.
+# Script will run this label through Installomator.
+######################################################################
+# v. 9.2.1 : Better logging handling and installomatorOptions fix.
+######################################################################
+
+# Mark: Script
+# PATH declaration
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+echo "$(date +%F\ %T) [LOG-BEGIN] $item"
+
+# Check if app is installed
+# We only want this to run if it's already installed
+if [ ! -e "${appPath}" ]; then
+ echo "App not found here:"
+ echo "${appPath}"
+ echo "Exiting."
+ exit 98
+fi
+echo "${appPath} Found!"
+
+# Verify that Installomator has been installed
+destFile="/usr/local/Installomator/Installomator.sh"
+if [ ! -e "${destFile}" ]; then
+ echo "Installomator not found here:"
+ echo "${destFile}"
+ echo "Exiting."
+ exit 99
+fi
+
+# No sleeping
+/usr/bin/caffeinate -d -i -m -u &
+caffeinatepid=$!
+caffexit () {
+ kill "$caffeinatepid"
+ pkill caffeinate
+ exit $1
+}
+
+# Install software using Installomator
+cmdOutput="$(${destFile} ${item} LOGO=$LOGO ${installomatorOptions} || true)"
+
+# Check result
+exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
+if [[ ${exitStatus} -eq 0 ]] ; then
+ echo "${item} succesfully installed."
+ warnOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "warn" || true )"
+ echo "$warnOutput"
+else
+ echo "ERROR installing ${item}. Exit code ${exitStatus}"
+ echo "$cmdOutput"
+ #errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
+ #echo "$errorOutput"
+fi
+
+echo "[$(DATE)][LOG-END]"
+
+caffexit $exitStatus
+
diff --git a/MDM/Installomator 1st Auto-install DEPNotify.sh b/MDM/Installomator 1st Auto-install DEPNotify.sh
new file mode 100755
index 0000000..7baa737
--- /dev/null
+++ b/MDM/Installomator 1st Auto-install DEPNotify.sh
@@ -0,0 +1,360 @@
+#!/bin/sh
+
+# Installomator 1st installation with DEPNotify window (auto installation at enrollment)
+instance="" # Name of used instance
+
+LOGO="" # "appstore", "jamf", "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
+
+items=(dialog dockutil microsoftautoupdate supportapp applenyfonts applesfpro applesfmono applesfcompact xink zohoworkdrivetruesync textmate 1password7 wwdc theunarchiver keka microsoftedge microsoftteams microsoftonedrive microsoftoffice365)
+# Remember: dialog dockutil
+
+installomatorOptions="NOTIFY=silent BLOCKING_PROCESS_ACTION=ignore INSTALL=force IGNORE_APP_STORE_APPS=yes LOGGING=REQ"
+
+# DEPNotify display settings, change as desired
+title="Installing Apps and other software"
+message="Please wait while we download and install the needed software."
+endMessage="Installation complete! Please reboot to activate FileVault."
+errorMessage="A problem was encountered setting up this Mac. Please contact IT."
+
+######################################################################
+# Installomator 1st DEPNotify
+#
+# Installation using Installomator showing progress with DEPNotify
+# Great stand-alone solution if installs are only done using Installomator.
+# No customization below…
+######################################################################
+# This script can be used to install software using Installomator.
+# Script will start DEPNotify to display a progress bar.
+# Progress bar moves between installations
+######################################################################
+# Other installomatorOptions:
+# LOGGING=REQ
+# LOGGING=DEBUG
+# LOGGING=WARN
+# BLOCKING_PROCESS_ACTION=ignore
+# BLOCKING_PROCESS_ACTION=tell_user
+# BLOCKING_PROCESS_ACTION=tell_user_then_quit
+# BLOCKING_PROCESS_ACTION=prompt_user
+# BLOCKING_PROCESS_ACTION=prompt_user_loop
+# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
+# BLOCKING_PROCESS_ACTION=quit
+# BLOCKING_PROCESS_ACTION=kill
+# NOTIFY=all
+# NOTIFY=success
+# NOTIFY=silent
+# IGNORE_APP_STORE_APPS=yes
+# INSTALL=force
+######################################################################
+#
+# This script made by Søren Theilgaard
+# https://github.com/Theile
+# Twitter and MacAdmins Slack: @theilgaard
+#
+# Some functions and code from Installomator:
+# https://github.com/Installomator/Installomator
+#
+######################################################################
+scriptVersion="9.5"
+# v. 9.5 : 2022-09-21 : change of GitHub download
+# v. 9.4 : 2022-09-14 : downloadURL can fall back on GitHub API
+# v. 9.3 : 2022-08-29 : installomatorOptions in quotes and ignore blocking processes. Improved installation with looping if it fails, so it can try again. Improved GitHub handling. ws1 support.
+# v. 9.2.2 : 2022-06-17 : installomatorOptions introduced. Check 1.1.1.1 for internet connection.
+# v. 9.2.1 : 2022-05-30 : Some changes to logging
+# v. 9.2 : 2022-05-19 : Built in installer for Installlomator, and display dialog if error happens. Now universal script for all supported MDMs based on LOGO variable.
+# v. 9.1 : 2022-04-13 : Using INSTALL=force in Label only, so Microsoft labels will not start updating
+# v. 9.0.1 : 2022-02-21 : LOGO=addigy, few more "true" lines, and errorOutput on error
+# v. 9.0.0 : 2022-02-14 : Updated for Inst. 9.0, Logging improved with printlog
+######################################################################
+
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+# Check before running
+case $LOGO in
+ addigy|microsoft)
+ conditionFile="/var/db/.Installomator1stDone"
+ # Addigy and Microsoft Endpoint Manager (Intune) need a check for a touched file
+ if [ -e "$conditionFile" ]; then
+ echo "$LOGO setup detected"
+ echo "$conditionFile exists, so we exit."
+ exit 0
+ else
+ echo "$conditionFile not found, so we continue…"
+ fi
+ ;;
+esac
+
+# Mark: Constants, logging and caffeinate
+log_message="$instance: Installomator 1st with DEPNotify, v$scriptVersion"
+label="1st-v$scriptVersion"
+
+log_location="/private/var/log/Installomator.log"
+printlog(){
+ timestamp=$(date +%F\ %T)
+ if [[ "$(whoami)" == "root" ]]; then
+ echo "$timestamp :: $label : $1" | tee -a $log_location
+ else
+ echo "$timestamp :: $label : $1"
+ fi
+}
+printlog "[LOG-BEGIN] ${log_message}"
+
+# Internet check
+if [[ "$(nc -z -v -G 10 1.1.1.1 53 2>&1 | grep -io "succeeded")" != "succeeded" ]]; then
+ printlog "ERROR. No internet connection, we cannot continue."
+ exit 90
+fi
+
+# No sleeping
+/usr/bin/caffeinate -d -i -m -u &
+caffeinatepid=$!
+caffexit () {
+ kill "$caffeinatepid" || true
+ pkill caffeinate || true
+ printlog "[LOG-END] Status $1"
+ exit $1
+}
+
+# Command-file to DEPNotify
+DEPNOTIFY_LOG="/var/tmp/depnotify.log"
+
+# Counters
+errorCount=0
+countLabels=${#items[@]}
+printlog "Total installations: $countLabels"
+
+# Using LOGO variable to specify MDM and shown logo
+case $LOGO in
+ appstore)
+ # Apple App Store on Mac
+ if [[ $(sw_vers -buildVersion) > "19" ]]; then
+ LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ else
+ LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ fi
+ ;;
+ jamf)
+ # Jamf Pro
+ LOGO_PATH="/Library/Application Support/JAMF/Jamf.app/Contents/Resources/AppIcon.icns"
+ ;;
+ mosyleb)
+ # Mosyle Business
+ LOGO_PATH="/Applications/Self-Service.app/Contents/Resources/AppIcon.icns"
+ ;;
+ mosylem)
+ # Mosyle Manager (education)
+ LOGO_PATH="/Applications/Manager.app/Contents/Resources/AppIcon.icns"
+ ;;
+ addigy)
+ # Addigy
+ LOGO_PATH="/Library/Addigy/macmanage/MacManage.app/Contents/Resources/atom.icns"
+ ;;
+ microsoft)
+ # Microsoft Endpoint Manager (Intune)
+ LOGO_PATH="/Library/Intune/Microsoft Intune Agent.app/Contents/Resources/AppIcon.icns"
+ ;;
+ ws1)
+ # Workspace ONE (AirWatch)
+ LOGO="/Applications/Workspace ONE Intelligent Hub.app/Contents/Resources/AppIcon.icns"
+ ;;
+esac
+if [[ ! -a "${LOGO_PATH}" ]]; then
+ printlog "ERROR in LOGO_PATH '${LOGO_PATH}', setting Mac App Store."
+ if [[ $(/usr/bin/sw_vers -buildVersion) > "19" ]]; then
+ LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ else
+ LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ fi
+fi
+printlog "LOGO: $LOGO - LOGO_PATH: $LOGO_PATH"
+
+# Mark: Functions
+printlog "depnotify_command function"
+echo "" > $DEPNOTIFY_LOG || true
+function depnotify_command(){
+ printlog "DEPNotify-command: $1"
+ echo "$1" >> $DEPNOTIFY_LOG || true
+}
+
+printlog "startDEPNotify function"
+function startDEPNotify() {
+ currentUser="$(stat -f "%Su" /dev/console)"
+ currentUserID=$(id -u "$currentUser")
+ launchctl asuser $currentUserID open -a "/Applications/Utilities/DEPNotify.app/Contents/MacOS/DEPNotify" --args -path "$DEPNOTIFY_LOG" || true # --args -fullScreen
+ sleep 5
+ depnotify_command "Command: KillCommandFile:"
+ depnotify_command "Command: MainTitle: $title"
+ depnotify_command "Command: Image: $LOGO_PATH"
+ depnotify_command "Command: MainText: $message"
+ depnotify_command "Command: Determinate: $countLabels"
+}
+
+# Notify the user using AppleScript
+printlog "displayDialog function"
+function displayDialog(){
+ currentUser="$(stat -f "%Su" /dev/console)"
+ currentUserID=$(id -u "$currentUser")
+ if [[ "$currentUser" != "" ]]; then
+ launchctl asuser $currentUserID sudo -u $currentUser osascript -e "button returned of (display dialog \"$message\" buttons {\"OK\"} default button \"OK\" with icon POSIX file \"$LOGO_PATH\")" || true
+ fi
+}
+
+# Mark: Code
+name="Installomator"
+printlog "$name check for installation"
+# download URL, version and Expected Team ID
+# Method for GitHub pkg
+gitusername="Installomator"
+gitreponame="Installomator"
+#printlog "$gitusername $gitreponame"
+filetype="pkg"
+#downloadURL="https://github.com$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
+downloadURL="https://github.com$(curl -sfL "$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "expanded_assets" | head -1)" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
+if [[ "$(echo $downloadURL | grep -ioE "https.*.$filetype")" == "" ]]; then
+ printlog "Trying GitHub API for download URL."
+ downloadURL=$(curl -sfL "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | awk -F '"' "/browser_download_url/ && /$filetype\"/ { print \$4; exit }")
+fi
+#printlog "$downloadURL"
+appNewVersion=$(curl -sLI "https://github.com/$gitusername/$gitreponame/releases/latest" | grep -i "^location" | tr "/" "\n" | tail -1 | sed 's/[^0-9\.]//g')
+#printlog "$appNewVersion"
+expectedTeamID="JME5BW3F3R"
+
+destFile="/usr/local/Installomator/Installomator.sh"
+currentInstalledVersion="$(${destFile} version 2>/dev/null || true)"
+printlog "${destFile} version: $currentInstalledVersion"
+if [[ ! -e "${destFile}" || "$currentInstalledVersion" != "$appNewVersion" ]]; then
+ printlog "$name not found or version not latest."
+ printlog "${destFile}"
+ printlog "Installing version ${appNewVersion} ..."
+ # Create temporary working directory
+ tmpDir="$(mktemp -d || true)"
+ printlog "Created working directory '$tmpDir'"
+ # Download the installer package
+ printlog "Downloading $name package version $appNewVersion from: $downloadURL"
+ installationCount=0
+ exitCode=9
+ while [[ $installationCount -lt 3 && $exitCode -gt 0 ]]; do
+ curlDownload=$(curl -Ls "$downloadURL" -o "$tmpDir/$name.pkg" || true)
+ curlDownloadStatus=$(echo $?)
+ if [[ $curlDownloadStatus -ne 0 ]]; then
+ printlog "error downloading $downloadURL, with status $curlDownloadStatus"
+ printlog "${curlDownload}"
+ exitCode=1
+ else
+ printlog "Download $name succes."
+ # Verify the download
+ teamID=$(spctl -a -vv -t install "$tmpDir/$name.pkg" 2>&1 | awk '/origin=/ {print $NF }' | tr -d '()' || true)
+ printlog "Team ID for downloaded package: $teamID"
+ # Install the package if Team ID validates
+ if [ "$expectedTeamID" = "$teamID" ] || [ "$expectedTeamID" = "" ]; then
+ printlog "$name package verified. Installing package '$tmpDir/$name.pkg'."
+ pkgInstall=$(installer -verbose -dumplog -pkg "$tmpDir/$name.pkg" -target "/" 2>&1)
+ pkgInstallStatus=$(echo $?)
+ if [[ $pkgInstallStatus -ne 0 ]]; then
+ printlog "ERROR. $name package installation failed."
+ printlog "${pkgInstall}"
+ exitCode=2
+ else
+ printlog "Installing $name package succes."
+ exitCode=0
+ fi
+ else
+ printlog "ERROR. Package verification failed for $name before package installation could start. Download link may be invalid."
+ exitCode=3
+ fi
+ fi
+ ((installationCount++))
+ printlog "$installationCount time(s), exitCode $exitCode"
+ if [[ $installationCount -lt 3 ]]; then
+ if [[ $exitCode -gt 0 ]]; then
+ printlog "Sleep a bit before trying download and install again. $installationCount time(s)."
+ printlog "Remove $(rm -fv "$tmpDir/$name.pkg" || true)"
+ sleep 2
+ fi
+ else
+ printlog "Download and install of $name succes."
+ fi
+ done
+ # Remove the temporary working directory
+ printlog "Deleting working directory '$tmpDir' and its contents."
+ printlog "Remove $(rm -Rfv "${tmpDir}" || true)"
+ # Handle installation errors
+ if [[ $exitCode != 0 ]]; then
+ printlog "ERROR. Installation of $name failed. Aborting."
+ caffexit $exitCode
+ else
+ printlog "$name version $appNewVersion installed!"
+ fi
+else
+ printlog "$name version $appNewVersion already found. Perfect!"
+fi
+
+# Installing DEPNotify
+cmdOutput="$( ${destFile} depnotify LOGO=$LOGO NOTIFY=silent BLOCKING_PROCESS_ACTION=ignore LOGGING=WARN || true )"
+exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
+printlog "DEPNotify install result: $exitStatus"
+
+itemName=""
+errorLabels=""
+((countLabels++))
+((countLabels--))
+printlog "$countLabels labels to install"
+
+startDEPNotify
+
+for item in "${items[@]}"; do
+ # Check if DEPNotify is running and try open it if not
+ if ! pgrep -xq "DEPNotify"; then
+ startDEPNotify
+ fi
+ itemName=$( ${destFile} ${item} RETURN_LABEL_NAME=1 LOGGING=REQ INSTALL=force | tail -1 || true )
+ if [[ "$itemName" != "#" ]]; then
+ depnotify_command "Status: $itemName installing…"
+ else
+ depnotify_command "Status: $item installing…"
+ fi
+ printlog "$item $itemName"
+ cmdOutput="$( ${destFile} ${item} LOGO=$LOGO ${installomatorOptions} || true )"
+ #cmdOutput="2022-05-19 13:20:45 : REQ : installomator : ################## End Installomator, exit code 0"
+ exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
+ if [[ ${exitStatus} -eq 0 ]] ; then
+ printlog "${item} succesfully installed."
+ warnOutput="$( echo "${cmdOutput}" | grep --binary-files=text "WARN" || true )"
+ printlog "$warnOutput"
+ else
+ printlog "Error installing ${item}. Exit code ${exitStatus}"
+ #printlog "$cmdOutput"
+ errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
+ printlog "$errorOutput"
+ ((errorCount++))
+ errorLabels="$errorLabels ${item}"
+ fi
+ ((countLabels--))
+ itemName=""
+done
+
+# Mark: Finishing
+# Prevent re-run of script if conditionFile is set
+if [[ ! -z "$conditionFile" ]]; then
+ printlog "Touching condition file so script will not run again"
+ touch "$conditionFile" || true
+ printlog "$(ls -al "$conditionFile" || true)"
+fi
+
+# Show error to user if any
+printlog "Errors: $errorCount"
+if [[ $errorCount -ne 0 ]]; then
+ errorMessage="${errorMessage} Total errors: $errorCount"
+ message="$errorMessage"
+ displayDialog &
+ endMessage="$message"
+ printlog "errorLabels: $errorLabels"
+fi
+
+depnotify_command "Command: MainText: $endMessage"
+depnotify_command "Command: Quit: $endMessage"
+
+sleep 1
+printlog "Remove $(rm -fv $DEPNOTIFY_LOG || true)"
+
+printlog "Ending"
+caffexit $errorCount
diff --git a/MDM/Installomator 1st Auto-install.sh b/MDM/Installomator 1st Auto-install.sh
new file mode 100755
index 0000000..6dd9353
--- /dev/null
+++ b/MDM/Installomator 1st Auto-install.sh
@@ -0,0 +1,308 @@
+#!/bin/sh
+
+# Installomator 1st installation (auto installation at enrollment)
+instance="" # Name of used instance
+
+LOGO="" # "appstore", "jamf", "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
+
+items=(dialog dockutil microsoftautoupdate supportapp xink zohoworkdrivetruesync textmate applenyfonts applesfpro applesfmono applesfcompact 1password7 wwdc theunarchiver keka microsoftedge microsoftteams microsoftonedrive microsoftoffice365)
+# Remember: dialog dockutil
+
+installomatorOptions="NOTIFY=silent BLOCKING_PROCESS_ACTION=ignore INSTALL=force IGNORE_APP_STORE_APPS=yes LOGGING=REQ"
+
+# Error message to user if any occur
+showError="1" # Show error message if 1 (0 if it should not be shown)
+errorMessage="A problem was encountered setting up this Mac. Please contact IT."
+
+######################################################################
+# Installomator 1st
+#
+# Installation using Installomator
+# (use separate Progress 1st script to show progress)
+# No customization below…
+######################################################################
+# This script can be used to install software using Installomator.
+# Script will display a dialog if any errors happens.
+# User is not notified about installations.
+######################################################################
+# Other installomatorOptions:
+# LOGGING=REQ
+# LOGGING=DEBUG
+# LOGGING=WARN
+# BLOCKING_PROCESS_ACTION=ignore
+# BLOCKING_PROCESS_ACTION=tell_user
+# BLOCKING_PROCESS_ACTION=tell_user_then_quit
+# BLOCKING_PROCESS_ACTION=prompt_user
+# BLOCKING_PROCESS_ACTION=prompt_user_loop
+# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
+# BLOCKING_PROCESS_ACTION=quit
+# BLOCKING_PROCESS_ACTION=kill
+# NOTIFY=all
+# NOTIFY=success
+# NOTIFY=silent
+# IGNORE_APP_STORE_APPS=yes
+# INSTALL=force
+######################################################################
+#
+# This script made by Søren Theilgaard
+# https://github.com/Theile
+# Twitter and MacAdmins Slack: @theilgaard
+#
+# Some functions and code from Installomator:
+# https://github.com/Installomator/Installomator
+#
+######################################################################
+scriptVersion="9.5"
+# v. 9.5 : 2022-09-21 : change of GitHub download
+# v. 9.4 : 2022-09-14 : Making error message optional. downloadURL can fall back on GitHub API.
+# v. 9.3 : 2022-08-29 : installomatorOptions in quotes and ignore blocking processes. Improved installation with looping if it fails, so it can try again. Improved GitHub handling. ws1 support.
+# v. 9.2.2 : 2022-06-17 : installomatorOptions introduced. Check 1.1.1.1 for internet connection.
+# v. 9.2.1 : 2022-05-30 : Some changes to logging
+# v. 9.2 : 2022-05-19 : Built in installer for Installomator, and display dialog if error happens. Now universal script for all supported MDMs based on LOGO variable.
+######################################################################
+
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+# Check before running
+case $LOGO in
+ addigy|microsoft)
+ conditionFile="/var/db/.Installomator1stDone"
+ # Addigy and Microsoft Endpoint Manager (Intune) need a check for a touched file
+ if [ -e "$conditionFile" ]; then
+ echo "$LOGO setup detected"
+ echo "$conditionFile exists, so we exit."
+ exit 0
+ else
+ echo "$conditionFile not found, so we continue…"
+ fi
+ ;;
+esac
+
+# Mark: Constants, logging and caffeinate
+log_message="$instance: Installomator 1st, v$scriptVersion"
+label="1st-v$scriptVersion"
+
+log_location="/private/var/log/Installomator.log"
+printlog(){
+ timestamp=$(date +%F\ %T)
+ if [[ "$(whoami)" == "root" ]]; then
+ echo "$timestamp :: $label : $1" | tee -a $log_location
+ else
+ echo "$timestamp :: $label : $1"
+ fi
+}
+printlog "[LOG-BEGIN] ${log_message}"
+
+# Internet check
+if [[ "$(nc -z -v -G 10 1.1.1.1 53 2>&1 | grep -io "succeeded")" != "succeeded" ]]; then
+ printlog "ERROR. No internet connection, we cannot continue."
+ caffexit 90
+fi
+
+# No sleeping
+/usr/bin/caffeinate -d -i -m -u &
+caffeinatepid=$!
+caffexit () {
+ kill "$caffeinatepid" || true
+ pkill caffeinate || true
+ printlog "[LOG-END] Status $1"
+ exit $1
+}
+
+# Counters
+errorCount=0
+countLabels=${#items[@]}
+printlog "Total installations: $countLabels"
+
+# Using LOGO variable to specify MDM and shown logo
+case $LOGO in
+ appstore)
+ # Apple App Store on Mac
+ if [[ $(sw_vers -buildVersion) > "19" ]]; then
+ LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ else
+ LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ fi
+ ;;
+ jamf)
+ # Jamf Pro
+ LOGO_PATH="/Library/Application Support/JAMF/Jamf.app/Contents/Resources/AppIcon.icns"
+ ;;
+ mosyleb)
+ # Mosyle Business
+ LOGO_PATH="/Applications/Self-Service.app/Contents/Resources/AppIcon.icns"
+ ;;
+ mosylem)
+ # Mosyle Manager (education)
+ LOGO_PATH="/Applications/Manager.app/Contents/Resources/AppIcon.icns"
+ ;;
+ addigy)
+ # Addigy
+ LOGO_PATH="/Library/Addigy/macmanage/MacManage.app/Contents/Resources/atom.icns"
+ ;;
+ microsoft)
+ # Microsoft Endpoint Manager (Intune)
+ LOGO_PATH="/Library/Intune/Microsoft Intune Agent.app/Contents/Resources/AppIcon.icns"
+ ;;
+ ws1)
+ # Workspace ONE (AirWatch)
+ LOGO="/Applications/Workspace ONE Intelligent Hub.app/Contents/Resources/AppIcon.icns"
+ ;;
+esac
+if [[ ! -a "${LOGO_PATH}" ]]; then
+ printlog "ERROR in LOGO_PATH '${LOGO_PATH}', setting Mac App Store."
+ if [[ $(/usr/bin/sw_vers -buildVersion) > "19" ]]; then
+ LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ else
+ LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ fi
+fi
+printlog "LOGO: $LOGO – LOGO_PATH: $LOGO_PATH"
+
+# Mark: Functions
+# Notify the user using AppleScript
+function displayDialog(){
+ currentUser="$(stat -f "%Su" /dev/console)"
+ currentUserID=$(id -u "$currentUser")
+ if [[ "$currentUser" != "" ]]; then
+ launchctl asuser $currentUserID sudo -u $currentUser osascript -e "button returned of (display dialog \"$message\" buttons {\"OK\"} default button \"OK\" with icon POSIX file \"$LOGO_PATH\")" || true
+ fi
+}
+
+# Mark: Code
+name="Installomator"
+printlog "$name check for installation"
+# download URL, version and Expected Team ID
+# Method for GitHub pkg
+gitusername="Installomator"
+gitreponame="Installomator"
+#printlog "$gitusername $gitreponame"
+filetype="pkg"
+#downloadURL="https://github.com$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
+downloadURL="https://github.com$(curl -sfL "$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "expanded_assets" | head -1)" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
+if [[ "$(echo $downloadURL | grep -ioE "https.*.$filetype")" == "" ]]; then
+ printlog "Trying GitHub API for download URL."
+ downloadURL=$(curl -sfL "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | awk -F '"' "/browser_download_url/ && /$filetype\"/ { print \$4; exit }")
+fi
+#printlog "$downloadURL"
+appNewVersion=$(curl -sLI "https://github.com/$gitusername/$gitreponame/releases/latest" | grep -i "^location" | tr "/" "\n" | tail -1 | sed 's/[^0-9\.]//g')
+#printlog "$appNewVersion"
+expectedTeamID="JME5BW3F3R"
+
+destFile="/usr/local/Installomator/Installomator.sh"
+currentInstalledVersion="$(${destFile} version 2>/dev/null || true)"
+printlog "${destFile} version: $currentInstalledVersion"
+if [[ ! -e "${destFile}" || "$currentInstalledVersion" != "$appNewVersion" ]]; then
+ printlog "$name not found or version not latest."
+ printlog "${destFile}"
+ printlog "Installing version ${appNewVersion} ..."
+ # Create temporary working directory
+ tmpDir="$(mktemp -d || true)"
+ printlog "Created working directory '$tmpDir'"
+ # Download the installer package
+ printlog "Downloading $name package version $appNewVersion from: $downloadURL"
+ installationCount=0
+ exitCode=9
+ while [[ $installationCount -lt 3 && $exitCode -gt 0 ]]; do
+ curlDownload=$(curl -Ls "$downloadURL" -o "$tmpDir/$name.pkg" || true)
+ curlDownloadStatus=$(echo $?)
+ if [[ $curlDownloadStatus -ne 0 ]]; then
+ printlog "error downloading $downloadURL, with status $curlDownloadStatus"
+ printlog "${curlDownload}"
+ exitCode=1
+ else
+ printlog "Download $name succes."
+ # Verify the download
+ teamID=$(spctl -a -vv -t install "$tmpDir/$name.pkg" 2>&1 | awk '/origin=/ {print $NF }' | tr -d '()' || true)
+ printlog "Team ID for downloaded package: $teamID"
+ # Install the package if Team ID validates
+ if [ "$expectedTeamID" = "$teamID" ] || [ "$expectedTeamID" = "" ]; then
+ printlog "$name package verified. Installing package '$tmpDir/$name.pkg'."
+ pkgInstall=$(installer -verbose -dumplog -pkg "$tmpDir/$name.pkg" -target "/" 2>&1)
+ pkgInstallStatus=$(echo $?)
+ if [[ $pkgInstallStatus -ne 0 ]]; then
+ printlog "ERROR. $name package installation failed."
+ printlog "${pkgInstall}"
+ exitCode=2
+ else
+ printlog "Installing $name package succes."
+ exitCode=0
+ fi
+ else
+ printlog "ERROR. Package verification failed for $name before package installation could start. Download link may be invalid."
+ exitCode=3
+ fi
+ fi
+ ((installationCount++))
+ printlog "$installationCount time(s), exitCode $exitCode"
+ if [[ $installationCount -lt 3 ]]; then
+ if [[ $exitCode -gt 0 ]]; then
+ printlog "Sleep a bit before trying download and install again. $installationCount time(s)."
+ printlog "Remove $(rm -fv "$tmpDir/$name.pkg" || true)"
+ sleep 2
+ fi
+ else
+ printlog "Download and install of $name succes."
+ fi
+ done
+ # Remove the temporary working directory
+ printlog "Deleting working directory '$tmpDir' and its contents."
+ printlog "Remove $(rm -Rfv "${tmpDir}" || true)"
+ # Handle installation errors
+ if [[ $exitCode != 0 ]]; then
+ printlog "ERROR. Installation of $name failed. Aborting."
+ caffexit $exitCode
+ else
+ printlog "$name version $appNewVersion installed!"
+ fi
+else
+ printlog "$name version $appNewVersion already found. Perfect!"
+fi
+
+errorLabels=""
+((countLabels++))
+((countLabels--))
+printlog "$countLabels labels to install"
+
+for item in "${items[@]}"; do
+ printlog "$item"
+ cmdOutput="$( ${destFile} ${item} LOGO=$LOGO ${installomatorOptions} || true )"
+ exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
+ if [[ ${exitStatus} -eq 0 ]] ; then
+ printlog "${item} succesfully installed."
+ warnOutput="$( echo "${cmdOutput}" | grep --binary-files=text "WARN" || true )"
+ printlog "$warnOutput"
+ else
+ printlog "Error installing ${item}. Exit code ${exitStatus}"
+ #printlog "$cmdOutput"
+ errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
+ printlog "$errorOutput"
+ ((errorCount++))
+ errorLabels="$errorLabels ${item}"
+ fi
+ ((countLabels--))
+ itemName=""
+done
+
+# Mark: Finishing
+# Prevent re-run of script if conditionFile is set
+if [[ ! -z "$conditionFile" ]]; then
+ printlog "Touching condition file so script will not run again"
+ touch "$conditionFile" || true
+ printlog "$(ls -al "$conditionFile" || true)"
+fi
+
+# Show error to user if any
+printlog "Errors: $errorCount"
+if [[ $errorCount -ne 0 ]]; then
+ printlog "ERROR: Display error dialog to user!"
+ errorMessage="${errorMessage} Total errors: $errorCount"
+ if [[ $showError -eq 1 ]]; then
+ message="$errorMessage"
+ displayDialog &
+ fi
+ printlog "errorLabels: $errorLabels"
+fi
+
+printlog "Ending"
+caffexit $errorCount
diff --git a/MDM/Installomator 1st SS DEPNotify.sh b/MDM/Installomator 1st SS DEPNotify.sh
new file mode 100755
index 0000000..b911f79
--- /dev/null
+++ b/MDM/Installomator 1st SS DEPNotify.sh
@@ -0,0 +1,360 @@
+#!/bin/sh
+
+# Installomator 1st installation with DEPNotify window (for self Service deployment)
+instance="" # Name of used instance
+
+LOGO="" # "appstore", "jamf", "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
+
+items=(dialog dockutil microsoftautoupdate supportapp applenyfonts applesfpro applesfmono applesfcompact xink zohoworkdrivetruesync textmate 1password7 wwdc theunarchiver keka microsoftedge microsoftteams microsoftonedrive microsoftoffice365)
+# Remember: dialog dockutil
+
+installomatorOptions="NOTIFY=all BLOCKING_PROCESS_ACTION=prompt_user"
+
+# DEPNotify display settings, change as desired
+title="Installing Apps and other software"
+message="Please wait while we download and install the needed software."
+endMessage="Installation complete! Please reboot to activate FileVault."
+errorMessage="A problem was encountered setting up this Mac. Please contact IT."
+
+######################################################################
+# Installomator 1st DEPNotify
+#
+# Installation using Installomator showing progress with DEPNotify
+# Great stand-alone solution if installs are only done using Installomator.
+# No customization below…
+######################################################################
+# This script can be used to install software using Installomator.
+# Script will start DEPNotify to display a progress bar.
+# Progress bar moves between installations
+######################################################################
+# Other installomatorOptions:
+# LOGGING=REQ
+# LOGGING=DEBUG
+# LOGGING=WARN
+# BLOCKING_PROCESS_ACTION=ignore
+# BLOCKING_PROCESS_ACTION=tell_user
+# BLOCKING_PROCESS_ACTION=tell_user_then_quit
+# BLOCKING_PROCESS_ACTION=prompt_user
+# BLOCKING_PROCESS_ACTION=prompt_user_loop
+# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
+# BLOCKING_PROCESS_ACTION=quit
+# BLOCKING_PROCESS_ACTION=kill
+# NOTIFY=all
+# NOTIFY=success
+# NOTIFY=silent
+# IGNORE_APP_STORE_APPS=yes
+# INSTALL=force
+######################################################################
+#
+# This script made by Søren Theilgaard
+# https://github.com/Theile
+# Twitter and MacAdmins Slack: @theilgaard
+#
+# Some functions and code from Installomator:
+# https://github.com/Installomator/Installomator
+#
+######################################################################
+scriptVersion="9.5"
+# v. 9.5 : 2022-09-21 : change of GitHub download
+# v. 9.4 : 2022-09-14 : downloadURL can fall back on GitHub API
+# v. 9.3 : 2022-08-29 : installomatorOptions in quotes and ignore blocking processes. Improved installation with looping if it fails, so it can try again. Improved GitHub handling. ws1 support.
+# v. 9.2.2 : 2022-06-17 : installomatorOptions introduced. Check 1.1.1.1 for internet connection.
+# v. 9.2.1 : 2022-05-30 : Some changes to logging
+# v. 9.2 : 2022-05-19 : Built in installer for Installlomator, and display dialog if error happens. Now universal script for all supported MDMs based on LOGO variable.
+# v. 9.1 : 2022-04-13 : Using INSTALL=force in Label only, so Microsoft labels will not start updating
+# v. 9.0.1 : 2022-02-21 : LOGO=addigy, few more "true" lines, and errorOutput on error
+# v. 9.0.0 : 2022-02-14 : Updated for Inst. 9.0, Logging improved with printlog
+######################################################################
+
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+# Check before running
+case $LOGO in
+ addigy|microsoft)
+ conditionFile="/var/db/.Installomator1stDone"
+ # Addigy and Microsoft Endpoint Manager (Intune) need a check for a touched file
+ if [ -e "$conditionFile" ]; then
+ echo "$LOGO setup detected"
+ echo "$conditionFile exists, so we exit."
+ exit 0
+ else
+ echo "$conditionFile not found, so we continue…"
+ fi
+ ;;
+esac
+
+# Mark: Constants, logging and caffeinate
+log_message="$instance: Installomator 1st with DEPNotify, v$scriptVersion"
+label="1st-v$scriptVersion"
+
+log_location="/private/var/log/Installomator.log"
+printlog(){
+ timestamp=$(date +%F\ %T)
+ if [[ "$(whoami)" == "root" ]]; then
+ echo "$timestamp :: $label : $1" | tee -a $log_location
+ else
+ echo "$timestamp :: $label : $1"
+ fi
+}
+printlog "[LOG-BEGIN] ${log_message}"
+
+# Internet check
+if [[ "$(nc -z -v -G 10 1.1.1.1 53 2>&1 | grep -io "succeeded")" != "succeeded" ]]; then
+ printlog "ERROR. No internet connection, we cannot continue."
+ exit 90
+fi
+
+# No sleeping
+/usr/bin/caffeinate -d -i -m -u &
+caffeinatepid=$!
+caffexit () {
+ kill "$caffeinatepid" || true
+ pkill caffeinate || true
+ printlog "[LOG-END] Status $1"
+ exit $1
+}
+
+# Command-file to DEPNotify
+DEPNOTIFY_LOG="/var/tmp/depnotify.log"
+
+# Counters
+errorCount=0
+countLabels=${#items[@]}
+printlog "Total installations: $countLabels"
+
+# Using LOGO variable to specify MDM and shown logo
+case $LOGO in
+ appstore)
+ # Apple App Store on Mac
+ if [[ $(sw_vers -buildVersion) > "19" ]]; then
+ LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ else
+ LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ fi
+ ;;
+ jamf)
+ # Jamf Pro
+ LOGO_PATH="/Library/Application Support/JAMF/Jamf.app/Contents/Resources/AppIcon.icns"
+ ;;
+ mosyleb)
+ # Mosyle Business
+ LOGO_PATH="/Applications/Self-Service.app/Contents/Resources/AppIcon.icns"
+ ;;
+ mosylem)
+ # Mosyle Manager (education)
+ LOGO_PATH="/Applications/Manager.app/Contents/Resources/AppIcon.icns"
+ ;;
+ addigy)
+ # Addigy
+ LOGO_PATH="/Library/Addigy/macmanage/MacManage.app/Contents/Resources/atom.icns"
+ ;;
+ microsoft)
+ # Microsoft Endpoint Manager (Intune)
+ LOGO_PATH="/Library/Intune/Microsoft Intune Agent.app/Contents/Resources/AppIcon.icns"
+ ;;
+ ws1)
+ # Workspace ONE (AirWatch)
+ LOGO="/Applications/Workspace ONE Intelligent Hub.app/Contents/Resources/AppIcon.icns"
+ ;;
+esac
+if [[ ! -a "${LOGO_PATH}" ]]; then
+ printlog "ERROR in LOGO_PATH '${LOGO_PATH}', setting Mac App Store."
+ if [[ $(/usr/bin/sw_vers -buildVersion) > "19" ]]; then
+ LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ else
+ LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ fi
+fi
+printlog "LOGO: $LOGO - LOGO_PATH: $LOGO_PATH"
+
+# Mark: Functions
+printlog "depnotify_command function"
+echo "" > $DEPNOTIFY_LOG || true
+function depnotify_command(){
+ printlog "DEPNotify-command: $1"
+ echo "$1" >> $DEPNOTIFY_LOG || true
+}
+
+printlog "startDEPNotify function"
+function startDEPNotify() {
+ currentUser="$(stat -f "%Su" /dev/console)"
+ currentUserID=$(id -u "$currentUser")
+ launchctl asuser $currentUserID open -a "/Applications/Utilities/DEPNotify.app/Contents/MacOS/DEPNotify" --args -path "$DEPNOTIFY_LOG" || true # --args -fullScreen
+ sleep 5
+ depnotify_command "Command: KillCommandFile:"
+ depnotify_command "Command: MainTitle: $title"
+ depnotify_command "Command: Image: $LOGO_PATH"
+ depnotify_command "Command: MainText: $message"
+ depnotify_command "Command: Determinate: $countLabels"
+}
+
+# Notify the user using AppleScript
+printlog "displayDialog function"
+function displayDialog(){
+ currentUser="$(stat -f "%Su" /dev/console)"
+ currentUserID=$(id -u "$currentUser")
+ if [[ "$currentUser" != "" ]]; then
+ launchctl asuser $currentUserID sudo -u $currentUser osascript -e "button returned of (display dialog \"$message\" buttons {\"OK\"} default button \"OK\" with icon POSIX file \"$LOGO_PATH\")" || true
+ fi
+}
+
+# Mark: Code
+name="Installomator"
+printlog "$name check for installation"
+# download URL, version and Expected Team ID
+# Method for GitHub pkg
+gitusername="Installomator"
+gitreponame="Installomator"
+#printlog "$gitusername $gitreponame"
+filetype="pkg"
+#downloadURL="https://github.com$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
+downloadURL="https://github.com$(curl -sfL "$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "expanded_assets" | head -1)" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
+if [[ "$(echo $downloadURL | grep -ioE "https.*.$filetype")" == "" ]]; then
+ printlog "Trying GitHub API for download URL."
+ downloadURL=$(curl -sfL "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | awk -F '"' "/browser_download_url/ && /$filetype\"/ { print \$4; exit }")
+fi
+#printlog "$downloadURL"
+appNewVersion=$(curl -sLI "https://github.com/$gitusername/$gitreponame/releases/latest" | grep -i "^location" | tr "/" "\n" | tail -1 | sed 's/[^0-9\.]//g')
+#printlog "$appNewVersion"
+expectedTeamID="JME5BW3F3R"
+
+destFile="/usr/local/Installomator/Installomator.sh"
+currentInstalledVersion="$(${destFile} version 2>/dev/null || true)"
+printlog "${destFile} version: $currentInstalledVersion"
+if [[ ! -e "${destFile}" || "$currentInstalledVersion" != "$appNewVersion" ]]; then
+ printlog "$name not found or version not latest."
+ printlog "${destFile}"
+ printlog "Installing version ${appNewVersion} ..."
+ # Create temporary working directory
+ tmpDir="$(mktemp -d || true)"
+ printlog "Created working directory '$tmpDir'"
+ # Download the installer package
+ printlog "Downloading $name package version $appNewVersion from: $downloadURL"
+ installationCount=0
+ exitCode=9
+ while [[ $installationCount -lt 3 && $exitCode -gt 0 ]]; do
+ curlDownload=$(curl -Ls "$downloadURL" -o "$tmpDir/$name.pkg" || true)
+ curlDownloadStatus=$(echo $?)
+ if [[ $curlDownloadStatus -ne 0 ]]; then
+ printlog "error downloading $downloadURL, with status $curlDownloadStatus"
+ printlog "${curlDownload}"
+ exitCode=1
+ else
+ printlog "Download $name succes."
+ # Verify the download
+ teamID=$(spctl -a -vv -t install "$tmpDir/$name.pkg" 2>&1 | awk '/origin=/ {print $NF }' | tr -d '()' || true)
+ printlog "Team ID for downloaded package: $teamID"
+ # Install the package if Team ID validates
+ if [ "$expectedTeamID" = "$teamID" ] || [ "$expectedTeamID" = "" ]; then
+ printlog "$name package verified. Installing package '$tmpDir/$name.pkg'."
+ pkgInstall=$(installer -verbose -dumplog -pkg "$tmpDir/$name.pkg" -target "/" 2>&1)
+ pkgInstallStatus=$(echo $?)
+ if [[ $pkgInstallStatus -ne 0 ]]; then
+ printlog "ERROR. $name package installation failed."
+ printlog "${pkgInstall}"
+ exitCode=2
+ else
+ printlog "Installing $name package succes."
+ exitCode=0
+ fi
+ else
+ printlog "ERROR. Package verification failed for $name before package installation could start. Download link may be invalid."
+ exitCode=3
+ fi
+ fi
+ ((installationCount++))
+ printlog "$installationCount time(s), exitCode $exitCode"
+ if [[ $installationCount -lt 3 ]]; then
+ if [[ $exitCode -gt 0 ]]; then
+ printlog "Sleep a bit before trying download and install again. $installationCount time(s)."
+ printlog "Remove $(rm -fv "$tmpDir/$name.pkg" || true)"
+ sleep 2
+ fi
+ else
+ printlog "Download and install of $name succes."
+ fi
+ done
+ # Remove the temporary working directory
+ printlog "Deleting working directory '$tmpDir' and its contents."
+ printlog "Remove $(rm -Rfv "${tmpDir}" || true)"
+ # Handle installation errors
+ if [[ $exitCode != 0 ]]; then
+ printlog "ERROR. Installation of $name failed. Aborting."
+ caffexit $exitCode
+ else
+ printlog "$name version $appNewVersion installed!"
+ fi
+else
+ printlog "$name version $appNewVersion already found. Perfect!"
+fi
+
+# Installing DEPNotify
+cmdOutput="$( ${destFile} depnotify LOGO=$LOGO NOTIFY=silent BLOCKING_PROCESS_ACTION=ignore LOGGING=WARN || true )"
+exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
+printlog "DEPNotify install result: $exitStatus"
+
+itemName=""
+errorLabels=""
+((countLabels++))
+((countLabels--))
+printlog "$countLabels labels to install"
+
+startDEPNotify
+
+for item in "${items[@]}"; do
+ # Check if DEPNotify is running and try open it if not
+ if ! pgrep -xq "DEPNotify"; then
+ startDEPNotify
+ fi
+ itemName=$( ${destFile} ${item} RETURN_LABEL_NAME=1 LOGGING=REQ INSTALL=force | tail -1 || true )
+ if [[ "$itemName" != "#" ]]; then
+ depnotify_command "Status: $itemName installing…"
+ else
+ depnotify_command "Status: $item installing…"
+ fi
+ printlog "$item $itemName"
+ cmdOutput="$( ${destFile} ${item} LOGO=$LOGO ${installomatorOptions} || true )"
+ #cmdOutput="2022-05-19 13:20:45 : REQ : installomator : ################## End Installomator, exit code 0"
+ exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
+ if [[ ${exitStatus} -eq 0 ]] ; then
+ printlog "${item} succesfully installed."
+ warnOutput="$( echo "${cmdOutput}" | grep --binary-files=text "WARN" || true )"
+ printlog "$warnOutput"
+ else
+ printlog "Error installing ${item}. Exit code ${exitStatus}"
+ #printlog "$cmdOutput"
+ errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
+ printlog "$errorOutput"
+ ((errorCount++))
+ errorLabels="$errorLabels ${item}"
+ fi
+ ((countLabels--))
+ itemName=""
+done
+
+# Mark: Finishing
+# Prevent re-run of script if conditionFile is set
+if [[ ! -z "$conditionFile" ]]; then
+ printlog "Touching condition file so script will not run again"
+ touch "$conditionFile" || true
+ printlog "$(ls -al "$conditionFile" || true)"
+fi
+
+# Show error to user if any
+printlog "Errors: $errorCount"
+if [[ $errorCount -ne 0 ]]; then
+ errorMessage="${errorMessage} Total errors: $errorCount"
+ message="$errorMessage"
+ displayDialog &
+ endMessage="$message"
+ printlog "errorLabels: $errorLabels"
+fi
+
+depnotify_command "Command: MainText: $endMessage"
+depnotify_command "Command: Quit: $endMessage"
+
+sleep 1
+printlog "Remove $(rm -fv $DEPNOTIFY_LOG || true)"
+
+printlog "Ending"
+caffexit $errorCount
diff --git a/MDM/Installomator 1st SS.sh b/MDM/Installomator 1st SS.sh
new file mode 100755
index 0000000..e017831
--- /dev/null
+++ b/MDM/Installomator 1st SS.sh
@@ -0,0 +1,307 @@
+#!/bin/sh
+
+# Installomator 1st installation (for Self Service deployment)
+instance="" # Name of used instance
+
+LOGO="" # "appstore", "jamf", "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
+
+items=(dialog dockutil microsoftautoupdate supportapp applenyfonts applesfpro applesfmono applesfcompact xink zohoworkdrivetruesync textmate 1password7 wwdc theunarchiver keka microsoftedge microsoftteams microsoftonedrive microsoftoffice365)
+# Remember: dialog dockutil
+
+installomatorOptions="NOTIFY=all BLOCKING_PROCESS_ACTION=prompt_user"
+
+# Error message to user if any occur
+showError="1" # Show error message if 1 (0 if it should not be shown)
+errorMessage="A problem was encountered setting up this Mac. Please contact IT."
+
+######################################################################
+# Installomator 1st for Self Service
+#
+# Installation using Installomator
+# No customization below…
+######################################################################
+# This script can be used to install software using Installomator, where the user activate it in Self Service.
+# Script will display a dialog if any errors happens.
+# Progress is shown in notifications to the user
+######################################################################
+# Other installomatorOptions:
+# LOGGING=REQ
+# LOGGING=DEBUG
+# LOGGING=WARN
+# BLOCKING_PROCESS_ACTION=ignore
+# BLOCKING_PROCESS_ACTION=tell_user
+# BLOCKING_PROCESS_ACTION=tell_user_then_quit
+# BLOCKING_PROCESS_ACTION=prompt_user
+# BLOCKING_PROCESS_ACTION=prompt_user_loop
+# BLOCKING_PROCESS_ACTION=prompt_user_then_kill
+# BLOCKING_PROCESS_ACTION=quit
+# BLOCKING_PROCESS_ACTION=kill
+# NOTIFY=all
+# NOTIFY=success
+# NOTIFY=silent
+# IGNORE_APP_STORE_APPS=yes
+# INSTALL=force
+######################################################################
+#
+# This script made by Søren Theilgaard
+# https://github.com/Theile
+# Twitter and MacAdmins Slack: @theilgaard
+#
+# Some functions and code from Installomator:
+# https://github.com/Installomator/Installomator
+#
+######################################################################
+scriptVersion="9.5"
+# v. 9.5 : 2022-09-21 : change of GitHub download
+# v. 9.4 : 2022-09-14 : Making error message optional. downloadURL can fall back on GitHub API.
+# v. 9.3 : 2022-08-29 : installomatorOptions in quotes and ignore blocking processes. Improved installation with looping if it fails, so it can try again. Improved GitHub handling. ws1 support.
+# v. 9.2.2 : 2022-06-17 : installomatorOptions introduced. Check 1.1.1.1 for internet connection.
+# v. 9.2.1 : 2022-05-30 : Some changes to logging
+# v. 9.2 : 2022-05-19 : Built in installer for Installomator, and display dialog if error happens. Now universal script for all supported MDMs based on LOGO variable.
+######################################################################
+
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+# Check before running
+case $LOGO in
+ addigy|microsoft)
+ conditionFile="/var/db/.Installomator1stDone"
+ # Addigy and Microsoft Endpoint Manager (Intune) need a check for a touched file
+ if [ -e "$conditionFile" ]; then
+ echo "$LOGO setup detected"
+ echo "$conditionFile exists, so we exit."
+ exit 0
+ else
+ echo "$conditionFile not found, so we continue…"
+ fi
+ ;;
+esac
+
+# Mark: Constants, logging and caffeinate
+log_message="$instance: Installomator 1st, v$scriptVersion"
+label="1st-v$scriptVersion"
+
+log_location="/private/var/log/Installomator.log"
+printlog(){
+ timestamp=$(date +%F\ %T)
+ if [[ "$(whoami)" == "root" ]]; then
+ echo "$timestamp :: $label : $1" | tee -a $log_location
+ else
+ echo "$timestamp :: $label : $1"
+ fi
+}
+printlog "[LOG-BEGIN] ${log_message}"
+
+# Internet check
+if [[ "$(nc -z -v -G 10 1.1.1.1 53 2>&1 | grep -io "succeeded")" != "succeeded" ]]; then
+ printlog "ERROR. No internet connection, we cannot continue."
+ caffexit 90
+fi
+
+# No sleeping
+/usr/bin/caffeinate -d -i -m -u &
+caffeinatepid=$!
+caffexit () {
+ kill "$caffeinatepid" || true
+ pkill caffeinate || true
+ printlog "[LOG-END] Status $1"
+ exit $1
+}
+
+# Counters
+errorCount=0
+countLabels=${#items[@]}
+printlog "Total installations: $countLabels"
+
+# Using LOGO variable to specify MDM and shown logo
+case $LOGO in
+ appstore)
+ # Apple App Store on Mac
+ if [[ $(sw_vers -buildVersion) > "19" ]]; then
+ LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ else
+ LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ fi
+ ;;
+ jamf)
+ # Jamf Pro
+ LOGO_PATH="/Library/Application Support/JAMF/Jamf.app/Contents/Resources/AppIcon.icns"
+ ;;
+ mosyleb)
+ # Mosyle Business
+ LOGO_PATH="/Applications/Self-Service.app/Contents/Resources/AppIcon.icns"
+ ;;
+ mosylem)
+ # Mosyle Manager (education)
+ LOGO_PATH="/Applications/Manager.app/Contents/Resources/AppIcon.icns"
+ ;;
+ addigy)
+ # Addigy
+ LOGO_PATH="/Library/Addigy/macmanage/MacManage.app/Contents/Resources/atom.icns"
+ ;;
+ microsoft)
+ # Microsoft Endpoint Manager (Intune)
+ LOGO_PATH="/Library/Intune/Microsoft Intune Agent.app/Contents/Resources/AppIcon.icns"
+ ;;
+ ws1)
+ # Workspace ONE (AirWatch)
+ LOGO="/Applications/Workspace ONE Intelligent Hub.app/Contents/Resources/AppIcon.icns"
+ ;;
+esac
+if [[ ! -a "${LOGO_PATH}" ]]; then
+ printlog "ERROR in LOGO_PATH '${LOGO_PATH}', setting Mac App Store."
+ if [[ $(/usr/bin/sw_vers -buildVersion) > "19" ]]; then
+ LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ else
+ LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ fi
+fi
+printlog "LOGO: $LOGO – LOGO_PATH: $LOGO_PATH"
+
+# Mark: Functions
+# Notify the user using AppleScript
+function displayDialog(){
+ currentUser="$(stat -f "%Su" /dev/console)"
+ currentUserID=$(id -u "$currentUser")
+ if [[ "$currentUser" != "" ]]; then
+ launchctl asuser $currentUserID sudo -u $currentUser osascript -e "button returned of (display dialog \"$message\" buttons {\"OK\"} default button \"OK\" with icon POSIX file \"$LOGO_PATH\")" || true
+ fi
+}
+
+# Mark: Code
+name="Installomator"
+printlog "$name check for installation"
+# download URL, version and Expected Team ID
+# Method for GitHub pkg
+gitusername="Installomator"
+gitreponame="Installomator"
+#printlog "$gitusername $gitreponame"
+filetype="pkg"
+#downloadURL="https://github.com$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
+downloadURL="https://github.com$(curl -sfL "$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "expanded_assets" | head -1)" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
+if [[ "$(echo $downloadURL | grep -ioE "https.*.$filetype")" == "" ]]; then
+ printlog "Trying GitHub API for download URL."
+ downloadURL=$(curl -sfL "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | awk -F '"' "/browser_download_url/ && /$filetype\"/ { print \$4; exit }")
+fi
+#printlog "$downloadURL"
+appNewVersion=$(curl -sLI "https://github.com/$gitusername/$gitreponame/releases/latest" | grep -i "^location" | tr "/" "\n" | tail -1 | sed 's/[^0-9\.]//g')
+#printlog "$appNewVersion"
+expectedTeamID="JME5BW3F3R"
+
+destFile="/usr/local/Installomator/Installomator.sh"
+currentInstalledVersion="$(${destFile} version 2>/dev/null || true)"
+printlog "${destFile} version: $currentInstalledVersion"
+if [[ ! -e "${destFile}" || "$currentInstalledVersion" != "$appNewVersion" ]]; then
+ printlog "$name not found or version not latest."
+ printlog "${destFile}"
+ printlog "Installing version ${appNewVersion} ..."
+ # Create temporary working directory
+ tmpDir="$(mktemp -d || true)"
+ printlog "Created working directory '$tmpDir'"
+ # Download the installer package
+ printlog "Downloading $name package version $appNewVersion from: $downloadURL"
+ installationCount=0
+ exitCode=9
+ while [[ $installationCount -lt 3 && $exitCode -gt 0 ]]; do
+ curlDownload=$(curl -Ls "$downloadURL" -o "$tmpDir/$name.pkg" || true)
+ curlDownloadStatus=$(echo $?)
+ if [[ $curlDownloadStatus -ne 0 ]]; then
+ printlog "error downloading $downloadURL, with status $curlDownloadStatus"
+ printlog "${curlDownload}"
+ exitCode=1
+ else
+ printlog "Download $name succes."
+ # Verify the download
+ teamID=$(spctl -a -vv -t install "$tmpDir/$name.pkg" 2>&1 | awk '/origin=/ {print $NF }' | tr -d '()' || true)
+ printlog "Team ID for downloaded package: $teamID"
+ # Install the package if Team ID validates
+ if [ "$expectedTeamID" = "$teamID" ] || [ "$expectedTeamID" = "" ]; then
+ printlog "$name package verified. Installing package '$tmpDir/$name.pkg'."
+ pkgInstall=$(installer -verbose -dumplog -pkg "$tmpDir/$name.pkg" -target "/" 2>&1)
+ pkgInstallStatus=$(echo $?)
+ if [[ $pkgInstallStatus -ne 0 ]]; then
+ printlog "ERROR. $name package installation failed."
+ printlog "${pkgInstall}"
+ exitCode=2
+ else
+ printlog "Installing $name package succes."
+ exitCode=0
+ fi
+ else
+ printlog "ERROR. Package verification failed for $name before package installation could start. Download link may be invalid."
+ exitCode=3
+ fi
+ fi
+ ((installationCount++))
+ printlog "$installationCount time(s), exitCode $exitCode"
+ if [[ $installationCount -lt 3 ]]; then
+ if [[ $exitCode -gt 0 ]]; then
+ printlog "Sleep a bit before trying download and install again. $installationCount time(s)."
+ printlog "Remove $(rm -fv "$tmpDir/$name.pkg" || true)"
+ sleep 2
+ fi
+ else
+ printlog "Download and install of $name succes."
+ fi
+ done
+ # Remove the temporary working directory
+ printlog "Deleting working directory '$tmpDir' and its contents."
+ printlog "Remove $(rm -Rfv "${tmpDir}" || true)"
+ # Handle installation errors
+ if [[ $exitCode != 0 ]]; then
+ printlog "ERROR. Installation of $name failed. Aborting."
+ caffexit $exitCode
+ else
+ printlog "$name version $appNewVersion installed!"
+ fi
+else
+ printlog "$name version $appNewVersion already found. Perfect!"
+fi
+
+errorLabels=""
+((countLabels++))
+((countLabels--))
+printlog "$countLabels labels to install"
+
+for item in "${items[@]}"; do
+ printlog "$item"
+ cmdOutput="$( ${destFile} ${item} LOGO=$LOGO ${installomatorOptions} || true )"
+ exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
+ if [[ ${exitStatus} -eq 0 ]] ; then
+ printlog "${item} succesfully installed."
+ warnOutput="$( echo "${cmdOutput}" | grep --binary-files=text "WARN" || true )"
+ printlog "$warnOutput"
+ else
+ printlog "Error installing ${item}. Exit code ${exitStatus}"
+ #printlog "$cmdOutput"
+ errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
+ printlog "$errorOutput"
+ ((errorCount++))
+ errorLabels="$errorLabels ${item}"
+ fi
+ ((countLabels--))
+ itemName=""
+done
+
+# Mark: Finishing
+# Prevent re-run of script if conditionFile is set
+if [[ ! -z "$conditionFile" ]]; then
+ printlog "Touching condition file so script will not run again"
+ touch "$conditionFile" || true
+ printlog "$(ls -al "$conditionFile" || true)"
+fi
+
+# Show error to user if any
+printlog "Errors: $errorCount"
+if [[ $errorCount -ne 0 ]]; then
+ printlog "ERROR: Display error dialog to user!"
+ errorMessage="${errorMessage} Total errors: $errorCount"
+ if [[ $showError -eq 1 ]]; then
+ message="$errorMessage"
+ displayDialog &
+ fi
+ printlog "errorLabels: $errorLabels"
+fi
+
+printlog "Ending"
+caffexit $errorCount
diff --git a/MDM/Installomator 1st condition.sh b/MDM/Installomator 1st condition.sh
new file mode 100644
index 0000000..95b9806
--- /dev/null
+++ b/MDM/Installomator 1st condition.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+# Mark: Addigy Condition on condition file
+# Install on success
+
+conditionFile="/var/db/.Installomator1stDone"
+if [ -e "$conditionFile" ]; then
+ echo "$conditionFile exists. Exiting."
+ exit 1
+else
+ echo "$conditionFile not found. Continue…"
+ exit 0
+fi
diff --git a/MDM/Installomator 1st prevention.sh b/MDM/Installomator 1st prevention.sh
new file mode 100644
index 0000000..b4658d9
--- /dev/null
+++ b/MDM/Installomator 1st prevention.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+# PREVENT Installomator 1st Auto-install from running
+
+# DESCRIPTION
+# Will create the file to prevent Installomator 1st Auto-install from running.
+# Only for MDM solutions (like Addigy and Microsoft) that have conditions for runnning scripts and do not offer an enrollment event for runnning the script.
+# By runninng this script, the file will be created on the client, that will prevent Installomator 1st Auto-install from runnning.
+# This is a great help for implementing Installomator 1st Auto-install in a running solution, where the command below have to be run on currently enrolled devices, and then Installomator 1st Auto-install can be assigned to all machines, and will run only on newly enrolled devices.
+
+/usr/bin/touch "/var/db/.Installomator1stDone"
diff --git a/MDM/Installomator update.sh b/MDM/Installomator update.sh
deleted file mode 100755
index 5b6bb67..0000000
--- a/MDM/Installomator update.sh
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/bin/bash
-# Updating Installomator
-# Usefull to push out after deployment if earlier version was deployed in DEP profile
-
-what="installomator" # enter the software to install
-LOGO="appstore" # or "addigy", "microsoft", "mosyleb", "mosylem"
-
-# Verify that Installomator has been installed
-destFile="/usr/local/Installomator/Installomator.sh"
-if [ ! -e "${destFile}" ]; then
- echo "Installomator not found here:"
- echo "${destFile}"
- echo "Exiting."
- exit 99
-fi
-
-# No sleeping
-/usr/bin/caffeinate -d -i -m -u &
-caffeinatepid=$!
-caffexit () {
- kill "$caffeinatepid"
- pkill caffeinate
- exit $1
-}
-
-# Install software using Installomator
-cmdOutput="$(${destFile} ${what} LOGO=$LOGO BLOCKING_PROCESS_ACTION=ignore NOTIFY=silent LOGGING=req || true)"
-
-# Check result
-exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
-if [[ ${exitStatus} -eq 0 ]] ; then
- echo -e "${what} succesfully installed.\n"
-else
- echo -e "Error installing ${what}. Exit code ${exitStatus}\n"
- #echo "$cmdOutput"
- errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
- echo "$errorOutput"
- caffexit $exitStatus
-fi
-
-echo "[$(DATE)][LOG-END]"
-caffexit 0
diff --git a/MDM/Jamf/00_PrepareInstall_SwiftDialog.sh b/MDM/Jamf/00_PrepareInstall_SwiftDialog.sh
new file mode 100755
index 0000000..84a1212
--- /dev/null
+++ b/MDM/Jamf/00_PrepareInstall_SwiftDialog.sh
@@ -0,0 +1,160 @@
+#!/bin/zsh
+
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+# MARK: Arguments/Parameters
+
+# Parameter 4: path to the swiftDialog command file
+dialog_command_file=${4:-"/var/tmp/dialog.log"}
+
+# Parameter 5: message displayed over the progress bar
+message=${5:-"Self Service Progress"}
+
+# Parameter 6: path or URL to an icon
+icon=${6:-"/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"}
+# see Dan Snelson's advice on how to get a URL to an icon in Self Service
+# https://rumble.com/v119x6y-harvesting-self-service-icons.html
+
+# MARK: Constants
+
+dialogApp="/Library/Application Support/Dialog/Dialog.app"
+
+# MARK: Functions
+
+dialogUpdate() {
+ # $1: dialog command
+ local dcommand="$1"
+
+ if [[ -n $dialog_command_file ]]; then
+ echo "$dcommand" >> "$dialog_command_file"
+ echo "Dialog: $dcommand"
+ fi
+}
+
+# MARK: sanity checks
+
+# check minimal macOS requirement
+if [[ $(sw_vers -buildVersion ) < "20A" ]]; then
+ echo "This script requires at least macOS 11 Big Sur."
+ exit 98
+fi
+
+# check we are running as root
+if [[ $DEBUG -eq 0 && $(id -u) -ne 0 ]]; then
+ echo "This script should be run as root"
+ exit 97
+fi
+
+# swiftDialog installation
+name="Dialog"
+echo "$name check for installation"
+# download URL, version and Expected Team ID
+# Method for GitHub pkg w. app version check
+gitusername="bartreardon"
+gitreponame="swiftDialog"
+#echo "$gitusername $gitreponame"
+filetype="pkg"
+#downloadURL="https://github.com$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
+downloadURL="https://github.com$(curl -sfL "$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "expanded_assets" | head -1)" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
+if [[ "$(echo $downloadURL | grep -ioE "https.*.$filetype")" == "" ]]; then
+ echo "Trying GitHub API for download URL."
+ downloadURL=$(curl -sfL "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | awk -F '"' "/browser_download_url/ && /$filetype\"/ { print \$4; exit }")
+fi
+#echo "$downloadURL"
+appNewVersion=$(curl -sLI "https://github.com/$gitusername/$gitreponame/releases/latest" | grep -i "^location" | tr "/" "\n" | tail -1 | sed 's/[^0-9\.]//g')
+#echo "$appNewVersion"
+expectedTeamID="PWA5E9TQ59"
+destFile="/Library/Application Support/Dialog/Dialog.app"
+versionKey="CFBundleShortVersionString" #CFBundleVersion
+
+currentInstalledVersion="$(defaults read "${destFile}/Contents/Info.plist" $versionKey || true)"
+echo "${name} version: $currentInstalledVersion"
+if [[ ! -e "${destFile}" || "$currentInstalledVersion" != "$appNewVersion" ]]; then
+ echo "$name not found or version not latest."
+ echo "${destFile}"
+ echo "Installing version ${appNewVersion}…"
+ # Create temporary working directory
+ tmpDir="$(mktemp -d || true)"
+ echo "Created working directory '$tmpDir'"
+ # Download the installer package
+ echo "Downloading $name package version $appNewVersion from: $downloadURL"
+ installationCount=0
+ exitCode=9
+ while [[ $installationCount -lt 3 && $exitCode -gt 0 ]]; do
+ curlDownload=$(curl -Ls "$downloadURL" -o "$tmpDir/$name.pkg" || true)
+ curlDownloadStatus=$(echo $?)
+ if [[ $curlDownloadStatus -ne 0 ]]; then
+ echo "error downloading $downloadURL, with status $curlDownloadStatus"
+ echo "${curlDownload}"
+ exitCode=1
+ else
+ echo "Download $name succes."
+ # Verify the download
+ teamID=$(spctl -a -vv -t install "$tmpDir/$name.pkg" 2>&1 | awk '/origin=/ {print $NF }' | tr -d '()' || true)
+ echo "Team ID for downloaded package: $teamID"
+ # Install the package if Team ID validates
+ if [ "$expectedTeamID" = "$teamID" ] || [ "$expectedTeamID" = "" ]; then
+ echo "$name package verified. Installing package '$tmpDir/$name.pkg'."
+ pkgInstall=$(installer -verbose -dumplog -pkg "$tmpDir/$name.pkg" -target "/" 2>&1)
+ pkgInstallStatus=$(echo $?)
+ if [[ $pkgInstallStatus -ne 0 ]]; then
+ echo "ERROR. $name package installation failed."
+ echo "${pkgInstall}"
+ exitCode=2
+ else
+ echo "Installing $name package succes."
+ exitCode=0
+ fi
+ else
+ echo "ERROR. Package verification failed for $name before package installation could start. Download link may be invalid."
+ exitCode=3
+ fi
+ fi
+ ((installationCount++))
+ echo "$installationCount time(s), exitCode $exitCode"
+ if [[ $installationCount -lt 3 ]]; then
+ if [[ $exitCode -gt 0 ]]; then
+ echo "Sleep a bit before trying download and install again. $installationCount time(s)."
+ echo "Remove $(rm -fv "$tmpDir/$name.pkg" || true)"
+ sleep 2
+ fi
+ else
+ echo "Download and install of $name succes."
+ fi
+ done
+ # Remove the temporary working directory
+ echo "Deleting working directory '$tmpDir' and its contents."
+ echo "Remove $(rm -Rfv "${tmpDir}" || true)"
+ # Handle installation errors
+ if [[ $exitCode != 0 ]]; then
+ echo "ERROR. Installation of $name failed. Aborting."
+ caffexit $exitCode
+ else
+ echo "$name version $appNewVersion installed!"
+ fi
+else
+ echo "$name version $appNewVersion already found. Perfect!"
+fi
+
+# check for Swift Dialog
+if [[ ! -d $dialogApp ]]; then
+ echo "Cannot find dialog at $dialogApp"
+ exit 95
+fi
+
+
+# MARK: Configure and display swiftDialog
+
+# display first screen
+open -a "$dialogApp" --args \
+ --title none \
+ --icon "$icon" \
+ --message "$message" \
+ --mini \
+ --progress 100 \
+ --position bottomright \
+ --movable \
+ --commandfile "$dialog_command_file"
+
+# give everything a moment to catch up
+sleep 0.1
diff --git a/MDM/Jamf/00_Prepare_SwiftDialog.sh b/MDM/Jamf/00_Prepare_SwiftDialog.sh
new file mode 100755
index 0000000..74213ec
--- /dev/null
+++ b/MDM/Jamf/00_Prepare_SwiftDialog.sh
@@ -0,0 +1,69 @@
+#!/bin/zsh
+
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+# MARK: Arguments/Parameters
+
+# Parameter 4: path to the swiftDialog command file
+dialog_command_file=${4:-"/var/tmp/dialog.log"}
+
+# Parameter 5: message displayed over the progress bar
+message=${5:-"Self Service Progress"}
+
+# Parameter 6: path or URL to an icon
+icon=${6:-"/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"}
+# see Dan Snelson's advice on how to get a URL to an icon in Self Service
+# https://rumble.com/v119x6y-harvesting-self-service-icons.html
+
+# MARK: Constants
+
+dialogApp="/Library/Application Support/Dialog/Dialog.app"
+
+# MARK: Functions
+
+dialogUpdate() {
+ # $1: dialog command
+ local dcommand="$1"
+
+ if [[ -n $dialog_command_file ]]; then
+ echo "$dcommand" >> "$dialog_command_file"
+ echo "Dialog: $dcommand"
+ fi
+}
+
+# MARK: sanity checks
+
+# check minimal macOS requirement
+if [[ $(sw_vers -buildVersion ) < "20A" ]]; then
+ echo "This script requires at least macOS 11 Big Sur."
+ exit 98
+fi
+
+# check we are running as root
+if [[ $DEBUG -eq 0 && $(id -u) -ne 0 ]]; then
+ echo "This script should be run as root"
+ exit 97
+fi
+
+# check for Swift Dialog
+if [[ ! -d $dialogApp ]]; then
+ echo "Cannot find dialog at $dialogApp"
+ exit 95
+fi
+
+
+# MARK: Configure and display swiftDialog
+
+# display first screen
+open -a "$dialogApp" --args \
+ --title none \
+ --icon "$icon" \
+ --message "$message" \
+ --mini \
+ --progress 100 \
+ --position bottomright \
+ --movable \
+ --commandfile "$dialog_command_file"
+
+# give everything a moment to catch up
+sleep 0.1
diff --git a/MDM/Jamf/ReadMe.md b/MDM/Jamf/ReadMe.md
new file mode 100644
index 0000000..e9cf769
--- /dev/null
+++ b/MDM/Jamf/ReadMe.md
@@ -0,0 +1,48 @@
+# Display Installomator Progress with SwiftDialog in Jamf
+
+Installomator 10 has functionality to communicate with [Bart Reardon's swiftDialog](https://github.com/bartreardon/swiftDialog). When you set the `DIALOG_CMD_FILE` variable Installomator will write progress for downloads and installation (with pkgs) to the command file which allows swiftDialog to display the progress.
+
+However, you have to launch and setup swiftDialog to display a window with a progress bar before Installomator launches and also make sure swiftDialog quits after Installomator has run. This may seem complex at first but allows to configure swiftDialog just for your case without needing to modify the Installomator script.
+
+Here are some example script that would run before and after Installomator to display a swiftDialog window and quit the process after. Since Jamf Pro executes scripts in alphanumerical order, the names are chosen accordingly, to ensure proper order.
+
+## Setup in Jamf Pro
+
+To show Installomator progress with swiftDialog from a Jamf Policy, you require three scripts:
+
+- `00_Prepare_SwiftDialog.sh`: Configures and displays the swiftDialog window
+- `Installomator.sh`: (v10 or higher)
+- `zz_Quit_SwiftDialog.sh`: quits swiftDialog
+
+Add these three scripts to your Jamf Pro and create a policy with these three scripts. The names are chosen that the script appear in the correct order. If you rename the scripts in Jamf Pro, this may disrupt the order and the workflow will not work anymore. The "Priority" of the scripts in the policy should all be the same value.
+
+The different scripts require a set of parameters. We will use the `googlechromepkg` label as an example.
+
+`00_Prepare_SwiftDialog.sh`
+
+Parameter 4: `/var/tmp/dialog.log` (Path to the swiftDialog command file)
+
+Parameter 5: `Installing Google Chrome...` (text shown in the swiftDialog window above the progress bar)
+
+Parameter 6: Path to or URL for an icon in swiftDialog. This can be a path on the client or a URL. See Dan Snelson's advice on how to get icon URLs for Self Service icons: https://rumble.com/v119x6y-harvesting-self-service-icons.html
+
+`Installomator.sh`
+
+Parameter 4: `googlechromepkg` (the label to install)
+
+Parameter 5: `DIALOG_CMD_FILE=/var/tmp/dialog.log` (the swiftDialog command file, this has to be the same value as parameter 4 in the previous script)
+
+Parameter 6: `NOTIFY=silent` (disable Installomator notifications, optional)
+
+You can add more configurations to the Installomator script when needed.
+
+`zz_Quit_SwiftDialog`
+
+Parameter 4: `/var/tmp/dialog.log` (the swiftDialog command file, this has to be the same value as parameter 4 in the first script)
+
+Then setup the remainder of the Jamf Policy to your needs. This works best with Self Service policies.
+
+When you run the policy, the first script will configure and display swiftDialog. Installomator.sh will download and install the app while writing the proper update commands to the file set in `DIALOG_CMD_FILE`. The final script will quit swiftDialog.
+
+
+
diff --git a/MDM/Jamf/SelfServiceProgress.png b/MDM/Jamf/SelfServiceProgress.png
new file mode 100644
index 0000000..1ab305f
Binary files /dev/null and b/MDM/Jamf/SelfServiceProgress.png differ
diff --git a/MDM/Jamf/zz_Quit_SwiftDialog.sh b/MDM/Jamf/zz_Quit_SwiftDialog.sh
new file mode 100755
index 0000000..b899e1e
--- /dev/null
+++ b/MDM/Jamf/zz_Quit_SwiftDialog.sh
@@ -0,0 +1,57 @@
+#!/bin/zsh
+
+# MARK: Arguments/Parameters
+
+# Parameter 4: path to the swiftDialog command file
+dialog_command_file=${4:-"/var/tmp/dialog.log"}
+
+# MARK: Constants
+dialogApp="/Library/Application Support/Dialog/Dialog.app"
+
+dialogUpdate() {
+ # $1: dialog command
+ local dcommand="$1"
+
+ if [[ -n $dialog_command_file ]]; then
+ echo "$dcommand" >> "$dialog_command_file"
+ echo "Dialog: $dcommand"
+ fi
+}
+
+# check minimal macOS requirement
+if [[ $(sw_vers -buildVersion ) < "20A" ]]; then
+ echo "This script requires at least macOS 11 Big Sur."
+ exit 98
+fi
+
+# check we are running as root
+if [[ $DEBUG -eq 0 && $(id -u) -ne 0 ]]; then
+ echo "This script should be run as root"
+ exit 97
+fi
+
+# check for Swift Dialog
+if [[ ! -d $dialogApp ]]; then
+ echo "Cannot find dialog at $dialogApp"
+ exit 95
+fi
+
+
+# close and quit dialog
+dialogUpdate "progress: complete"
+dialogUpdate "progresstext: Done"
+
+# pause a moment
+sleep 0.5
+
+dialogUpdate "quit:"
+
+# let everything catch up
+sleep 0.5
+
+# just to be safe
+killall "Dialog"
+
+# the killall command above will return error when Dialog is already quit
+# but we don't want that to register as a failure in Jamf, so always exit 0
+exit 0
diff --git a/MDM/MDMAddigy CustomSoftware.sh b/MDM/MDMAddigy CustomSoftware.sh
deleted file mode 100755
index e7918fd..0000000
--- a/MDM/MDMAddigy CustomSoftware.sh
+++ /dev/null
@@ -1,115 +0,0 @@
-#!/bin/zsh
-
-# Specific settings in Addigy to configure Custom Software for installomator.
-# Addigy has 3 parts to fill out for this, Installation script, Condition, and Removal steps (see RemoveInstallomator.sh).
-
-# Mark: Installation script
-# Just click “Add” to autogenerate the installer script line by clicking the “Add”-button next to the Installer PKG, replace with first line below
-/usr/sbin/installer -pkg "/Library/Addigy/ansible/packages/Installomator (9.1.0)/Installomator-9.1.pkg" -target /
-
-# Installation using Installomator
-whatList="supportapp xink textmate microsoftedge wwdc keka vlc " # enter the software to installed separated with spaces
-
-# To be used as a script sent out from a MDM.
-# Fill the variable "whatList" above with labels separated by space " ".
-# Script will loop through these labels and exit with number of errors.
-######################################################################
-# Parameters for reinstall/initial install (owner root:wheel):
-# "BLOCKING_PROCESS_ACTION=quit_kill INSTALL=force IGNORE_APP_STORE_APPS=yes SYSTEMOWNER=1"
-# Parameters for Self Service installed app:
-# "BLOCKING_PROCESS_ACTION=prompt_user NOTIFY=all"
-# Parameters for security important apps, like browsers (run automaticaly every day):
-# "BLOCKING_PROCESS_ACTION=tell_user_then_kill"
-# Update of service apps (run automatically):
-# "BLOCKING_PROCESS_ACTION=quit_kill NOTIFY=silent"
-parameters="BLOCKING_PROCESS_ACTION=quit_kill INSTALL=force IGNORE_APP_STORE_APPS=yes"
-######################################################################
-
-# Verify that Installomator has been installed
-destFile="/usr/local/Installomator/Installomator.sh"
-if [ ! -e "${destFile}" ]; then
- echo "Installomator not found here:"
- echo "${destFile}"
- echo "Exiting."
- exit 99
-fi
-
-# No sleeping
-/usr/bin/caffeinate -d -i -m -u &
-caffeinatepid=$!
-caffexit () {
- kill "$caffeinatepid"
- pkill caffeinate
- exit $1
-}
-
-# Count errors
-errorCount=0
-
-for what in $whatList; do
- #echo $what
- # Install software using Installomator
- cmdOutput="$(${destFile} ${what} LOGO=addigy $parameters || true)"
- # Check result
- exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
- if [[ ${exitStatus} -ne 0 ]] ; then
- echo -e "Error installing ${what}. Exit code ${exitStatus}"
- #echo "$cmdOutput"
- errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
- echo "$errorOutput"
- let errorCount++
- fi
-done
-
-echo
-echo "Errors: $errorCount"
-echo "[$(DATE)][LOG-END]"
-
-caffexit $errorCount
-
-# Mark: Conditions
-# Install on success
-# Remember to fill out the correct “TARGET_VERSION” and “PKG_ID”, and click "Install on succes".
-PKG_ID="com.scriptingosx.Installomator"
-TARGET_VERSION="9.1"
-
-vercomp () {
- if [[ $1 == $2 ]]; then
- return 0
- fi
- local IFS=.
- local i ver1=($1) ver2=($2)
- # fill empty fields in ver1 with zeros
- for ((i=${#ver1[@]}; i<${#ver2[@]}; i++)); do
- ver1[i]=0
- done
- for ((i=0; i<${#ver1[@]}; i++)); do
- if [[ -z ${ver2[i]} ]]; then
- # fill empty fields in ver2 with zeros
- ver2[i]=0
- fi
- if ((10#${ver1[i]} > 10#${ver2[i]})); then
- return 1
- fi
- if ((10#${ver1[i]} < 10#${ver2[i]})); then
- return 2
- fi
- done
- return 0
-}
-
-INSTALLED_VERSION="$(pkgutil --pkg-info $PKG_ID | grep -i "^version" | awk '{print $2}')"
-
-echo "Current Version: ${INSTALLED_VERSION}"
-
-vercomp ${TARGET_VERSION} ${INSTALLED_VERSION}
-COMP=$? # 0 means the same, 1 means TARGET is newer, 2 means INSTALLED is newer
-echo "COMPARISON: ${COMP}"
-
-if [ "${COMP}" -eq 1 ]; then
- echo "Installed version is older than ${TARGET_VERSION}."
- exit 0
-else
- echo "Installed version is the same or newer than ${TARGET_VERSION}."
- exit 1
-fi
diff --git a/MDM/MDMMosyle install.sh b/MDM/MDMMosyle install.sh
deleted file mode 100644
index 27f9d8d..0000000
--- a/MDM/MDMMosyle install.sh
+++ /dev/null
@@ -1,79 +0,0 @@
-PKG_ID="com.scriptingosx.Installomator"
-TARGET_VERSION="9.1"
-URLDOWNLOAD="%MosyleCDNFile:blah-blah-blah%"
-######################################################################
-# Installation using Installomator (enter the software to install separated with spaces in the "whatList"-variable)
-whatList="handbrake theunarchiver microsoftoffice365"
-# Covered by Mosyle Catalog: "brave firefox googlechrome microsoftedge microsoftteams signal sublimetext vlc webex zoom" among others
-LOGO="mosyleb" # or "mosylem"
-######################################################################
-
-## Mark: Code here
-
-# No sleeping
-/usr/bin/caffeinate -d -i -m -u &
-caffeinatepid=$!
-caffexit () {
- kill "$caffeinatepid"
- pkill caffeinate
- exit $1
-}
-
-# Mark: Condition for Installomator installation
-
-INSTALLED_VERSION="$(pkgutil --pkg-info $PKG_ID 2>/dev/null | grep -i "^version" | awk '{print $2}')"
-
-echo "Current Version: ${INSTALLED_VERSION}"
-
-if [[ "$TARGET_VERSION" != "$INSTALLED_VERSION" ]]; then
- TMPDIR=$(mktemp -d )
- if ! cd "$TMPDIR"; then
- echo "error changing directory $TMPDIR"
- caffexit 98
- fi
- NAME=$TMPDIR/$(date +%s).pkg
- if ! curl -fsL "$URLDOWNLOAD" -o "$NAME"; then
- echo "error downloading $URLDOWNLOAD to $NAME."
- caffexit 97
- fi
- installer -pkg "$NAME" -target /
- rm -rf "$TMPDIR"
-else
- echo "Installomator version $INSTALLED_VERSION already installed!"
-fi
-
-
-# Mark: Start Installomator label(s) installation
-
-# Count errors
-errorCount=0
-
-# Verify that Installomator has been installed
-destFile="/usr/local/Installomator/Installomator.sh"
-if [ ! -e "${destFile}" ]; then
- echo "Installomator not found here:"
- echo "${destFile}"
- echo "Exiting."
- caffexit 99
-fi
-
-for what in $whatList; do
- #echo $item
- # Install software using Installomator
- cmdOutput="$(${destFile} ${what} LOGO=$LOGO NOTIFY=all BLOCKING_PROCESS_ACTION=tell_user || true)" # NOTIFY=silent BLOCKING_PROCESS_ACTION=quit_kill INSTALL=force
- # Check result
- exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
- if [[ ${exitStatus} -ne 0 ]] ; then
- echo "Error installing ${what}. Exit code ${exitStatus}"
- #echo "$cmdOutput"
- errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
- echo "$errorOutput"
- let errorCount++
- fi
-done
-
-echo
-echo "Errors: $errorCount"
-echo "[$(DATE)][LOG-END]"
-
-caffexit $errorCount
diff --git a/MDM/Manual valuesfromarguments.sh b/MDM/Manual valuesfromarguments.sh
deleted file mode 100755
index ee80291..0000000
--- a/MDM/Manual valuesfromarguments.sh
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/bin/bash
-# Software
-
-# Installation using Installomator
-# Example of installing software using valuesfromarguments to install a custom software
-
-LOGO="appstore" # or "addigy", "microsoft", "mosyleb", "mosylem"
-###############################################
-
-# Verify that Installomator has been installed
-destFile="/usr/local/Installomator/Installomator.sh"
-if [ ! -e "${destFile}" ]; then
- echo "Installomator not found here:"
- echo "${destFile}"
- echo "Exiting."
- exit 99
-fi
-
-# No sleeping
-/usr/bin/caffeinate -d -i -m -u &
-caffeinatepid=$!
-caffexit () {
- kill "$caffeinatepid"
- pkill caffeinate
- exit $1
-}
-
-# Variables to calculate
-downloadURL="https://craft-assets.invisionapp.com/CraftManager/production/CraftManager.zip"
-appNewVersion=$(curl -fs https://craft-assets.invisionapp.com/CraftManager/production/appcast.xml | xpath -e '//rss/channel/item[1]/enclosure/@sparkle:shortVersionString' 2>/dev/null | cut -d '"' -f2)
-
-# Install software using Installomator
-cmdOutput="$(${destFile} valuesfromarguments LOGO=$LOGO \
- name=CraftManager \
- type=zip \
- downloadURL=$downloadURL \
- appNewVersion=$appNewVersion \
- expectedTeamID=VRXQSNCL5W \
- BLOCKING_PROCESS_ACTION=prompt_user \
- LOGGING=REQ \
- NOTIFY=all || true)"
-
-# Check result
-exitStatus="$( echo "${cmdOutput}" | grep --binary-files=text -i "exit" | tail -1 | sed -E 's/.*exit code ([0-9]).*/\1/g' || true )"
-if [[ ${exitStatus} -eq 0 ]] ; then
- echo -e "${what} succesfully installed.\n"
-else
- echo -e "Error installing ${what}. Exit code ${exitStatus}\n"
- #printlog "$cmdOutput"
- errorOutput="$( echo "${cmdOutput}" | grep --binary-files=text -i "error" || true )"
- echo "$errorOutput"
- caffexit $exitStatus
-fi
-
-echo "[$(DATE)][LOG-END]"
-caffexit 0
diff --git a/MDM/Progress 1st swiftDialog condition.sh b/MDM/Progress 1st swiftDialog condition.sh
new file mode 100644
index 0000000..63d0055
--- /dev/null
+++ b/MDM/Progress 1st swiftDialog condition.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+# Mark: Addigy Condition on condition file
+# Install on success
+
+conditionFile="/var/db/.Progress1stDone"
+if [ -e "$conditionFile" ]; then
+ echo "$conditionFile exists. Exiting."
+ exit 1
+else
+ echo "$conditionFile not found. Continue…"
+ exit 0
+fi
diff --git a/MDM/Progress 1st swiftDialog prevention.sh b/MDM/Progress 1st swiftDialog prevention.sh
new file mode 100644
index 0000000..bd43e56
--- /dev/null
+++ b/MDM/Progress 1st swiftDialog prevention.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+# PREVENT Progress 1st swiftDialog from running
+
+# DESCRIPTION
+# Will create the file to prevent Progress 1st swiftDialog from running.
+# Only for MDM solutions (like Addigy and Microsoft) that have conditions for runnning scripts and do not offer an enrollment event for runnning the script.
+# By runninng this script, the file will be created on the client, that will prevent Progress 1st swiftDialog from runnning.
+# This is a great help for implementing Progress 1st swiftDialog in a running solution, where the command below have to be run on currently enrolled devices, and then Progress 1st swiftDialog can be assigned to all machines, and will run only on newly enrolled devices.
+
+/usr/bin/touch "/var/db/.Progress1stDone"
diff --git a/MDM/Progress 1st swiftDialog.sh b/MDM/Progress 1st swiftDialog.sh
new file mode 100755
index 0000000..f279d3d
--- /dev/null
+++ b/MDM/Progress 1st swiftDialog.sh
@@ -0,0 +1,397 @@
+#!/bin/sh
+
+# Progress 1st with swiftDialog (auto installation at enrollment)
+instance="" # Name of used instance
+
+LOGO="" # "appstore", "jamf", "mosyleb", "mosylem", "addigy", "microsoft", "ws1"
+
+apps=(
+ "swiftDialog,/usr/local/bin/dialog"
+ "dockutil,/usr/local/bin/dockutil"
+ "desktoppr,/usr/local/bin/desktoppr"
+ "SupportApp,/Applications/Support.app"
+ "Xink,/Applications/Xink.app"
+ "Apple NewYork Font,/Library/Fonts/NewYork.ttf"
+ "Apple SF Pro Font,/Library/Fonts/SF-Pro.ttf"
+ "Apple SF Mono Font,/Library/Fonts/SF-Mono-Bold.otf"
+ "Apple SF Compact Font,/Library/Fonts/SF-Compact.ttf"
+ "Zoho WorkDrive TrueSync,/Applications/Zoho WorkDrive TrueSync.app"
+ "TextMate,/Applications/TextMate.app"
+ "Sublime Text,/Applications/Sublime Text.app"
+ "1Password,/Applications/1Password 7.app"
+ "Mactracker,/Applications/Mactracker.app"
+ "WWDC,/Applications/WWDC.app"
+ "The Unarchiver,/Applications/The Unarchiver.app"
+ "Keka,/Applications/Keka.app"
+ "Brave,/Applications/Brave Browser.app"
+ "Firefox,/Applications/Firefox.app"
+ "Microsoft AutoUpdate,/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app"
+ "Microsoft Edge,/Applications/Microsoft Edge.app"
+ "Microsoft Teams,/Applications/Microsoft Teams.app"
+ "Microsoft Excel,/Applications/Microsoft Excel.app"
+ "Microsoft OneNote,/Applications/Microsoft OneNote.app"
+ "Microsoft Outlook,/Applications/Microsoft Outlook.app"
+ "Microsoft PowerPoint,/Applications/Microsoft PowerPoint.app"
+ "Microsoft Word,/Applications/Microsoft Word.app"
+ "Microsoft OneDrive,/Applications/OneDrive.app"
+)
+
+# Dialog display settings, change as desired
+title="Installing Apps and other software"
+message="Please wait while we download and install the needed software."
+endMessage="Installation complete! Please reboot to activate FileVault."
+displayEndMessageDialog=1 # Should endMessage be shown as a dialog? (0|1)
+errorMessage="A problem was encountered setting up this Mac. Please contact IT."
+
+######################################################################
+# Progress 1st Dialog
+#
+# Showing installation progress using swiftDialog
+# No customization below…
+######################################################################
+# Complete script meant for running via MDM on device enrollment. This will download
+# and install Dialog on the fly before opening Dialog.
+#
+# Log: /private/var/log/InstallationProgress.log
+# This file prevents script from running again on Addigy and Microsoft Endpoint (Intune):
+# "/var/db/.Progress1stDone"
+#
+# Display a Dialog with a list of applications and indicate when they’ve been installed
+# Useful when apps are deployed at random, perhaps without local logging.
+# Applies to Mosyle App Catalog installs, VPP app installs, Installomator installs etc.
+# The script watches the existence of files in the file system, so that is used to show progress.
+#
+# Requires Dialog v1.9.1 or later (will be installed) https://github.com/bartreardon/swiftDialog
+#
+######################################################################
+#
+# This script made by Søren Theilgaard
+# https://github.com/Theile
+# Twitter and MacAdmins Slack: @theilgaard
+#
+# Based on the work by Adam Codega:
+# https://github.com/acodega/dialog-scripts
+#
+# Some functions and code from Installomator:
+# https://github.com/Installomator/Installomator
+#
+######################################################################
+# List of apps/installs to process in “apps” array.
+# Provide the display name as you prefer and the path to the app/file. ex:
+# "Google Chrome,/Applications/Google Chrome.app"
+# A comma separates the display name from the path. Do not use commas in your display name text.
+#
+# Tip: Check for something like print drivers using the pkg receipt, like:
+# "Konica-Minolta drivers,/var/db/receipts/jp.konicaminolta.print.package.C759.plist"
+# Or fonts, like:
+# "Apple SF Pro Font,/Library/Fonts/SF-Pro.ttf"
+######################################################################
+scriptVersion="9.5"
+# v. 9.5 : 2022-09-21 : change of GitHub download
+# v. 9.4 : 2022-09-14 : downloadURL can fall back on GitHub API
+# v. 9.3 : 2022-08-29 : Logging changed for current version. Improved installation with looping if it fails, so it can try again. Improved GitHub handling.
+# v. 9.2.2 : 2022-06-17 : Improved Dialog installation. Check 1.1.1.1 for internet connection.
+# v. 9.2 : 2022-05-19 : Not using GitHub api for download of Dialog, show a dialog when finished to make message more important. Now universal script for all supported MDMs based on LOGO variable.
+# v. 9.0 : 2022-05-16 : Based on acodega’s work, I have added progress bar, changed logging and use another log-location, a bit more error handling for Dialog download, added some "|| true"-endings to some lines to not make them fail in Addigy, and some more.
+######################################################################
+
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+# Check before running
+case $LOGO in
+ addigy|microsoft)
+ conditionFile="/var/db/.Progress1stDone"
+ # Addigy and Microsoft Endpoint Manager (Intune) need a check for a touched file
+ if [ -e "$conditionFile" ]; then
+ echo "$LOGO setup detected"
+ echo "$conditionFile exists, so we exit."
+ exit 0
+ else
+ echo "$conditionFile not found, so we continue…"
+ fi
+ ;;
+esac
+
+# Mark: Constants and logging
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+log_message="$instance: Progress 1st with Dialog, v$scriptVersion"
+label="P1st-v$scriptVersion"
+
+log_location="/private/var/log/Installomator.log"
+function printlog(){
+ timestamp=$(date +%F\ %T)
+ if [[ "$(whoami)" == "root" ]]; then
+ echo "$timestamp :: $label : $1" | tee -a $log_location
+ else
+ echo "$timestamp :: $label : $1"
+ fi
+}
+printlog "[LOG-BEGIN] ${log_message}"
+
+# Internet check
+if [[ "$(nc -z -v -G 10 1.1.1.1 53 2>&1 | grep -io "succeeded")" != "succeeded" ]]; then
+ printlog "ERROR. No internet connection, we cannot continue."
+ exit 90
+fi
+
+# Location of dialog and dialog command file
+dialogApp="/usr/local/bin/dialog"
+dialog_command_file="/var/tmp/dialog.log"
+counterFile="/var/tmp/Progress1st.plist"
+
+# Counters
+progress_index=0
+step_progress=0
+defaults write $counterFile step -int 0
+progress_total=${#apps[@]}
+printlog "Total watched installations: $progress_total"
+
+# Using LOGO variable to specify MDM and shown logo
+case $LOGO in
+ appstore)
+ # Apple App Store on Mac
+ if [[ $(sw_vers -buildVersion) > "19" ]]; then
+ LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ else
+ LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ fi
+ ;;
+ jamf)
+ # Jamf Pro
+ LOGO_PATH="/Library/Application Support/JAMF/Jamf.app/Contents/Resources/AppIcon.icns"
+ ;;
+ mosyleb)
+ # Mosyle Business
+ LOGO_PATH="/Applications/Self-Service.app/Contents/Resources/AppIcon.icns"
+ ;;
+ mosylem)
+ # Mosyle Manager (education)
+ LOGO_PATH="/Applications/Manager.app/Contents/Resources/AppIcon.icns"
+ ;;
+ addigy)
+ # Addigy
+ LOGO_PATH="/Library/Addigy/macmanage/MacManage.app/Contents/Resources/atom.icns"
+ ;;
+ microsoft)
+ # Microsoft Endpoint Manager (Intune)
+ LOGO_PATH="/Library/Intune/Microsoft Intune Agent.app/Contents/Resources/AppIcon.icns"
+ ;;
+ ws1)
+ # Workspace ONE (AirWatch)
+ LOGO="/Applications/Workspace ONE Intelligent Hub.app/Contents/Resources/AppIcon.icns"
+ ;;
+esac
+if [[ ! -a "${LOGO_PATH}" ]]; then
+ printlog "ERROR in LOGO_PATH '${LOGO_PATH}', setting Mac App Store."
+ if [[ $(/usr/bin/sw_vers -buildVersion) > "19" ]]; then
+ LOGO_PATH="/System/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ else
+ LOGO_PATH="/Applications/App Store.app/Contents/Resources/AppIcon.icns"
+ fi
+fi
+printlog "LOGO: $LOGO – LOGO_PATH: $LOGO_PATH"
+
+# Mark: Functions
+# execute a dialog command
+echo "" > $dialog_command_file || true
+function dialog_command(){
+ printlog "Dialog-command: $1"
+ echo "$1" >> $dialog_command_file || true
+}
+
+function appCheck(){
+ dialog_command "listitem: $(echo "$app" | cut -d ',' -f1): wait"
+ while [ ! -e "$(echo "$app" | cut -d ',' -f2)" ]; do
+ sleep 2
+ done
+ dialog_command "progresstext: Install of “$(echo "$app" | cut -d ',' -f1)” complete"
+ dialog_command "listitem: $(echo "$app" | cut -d ',' -f1): ✅"
+ progress_index=$(defaults read $counterFile step)
+ progress_index=$(( progress_index + 1 ))
+ defaults write $counterFile step -int $progress_index
+ dialog_command "progress: $progress_index"
+ printlog "at item number $progress_index"
+}
+
+# Notify the user using AppleScript
+function displayDialog(){
+ if [[ "$currentUser" != "" ]]; then
+ launchctl asuser $currentUserID sudo -u $currentUser osascript -e "button returned of (display dialog \"$message\" buttons {\"OK\"} default button \"OK\" with icon POSIX file \"$LOGO_PATH\")" || true
+ fi
+}
+
+# Mark: Code
+name="Dialog"
+printlog "$name check for installation"
+# download URL, version and Expected Team ID
+# Method for GitHub pkg w. app version check
+gitusername="bartreardon"
+gitreponame="swiftDialog"
+#printlog "$gitusername $gitreponame"
+filetype="pkg"
+#downloadURL="https://github.com$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
+downloadURL="https://github.com$(curl -sfL "$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "expanded_assets" | head -1)" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
+if [[ "$(echo $downloadURL | grep -ioE "https.*.$filetype")" == "" ]]; then
+ printlog "Trying GitHub API for download URL."
+ downloadURL=$(curl -sfL "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | awk -F '"' "/browser_download_url/ && /$filetype\"/ { print \$4; exit }")
+fi
+#printlog "$downloadURL"
+appNewVersion=$(curl -sLI "https://github.com/$gitusername/$gitreponame/releases/latest" | grep -i "^location" | tr "/" "\n" | tail -1 | sed 's/[^0-9\.]//g')
+#printlog "$appNewVersion"
+expectedTeamID="PWA5E9TQ59"
+destFile="/Library/Application Support/Dialog/Dialog.app"
+versionKey="CFBundleShortVersionString" #CFBundleVersion
+
+currentInstalledVersion="$(defaults read "${destFile}/Contents/Info.plist" $versionKey || true)"
+printlog "${name} version: $currentInstalledVersion"
+if [[ ! -e "${destFile}" || "$currentInstalledVersion" != "$appNewVersion" ]]; then
+ printlog "$name not found or version not latest."
+ printlog "${destFile}"
+ printlog "Installing version ${appNewVersion}…"
+ # Create temporary working directory
+ tmpDir="$(mktemp -d || true)"
+ printlog "Created working directory '$tmpDir'"
+ # Download the installer package
+ printlog "Downloading $name package version $appNewVersion from: $downloadURL"
+ installationCount=0
+ exitCode=9
+ while [[ $installationCount -lt 3 && $exitCode -gt 0 ]]; do
+ curlDownload=$(curl -Ls "$downloadURL" -o "$tmpDir/$name.pkg" || true)
+ curlDownloadStatus=$(echo $?)
+ if [[ $curlDownloadStatus -ne 0 ]]; then
+ printlog "error downloading $downloadURL, with status $curlDownloadStatus"
+ printlog "${curlDownload}"
+ exitCode=1
+ else
+ printlog "Download $name succes."
+ # Verify the download
+ teamID=$(spctl -a -vv -t install "$tmpDir/$name.pkg" 2>&1 | awk '/origin=/ {print $NF }' | tr -d '()' || true)
+ printlog "Team ID for downloaded package: $teamID"
+ # Install the package if Team ID validates
+ if [ "$expectedTeamID" = "$teamID" ] || [ "$expectedTeamID" = "" ]; then
+ printlog "$name package verified. Installing package '$tmpDir/$name.pkg'."
+ pkgInstall=$(installer -verbose -dumplog -pkg "$tmpDir/$name.pkg" -target "/" 2>&1)
+ pkgInstallStatus=$(echo $?)
+ if [[ $pkgInstallStatus -ne 0 ]]; then
+ printlog "ERROR. $name package installation failed."
+ printlog "${pkgInstall}"
+ exitCode=2
+ else
+ printlog "Installing $name package succes."
+ exitCode=0
+ fi
+ else
+ printlog "ERROR. Package verification failed for $name before package installation could start. Download link may be invalid."
+ exitCode=3
+ fi
+ fi
+ ((installationCount++))
+ printlog "$installationCount time(s), exitCode $exitCode"
+ if [[ $installationCount -lt 3 ]]; then
+ if [[ $exitCode -gt 0 ]]; then
+ printlog "Sleep a bit before trying download and install again. $installationCount time(s)."
+ printlog "Remove $(rm -fv "$tmpDir/$name.pkg" || true)"
+ sleep 2
+ fi
+ else
+ printlog "Download and install of $name succes."
+ fi
+ done
+ # Remove the temporary working directory
+ printlog "Deleting working directory '$tmpDir' and its contents."
+ printlog "Remove $(rm -Rfv "${tmpDir}" || true)"
+ # Handle installation errors
+ if [[ $exitCode != 0 ]]; then
+ printlog "ERROR. Installation of $name failed. Aborting."
+ caffexit $exitCode
+ else
+ printlog "$name version $appNewVersion installed!"
+ fi
+else
+ printlog "$name version $appNewVersion already found. Perfect!"
+fi
+
+
+while [ "$(pgrep -l "Setup Assistant")" != "" ]; do
+ printlog "Setup Assistant Still Running. PID $setupAssistantProcess."
+ sleep 1
+done
+printlog "Out of Setup Assistant."
+
+while [ "$(pgrep -l "Finder")" = "" ]; do
+ printlog "Finder process not found. Assuming device is at login screen. PID $finderProcess"
+ sleep 1
+done
+printlog "Finder is running…"
+
+currentUser=$(stat -f "%Su" /dev/console)
+currentUserID=$(id -u "$currentUser")
+printlog "Logged in user is $currentUser with ID $currentUserID"
+
+# set icon based on whether computer is a desktop or laptop
+#hwType=$(system_profiler SPHardwareDataType | grep "Model Identifier" | grep "Book" || true)
+#if [ "$hwType" != "" ]; then
+# LOGO_PATH="SF=laptopcomputer.and.arrow.down,weight=thin,colour1=#51a3ef,colour2=#5154ef"
+#else
+# LOGO_PATH="SF=desktopcomputer.and.arrow.down,weight=thin,colour1=#51a3ef,colour2=#5154ef"
+#fi
+
+dialogCMD="$dialogApp -p --title \"$title\" \
+--message \"$message\" \
+--icon \"$LOGO_PATH\" \
+--progress $progress_total \
+--button1text \"Please Wait\" \
+--button1disabled"
+
+# create the list of apps
+listitems=""
+for app in "${apps[@]}"; do
+ listitems="$listitems --listitem '$(echo "$app" | cut -d ',' -f1)'"
+done
+
+# final command to execute
+dialogCMD="$dialogCMD $listitems"
+
+printlog "$dialogCMD"
+
+# Launch dialog and run it in the background sleep for a second to let thing initialise
+printlog "About to launch Dialog."
+eval "$dialogCMD" &
+sleep 2
+
+(for app in "${apps[@]}"; do
+ #step_progress=$(( 1 + progress_index ))
+ #dialog_command "progress: $step_progress"
+ sleep 0.5
+ appCheck &
+done
+
+wait)
+
+# Mark: Finishing
+
+# Prevent re-run of script if conditionFile is set
+if [[ ! -z "$conditionFile" ]]; then
+ printlog "Touching condition file so script will not run again"
+ touch "$conditionFile" || true
+ printlog "$(ls -al "$conditionFile" || true)"
+fi
+
+# all done. close off processing and enable the "Done" button
+printlog "Finalizing."
+dialog_command "progresstext: $endMessage"
+dialog_command "progress: complete"
+dialog_command "button1text: Done"
+dialog_command "button1: enable"
+
+if [[ $displayEndMessageDialog -eq 1 ]]; then
+ message="$endMessage"
+ displayDialog &
+fi
+
+sleep 1
+printlog $(rm -fv $dialog_command_file || true)
+printlog $(rm -fv $counterFile || true)
+
+printlog "Ending"
diff --git a/MDM/README.md b/MDM/README.md
new file mode 100644
index 0000000..0360ffb
--- /dev/null
+++ b/MDM/README.md
@@ -0,0 +1,101 @@
+# MDM scripts
+
+This is a long list of various scripts for certain use in the various MDM solutions that we have used Installomator with.
+
+There are two categories of MDMs. Either like Jamf Pro, that can contain the full script, and call that as a software installation (called policy in Jamf Pro). If the MDM cannot do that, it have to be able to run a script on the clients. That script can call Installomator on the client, and should therefore be locally installed.
+
+## “Jamf”-folder
+
+Here you have scripts for using swiftDialog as part of the Installomator installation. Showing progress in a small window. Separate [ReadMe-file](Jamf/ReadMe.md) in this folder.
+
+## Script capable MDM-solutions
+
+So for Mosyle, Addigy, and Microsoft Endpoint Manager (Intune), we have tested these scripts. If these works in other MDMs, let us know.
+
+Especially for Addigy, and maybe also for other MDMs, `condition`-scripts has been added if software installation will run on certain conditions. Also `prevention`-scripts has been added, if you manually need to eliminate the runnning of a script, this can be needed if you want to use the enrollment script, but don’t want it to run on the currently managed Macs Then you should sent out the `prevention`-script to make sure the file it creates is present on the Macs so the ordinary script will not do anything (it will detect this file and stop if found).
+
+_The scripts utilizing __swiftDialog__ requires version 10 of __Installomator__, but will work with version 9. If runnning on version 9 it will set `NOTIFY=all` and use __Installomator__ notifications for showing progress, where as on version 10 it will be `NOTIFY=silent` as __swiftDialog__ is used instead._
+
+### Shortenings
+
+- SS — Self Service — scripts designed for use through a Self Service catalog
+- VFA — valuesfromarguments — a custom label call to Installomator
+
+# To be installed on all the Macs
+
+In order for our MDM scripts to work, we need Installomator locally installed using the pkg we provide in our release.
+
+So I suggest to install these on enrollment.
+
+To utilize swiftDialog, we also need that installed.
+
+If you need dockutil, that should be maintained as well, but if missing the MDM scripts will install it.
+
+## Maintenance of Installomator, swiftDialog, and dockutil
+
+I suggest to check weekly, and maybe at each boot, it newer versions have been released of these tools.
+
+The verious MDMs have various ways of running scheduled, but it is possible.
+
+### Scripts to use for installing these components
+
+These do not require anything to be installed on macOS:
+
+- `install Installomator direct.sh` — can be run at enrollment and as maintenance at any time to install __Installomator__.
+
+- `install swiftDialog direct.sh` — can be used at enrollment and as maintenance at any time to install __swiftDialog__.
+
+Once Installomator has been installed, __dockutil__ can be installed using Installomator (as a service), using this script:
+
+- `App-install/App service Auto-install.sh` — This script uses pre-installed installomator to install dockutil.
+
+# Enrollment scripts
+
+For enrollment purposes, som 1st-scripts has been created. One is not showing anything to the end-user while running and another is using __DEPNotify__ to show progress (so hopefully the user will wait for the installation to finish):
+
+- `Installomator 1st Auto-install DEPNotify.sh` — will install __DEPNotify__ first, start that up, and change progress on the installation bar at each installed label. Very good for Addigy.
+
+- `Installomator 1st Auto-install.sh` — runnning silently installing Installomator labels in the given order. Can be used in combination with the Progress-script.
+
+- `Progress 1st swiftDialog.sh` — It will install __swiftDialog__ and start that up with a list of software it will look for. It will look for an installed file/folder in the file system for each item. This is great for Mosyle that can install software using various methods, and then this script can show when it has been installed.
+
+There are also Self Service scripts for this, if it’s somehow needed to have users running the installation manually.
+
+# _App-install_ folders
+
+Two different kinds of App-installation scripts have been made. Some that is very similar to the old provided scripts that are only using __Installomator__ for notifications (if any). And others that can use __swiftDialog__ for installation progress, and can also add the app to the Dock using __dockutil__.
+
+## “App-install”-folder
+
+- App browser-security Auto-install.sh
+- App browser-security SS.sh
+- App normal Auto-install.sh
+- App normal SS.sh
+- App service Auto-install.sh
+- App VFA.sh
+
+Here you can use scripts for Self Service (SS) or for Auto-install. THere will be a difference in how many notifications will be used and maybe handling of blocking processes.
+
+What is also differentiated is what kind of app it is. Is it of the kind of browser, that can often have critical security fixes, then we don’t want the user to postpone the installation, wheras a normal app can wait. A service app do not have to ask before installing, and should be able to install regardsliess if the app is currently running.
+
+## “App-install SS with swiftDialog and dockutil”-folder
+
+- App browser-security SS.sh
+- App normal SS multi-app.sh
+- App normal SS.sh
+- App service SS.sh
+- App VFA SS github.sh
+- App VFA SS.sh
+
+All of the notes for the above scripts are the same for these.
+
+But these scripts utilize __swiftDialog__ to show a more live progress for the installation, and they also have a setting to use __dockutil__ to add the software to the Dock of the user.
+
+# App-update
+
+These script verifies if the app is already installed, before runnning Installomator.
+
+- App browser-security Auto-install.sh
+- App normal Auto-install.sh
+
+These scripts only use Installomator, like “App-install”, but will check for the app to be installed first. Very usefull for Addigy and Microsoft.
diff --git a/MDM/RemoveInstallomator.sh b/MDM/Remove Installomator.sh
similarity index 100%
rename from MDM/RemoveInstallomator.sh
rename to MDM/Remove Installomator.sh
diff --git a/MDM/install Installomator direct condition.sh b/MDM/install Installomator direct condition.sh
new file mode 100755
index 0000000..342e72d
--- /dev/null
+++ b/MDM/install Installomator direct condition.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+# Mark: Addigy Condition
+# Install on success
+
+gitusername="Installomator"
+gitreponame="Installomator"
+appNewVersion=$(curl -sLI "https://github.com/$gitusername/$gitreponame/releases/latest" | grep -i "^location" | tr "/" "\n" | tail -1 | sed 's/[^0-9\.]//g')
+
+destFile="/usr/local/Installomator/Installomator.sh"
+if [[ ! -e "${destFile}" || "$(${destFile} version)" != "$appNewVersion" ]]; then
+ #echo "Let's install…"
+ exit 0
+else
+ #echo "No need!"
+ exit 1
+fi
diff --git a/MDM/install Installomator direct.sh b/MDM/install Installomator direct.sh
new file mode 100755
index 0000000..352275e
--- /dev/null
+++ b/MDM/install Installomator direct.sh
@@ -0,0 +1,149 @@
+#!/bin/sh
+
+######################################################################
+# Installation of Installomator
+#
+# No customization below…
+######################################################################
+# This script can be used to install Installomator directly from GitHub.
+######################################################################
+#
+# This script made by Søren Theilgaard
+# https://github.com/Theile
+# Twitter and MacAdmins Slack: @theilgaard
+#
+# Some functions and code from Installomator:
+# https://github.com/Installomator/Installomator
+#
+######################################################################
+scriptVersion="9.5"
+# v. 9.5 : 2022-09-21 : change of GitHub download
+# v. 9.4 : 2022-09-14 : downloadURL can fall back on GitHub API
+# v. 9.3 : 2022-08-29 : Logging changed for current version. Improved installation with looping if it fails, so it can try again. Improved GitHub handling.
+# v. 9.2.2 : 2022-06-17 : Check 1.1.1.1 for internet connection.
+# v. 9.2 : 2022-05-19 : Built in installer for Installlomator. Universal script.
+######################################################################
+
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+# Mark: Constants, logging and caffeinate
+log_message="Installomator install, v$scriptVersion"
+label="Inst-v$scriptVersion"
+
+log_location="/private/var/log/Installomator.log"
+printlog(){
+ timestamp=$(date +%F\ %T)
+ if [[ "$(whoami)" == "root" ]]; then
+ echo "$timestamp :: $label : $1" | tee -a $log_location
+ else
+ echo "$timestamp :: $label : $1"
+ fi
+}
+printlog "[LOG-BEGIN] ${log_message}"
+
+# Internet check
+if [[ "$(nc -z -v -G 10 1.1.1.1 53 2>&1 | grep -io "succeeded")" != "succeeded" ]]; then
+ printlog "ERROR. No internet connection, we cannot continue."
+ exit 90
+fi
+
+# No sleeping
+/usr/bin/caffeinate -d -i -m -u &
+caffeinatepid=$!
+caffexit () {
+ kill "$caffeinatepid" || true
+ pkill caffeinate || true
+ printlog "[LOG-END] Status $1"
+ exit $1
+}
+
+name="Installomator"
+printlog "$name check for installation"
+# download URL, version and Expected Team ID
+# Method for GitHub pkg with destFile
+gitusername="Installomator"
+gitreponame="Installomator"
+#printlog "$gitusername $gitreponame"
+filetype="pkg"
+#downloadURL="https://github.com$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
+downloadURL="https://github.com$(curl -sfL "$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "expanded_assets" | head -1)" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
+if [[ "$(echo $downloadURL | grep -ioE "https.*.$filetype")" == "" ]]; then
+ printlog "Trying GitHub API for download URL."
+ downloadURL=$(curl -sfL "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | awk -F '"' "/browser_download_url/ && /$filetype\"/ { print \$4; exit }")
+fi
+#printlog "$downloadURL"
+appNewVersion=$(curl -sLI "https://github.com/$gitusername/$gitreponame/releases/latest" | grep -i "^location" | tr "/" "\n" | tail -1 | sed 's/[^0-9\.]//g')
+#printlog "$appNewVersion"
+expectedTeamID="JME5BW3F3R"
+
+destFile="/usr/local/Installomator/Installomator.sh"
+currentInstalledVersion="$(${destFile} version 2>/dev/null || true)"
+printlog "${destFile} version: $currentInstalledVersion"
+if [[ ! -e "${destFile}" || "$currentInstalledVersion" != "$appNewVersion" ]]; then
+ printlog "$name not found or version not latest."
+ printlog "${destFile}"
+ printlog "Installing version ${appNewVersion} ..."
+ # Create temporary working directory
+ tmpDir="$(mktemp -d || true)"
+ printlog "Created working directory '$tmpDir'"
+ # Download the installer package
+ printlog "Downloading $name package version $appNewVersion from: $downloadURL"
+ installationCount=0
+ exitCode=9
+ while [[ $installationCount -lt 3 && $exitCode -gt 0 ]]; do
+ curlDownload=$(curl -Ls "$downloadURL" -o "$tmpDir/$name.pkg" || true)
+ curlDownloadStatus=$(echo $?)
+ if [[ $curlDownloadStatus -ne 0 ]]; then
+ printlog "error downloading $downloadURL, with status $curlDownloadStatus"
+ printlog "${curlDownload}"
+ exitCode=1
+ else
+ printlog "Download $name succes."
+ # Verify the download
+ teamID=$(spctl -a -vv -t install "$tmpDir/$name.pkg" 2>&1 | awk '/origin=/ {print $NF }' | tr -d '()' || true)
+ printlog "Team ID for downloaded package: $teamID"
+ # Install the package if Team ID validates
+ if [ "$expectedTeamID" = "$teamID" ] || [ "$expectedTeamID" = "" ]; then
+ printlog "$name package verified. Installing package '$tmpDir/$name.pkg'."
+ pkgInstall=$(installer -verbose -dumplog -pkg "$tmpDir/$name.pkg" -target "/" 2>&1)
+ pkgInstallStatus=$(echo $?)
+ if [[ $pkgInstallStatus -ne 0 ]]; then
+ printlog "ERROR. $name package installation failed."
+ printlog "${pkgInstall}"
+ exitCode=2
+ else
+ printlog "Installing $name package succes."
+ exitCode=0
+ fi
+ else
+ printlog "ERROR. Package verification failed for $name before package installation could start. Download link may be invalid."
+ exitCode=3
+ fi
+ fi
+ ((installationCount++))
+ printlog "$installationCount time(s), exitCode $exitCode"
+ if [[ $installationCount -lt 3 ]]; then
+ if [[ $exitCode -gt 0 ]]; then
+ printlog "Sleep a bit before trying download and install again. $installationCount time(s)."
+ printlog "Remove $(rm -fv "$tmpDir/$name.pkg" || true)"
+ sleep 2
+ fi
+ else
+ printlog "Download and install of $name succes."
+ fi
+ done
+ # Remove the temporary working directory
+ printlog "Deleting working directory '$tmpDir' and its contents."
+ printlog "Remove $(rm -Rfv "${tmpDir}" || true)"
+ # Handle installation errors
+ if [[ $exitCode != 0 ]]; then
+ printlog "ERROR. Installation of $name failed. Aborting."
+ caffexit $exitCode
+ else
+ printlog "$name version $appNewVersion installed!"
+ fi
+else
+ printlog "$name version $appNewVersion already found. Perfect!"
+fi
+
+caffexit 0
diff --git a/MDM/install swiftDialog direct condition.sh b/MDM/install swiftDialog direct condition.sh
new file mode 100755
index 0000000..79adc19
--- /dev/null
+++ b/MDM/install swiftDialog direct condition.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+# Mark: Addigy Condition
+# Install on success
+
+gitusername="bartreardon"
+gitreponame="swiftDialog"
+appNewVersion=$(curl -sLI "https://github.com/$gitusername/$gitreponame/releases/latest" | grep -i "^location" | tr "/" "\n" | tail -1 | sed 's/[^0-9\.]//g')
+
+destFile="/Library/Application Support/Dialog/Dialog.app"
+versionKey="CFBundleShortVersionString" #CFBundleVersion
+
+currentInstalledVersion="$(defaults read "${destFile}/Contents/Info.plist" $versionKey || true)"
+if [[ ! -e "${destFile}" || "$currentInstalledVersion" != "$appNewVersion" ]]; then
+ #echo "Let's install…"
+ exit 0
+else
+ #echo "No need!"
+ exit 1
+fi
diff --git a/MDM/install swiftDialog direct.sh b/MDM/install swiftDialog direct.sh
new file mode 100755
index 0000000..c29d299
--- /dev/null
+++ b/MDM/install swiftDialog direct.sh
@@ -0,0 +1,150 @@
+#!/bin/sh
+
+######################################################################
+# Installation of swiftDialog
+#
+# No customization below…
+######################################################################
+# This script can be used to install swiftDialog directly from GitHub.
+######################################################################
+#
+# This script made by Søren Theilgaard
+# https://github.com/Theile
+# Twitter and MacAdmins Slack: @theilgaard
+#
+# Some functions and code from Installomator:
+# https://github.com/Installomator/Installomator
+#
+######################################################################
+scriptVersion="9.5"
+# v. 9.5 : 2022-09-21 : change of GitHub download
+# v. 9.4 : 2022-09-14 : downloadURL can fall back on GitHub API.
+# v. 9.3 : 2022-08-29 : Logging changed for current version. Improved installation with looping if it fails, so it can try again. Improved GitHub handling.
+# v. 9.2.2 : 2022-06-17 : Check 1.1.1.1 for internet connection.
+# v. 9.2 : 2022-05-19 : Built in installer for Installlomator. Universal script.
+######################################################################
+
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+# Mark: Constants, logging and caffeinate
+log_message="Dialog install, v$scriptVersion"
+label="Dialog-v$scriptVersion"
+
+log_location="/private/var/log/Installomator.log"
+printlog(){
+ timestamp=$(date +%F\ %T)
+ if [[ "$(whoami)" == "root" ]]; then
+ echo "$timestamp :: $label : $1" | tee -a $log_location
+ else
+ echo "$timestamp :: $label : $1"
+ fi
+}
+printlog "[LOG-BEGIN] ${log_message}"
+
+# Internet check
+if [[ "$(nc -z -v -G 10 1.1.1.1 53 2>&1 | grep -io "succeeded")" != "succeeded" ]]; then
+ printlog "ERROR. No internet connection, we cannot continue."
+ exit 90
+fi
+
+# No sleeping
+/usr/bin/caffeinate -d -i -m -u &
+caffeinatepid=$!
+caffexit () {
+ kill "$caffeinatepid" || true
+ pkill caffeinate || true
+ printlog "[LOG-END] Status $1"
+ exit $1
+}
+
+name="Dialog"
+printlog "$name check for installation"
+# download URL, version and Expected Team ID
+# Method for GitHub pkg w. app version check
+gitusername="bartreardon"
+gitreponame="swiftDialog"
+#printlog "$gitusername $gitreponame"
+filetype="pkg"
+#downloadURL="https://github.com$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
+downloadURL="https://github.com$(curl -sfL "$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "expanded_assets" | head -1)" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
+if [[ "$(echo $downloadURL | grep -ioE "https.*.$filetype")" == "" ]]; then
+ printlog "Trying GitHub API for download URL."
+ downloadURL=$(curl -sfL "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | awk -F '"' "/browser_download_url/ && /$filetype\"/ { print \$4; exit }")
+fi
+#printlog "$downloadURL"
+appNewVersion=$(curl -sLI "https://github.com/$gitusername/$gitreponame/releases/latest" | grep -i "^location" | tr "/" "\n" | tail -1 | sed 's/[^0-9\.]//g')
+#printlog "$appNewVersion"
+expectedTeamID="PWA5E9TQ59"
+destFile="/Library/Application Support/Dialog/Dialog.app"
+versionKey="CFBundleShortVersionString" #CFBundleVersion
+
+currentInstalledVersion="$(defaults read "${destFile}/Contents/Info.plist" $versionKey || true)"
+printlog "${name} version: $currentInstalledVersion"
+if [[ ! -e "${destFile}" || "$currentInstalledVersion" != "$appNewVersion" ]]; then
+ printlog "$name not found or version not latest."
+ printlog "${destFile}"
+ printlog "Installing version ${appNewVersion}…"
+ # Create temporary working directory
+ tmpDir="$(mktemp -d || true)"
+ printlog "Created working directory '$tmpDir'"
+ # Download the installer package
+ printlog "Downloading $name package version $appNewVersion from: $downloadURL"
+ installationCount=0
+ exitCode=9
+ while [[ $installationCount -lt 3 && $exitCode -gt 0 ]]; do
+ curlDownload=$(curl -Ls "$downloadURL" -o "$tmpDir/$name.pkg" || true)
+ curlDownloadStatus=$(echo $?)
+ if [[ $curlDownloadStatus -ne 0 ]]; then
+ printlog "error downloading $downloadURL, with status $curlDownloadStatus"
+ printlog "${curlDownload}"
+ exitCode=1
+ else
+ printlog "Download $name succes."
+ # Verify the download
+ teamID=$(spctl -a -vv -t install "$tmpDir/$name.pkg" 2>&1 | awk '/origin=/ {print $NF }' | tr -d '()' || true)
+ printlog "Team ID for downloaded package: $teamID"
+ # Install the package if Team ID validates
+ if [ "$expectedTeamID" = "$teamID" ] || [ "$expectedTeamID" = "" ]; then
+ printlog "$name package verified. Installing package '$tmpDir/$name.pkg'."
+ pkgInstall=$(installer -verbose -dumplog -pkg "$tmpDir/$name.pkg" -target "/" 2>&1)
+ pkgInstallStatus=$(echo $?)
+ if [[ $pkgInstallStatus -ne 0 ]]; then
+ printlog "ERROR. $name package installation failed."
+ printlog "${pkgInstall}"
+ exitCode=2
+ else
+ printlog "Installing $name package succes."
+ exitCode=0
+ fi
+ else
+ printlog "ERROR. Package verification failed for $name before package installation could start. Download link may be invalid."
+ exitCode=3
+ fi
+ fi
+ ((installationCount++))
+ printlog "$installationCount time(s), exitCode $exitCode"
+ if [[ $installationCount -lt 3 ]]; then
+ if [[ $exitCode -gt 0 ]]; then
+ printlog "Sleep a bit before trying download and install again. $installationCount time(s)."
+ printlog "Remove $(rm -fv "$tmpDir/$name.pkg" || true)"
+ sleep 2
+ fi
+ else
+ printlog "Download and install of $name succes."
+ fi
+ done
+ # Remove the temporary working directory
+ printlog "Deleting working directory '$tmpDir' and its contents."
+ printlog "Remove $(rm -Rfv "${tmpDir}" || true)"
+ # Handle installation errors
+ if [[ $exitCode != 0 ]]; then
+ printlog "ERROR. Installation of $name failed. Aborting."
+ caffexit $exitCode
+ else
+ printlog "$name version $appNewVersion installed!"
+ fi
+else
+ printlog "$name version $appNewVersion already found. Perfect!"
+fi
+
+caffexit 0
diff --git a/MDM/swiftdialog_example.sh b/MDM/swiftdialog_example.sh
new file mode 100755
index 0000000..ee48ef3
--- /dev/null
+++ b/MDM/swiftdialog_example.sh
@@ -0,0 +1,151 @@
+#!/bin/zsh
+
+# runs through a list of Installomator items
+# and displays status using Swift Dialog
+#
+# dependencies:
+# - Swift Dialog: https://github.com/bartreardon/swiftDialog
+# - Installomator: https://github.com/Installomator/Installomator
+# this script will install both if they are not yet present
+
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+# MARK: Variables
+
+# set to 1 to not require root and not actually do any changes
+# set to 0 for production
+if [[ $1 == "NODEBUG" ]]; then
+ DEBUG=0
+else
+ DEBUG=1
+fi
+
+# the label to install:
+label="googlechromepkg"
+
+
+# MARK: Constants
+
+scriptDir=$(dirname ${0:A})
+repoDir=$(dirname $scriptDir)
+
+# if [[ $DEBUG -eq 1 ]]; then
+ installomator="$repoDir/utils/assemble.sh"
+# else
+# installomator="/usr/local/Installomator/Installomator.sh"
+# fi
+
+dialog="/usr/local/bin/dialog"
+
+if [[ DEBUG -eq 0 ]]; then
+ dialog_command_file="/var/tmp/dialog.log"
+else
+ dialog_command_file="$HOME/dialog.log"
+fi
+
+
+# MARK: Functions
+
+dialogUpdate() {
+ # $1: dialog command
+ local dcommand=$1
+
+ if [[ -n $dialog_command_file ]]; then
+ echo "$dcommand" >> $dialog_command_file
+ echo "Dialog: $dcommand"
+ fi
+}
+
+progressUpdate() {
+ # $1: progress text (optional)
+ local text=$1
+ itemCounter=$((itemCounter + 1))
+ dialogUpdate "progress: $itemCounter"
+ if [[ -n $text ]]; then
+ dialogUpdate "progresstext: $text"
+ fi
+}
+
+startItem() {
+ local description=$1
+
+ echo "Starting Item: $description"
+ dialogUpdate "listitem: $description: wait"
+ progressUpdate $description
+}
+
+cleanupAndExit() {
+ # kill caffeinate process
+ if [[ -n $caffeinatePID ]]; then
+ echo "killing caffeinate..."
+ kill $caffeinatePID
+ fi
+
+ # clean up tmp dir
+ if [[ -n $tmpDir && -d $tmpDir ]]; then
+ echo "removing tmpDir $tmpDir"
+ rm -rf $tmpDir
+ fi
+}
+
+# MARK: sanity checks
+
+# check minimal macOS requirement
+if [[ $(sw_vers -buildVersion ) < "20" ]]; then
+ echo "This script requires at least macOS 11 Big Sur."
+ exit 98
+fi
+
+# check we are running as root
+if [[ $DEBUG -eq 0 && $(id -u) -ne 0 ]]; then
+ echo "This script should be run as root"
+ exit 97
+fi
+
+# check for installomator
+if [[ ! -x $installomator ]]; then
+ echo "Cannot find Installomator at $installomator"
+ exit 96
+fi
+
+# check for Swift Dialog
+if [[ ! -x $dialog ]]; then
+ echo "Cannot find dialog at $dialog"
+ exit 95
+fi
+
+
+# MARK: Setup
+
+# No sleeping
+caffeinate -dimsu & caffeinatePID=$!
+
+# trap exit for cleanup
+trap cleanupAndExit EXIT
+
+# display first screen
+$dialog --title "Installing $label" \
+ --message "" \
+ --hideicon \
+ --mini \
+ --progress 100 \
+ --position bottomright \
+ --ontop \
+ --movable \
+ --commandfile $dialog_command_file & dialogPID=$!
+
+sleep 0.1
+
+$installomator $label \
+ DIALOG_CMD_FILE="$dialog_command_file" \
+ DEBUG=$DEBUG
+
+# clean up UI
+
+dialogUpdate "progress: complete"
+dialogUpdate "progresstext: Done"
+
+sleep 0.5
+
+dialogUpdate "quit:"
+
diff --git a/MDM/swiftdialog_list.sh b/MDM/swiftdialog_list.sh
new file mode 100755
index 0000000..cb48483
--- /dev/null
+++ b/MDM/swiftdialog_list.sh
@@ -0,0 +1,185 @@
+#!/bin/zsh
+
+# runs through a list of Installomator items
+# and displays status using Swift Dialog
+#
+# dependencies:
+# - Swift Dialog: https://github.com/bartreardon/swiftDialog
+# - Installomator: https://github.com/Installomator/Installomator
+# this script will install both if they are not yet present
+
+export PATH=/usr/bin:/bin:/usr/sbin:/sbin
+
+# MARK: Variables
+
+# set to 1 to not require root and not actually do any changes
+# set to 0 for production
+if [[ $1 == "NODEBUG" ]]; then
+ DEBUG=0
+else
+ DEBUG=1
+fi
+
+# list of Installomator labels
+
+items=(
+ "firefoxpkg|Firefox"
+ "error|Expected Error"
+ "googlechromepkg|Google Chrome"
+ )
+
+# MARK: Constants
+
+scriptDir=$(dirname ${0:A})
+repoDir=$(dirname $scriptDir)
+
+# if [[ $DEBUG -eq 1 ]]; then
+ installomator="$repoDir/utils/assemble.sh"
+# else
+# installomator="/usr/local/Installomator/Installomator.sh"
+# fi
+
+dialog="/usr/local/bin/dialog"
+
+if [[ DEBUG -eq 0 ]]; then
+ dialog_command_file="/var/tmp/dialog.log"
+else
+ dialog_command_file="$HOME/dialog.log"
+fi
+
+
+# MARK: Functions
+
+dialogUpdate() {
+ # $1: dialog command
+ local dcommand=$1
+
+ if [[ -n $dialog_command_file ]]; then
+ echo "$dcommand" >> $dialog_command_file
+ echo "Dialog: $dcommand"
+ fi
+}
+
+progressUpdate() {
+ # $1: progress text (optional)
+ local text=$1
+ itemCounter=$((itemCounter + 1))
+ dialogUpdate "progress: $itemCounter"
+ if [[ -n $text ]]; then
+ dialogUpdate "progresstext: $text"
+ fi
+}
+
+startItem() {
+ local description=$1
+
+ echo "Starting Item: $description"
+ dialogUpdate "listitem: $description: wait"
+ progressUpdate $description
+}
+
+installomator() {
+ # $1: label
+ # $2: description
+ local label=$1
+ local description=$2
+
+ $installomator $label \
+ DIALOG_CMD_FILE=${(q)dialog_command_file} \
+ DIALOG_LIST_ITEM_NAME=${(q)description} \
+ DEBUG=$DEBUG \
+ LOGGING=DEBUG
+}
+
+cleanupAndExit() {
+ # kill caffeinate process
+ if [[ -n $caffeinatePID ]]; then
+ echo "killing caffeinate..."
+ kill $caffeinatePID
+ fi
+
+ # clean up tmp dir
+ if [[ -n $tmpDir && -d $tmpDir ]]; then
+ echo "removing tmpDir $tmpDir"
+ rm -rf $tmpDir
+ fi
+}
+
+# MARK: sanity checks
+
+# check minimal macOS requirement
+if [[ $(sw_vers -buildVersion ) < "20" ]]; then
+ echo "This script requires at least macOS 11 Big Sur."
+ exit 98
+fi
+
+# check we are running as root
+if [[ $DEBUG -eq 0 && $(id -u) -ne 0 ]]; then
+ echo "This script should be run as root"
+ exit 97
+fi
+
+# check for installomator
+if [[ ! -x $installomator ]]; then
+ echo "Cannot find Installomator at $installomator"
+ exit 96
+fi
+
+# check for Swift Dialog
+if [[ ! -x $dialog ]]; then
+ echo "Cannot find dialog at $dialog"
+ exit 95
+fi
+
+
+# MARK: Setup
+
+# No sleeping
+caffeinate -dimsu & caffeinatePID=$!
+
+# trap exit for cleanup
+trap cleanupAndExit EXIT
+
+# setup first list
+itemCount=$((${#items} + 1))
+
+listitems=( )
+
+for item in $items; do
+ label=$(cut -d '|' -f 1 <<< $item)
+ description=$(cut -d '|' -f 2 <<< $item)
+ listitems+=( "--listitem" ${description} )
+done
+
+# display first screen
+$dialog --title "More Software" \
+ --icon "SF=gear" \
+ --message "We are downloading and installing some extra Apps..." \
+ --progress $itemCount \
+ "${listitems[@]}" \
+ --button1disabled \
+ --big \
+ --ontop \
+ --liststyle compact \
+ --width 700 \
+ --commandfile $dialog_command_file & dialogPID=$!
+sleep 0.1
+
+itemCounter=0
+
+for item in $items; do
+ label=$(cut -d '|' -f 1 <<< $item)
+ description=$(cut -d '|' -f 2 <<< $item)
+
+ startItem $description
+ installomator $label $description
+done
+
+# clean up UI
+
+dialogUpdate "progress: complete"
+dialogUpdate "progresstext: Finished"
+
+dialogUpdate "button1: enable"
+dialogUpdate "button1text: Done"
+
diff --git a/fragments/arguments.sh b/fragments/arguments.sh
index d600180..29d81a5 100644
--- a/fragments/arguments.sh
+++ b/fragments/arguments.sh
@@ -7,6 +7,7 @@ if ! is-at-least 10.14 $installedOSversion; then
exit 98
fi
+
# MARK: argument parsing
if [[ $# -eq 0 ]]; then
if [[ -z $label ]]; then # check if label is set inside script
@@ -24,7 +25,7 @@ fi
while [[ -n $1 ]]; do
if [[ $1 =~ ".*\=.*" ]]; then
# if an argument contains an = character, send it to eval
- printlog "setting variable from argument $1" WARN
+ printlog "setting variable from argument $1" INFO
eval $1
else
# assume it's a label
@@ -99,6 +100,16 @@ if [[ "$(whoami)" != "root" && "$DEBUG" -eq 0 ]]; then
cleanupAndExit 6 "not running as root, exiting" ERROR
fi
+
+# check Swift Dialog presence and version
+DIALOG_CMD="/usr/local/bin/dialog"
+
+if [[ ! -x $DIALOG_CMD ]]; then
+ # Swift Dialog is not installed, clear cmd file variable to ignore
+ printlog "SwiftDialog is not installed, clear cmd file var"
+ DIALOG_CMD_FILE=""
+fi
+
# MARK: labels in case statement
case $label in
longversion)
diff --git a/fragments/labels/wickrme.sh b/fragments/disabled/wickrme.sh
similarity index 74%
rename from fragments/labels/wickrme.sh
rename to fragments/disabled/wickrme.sh
index 2ce25d4..5b226ba 100644
--- a/fragments/labels/wickrme.sh
+++ b/fragments/disabled/wickrme.sh
@@ -1,6 +1,7 @@
wickrme)
- # credit: Søren Theilgaard (@theilgaard)
+ # Label not working, haven't found a solution
name="WickrMe"
+ printlog "Label for $name broken in test" WARN
type="dmg"
downloadURL=$( curl -fs https://me-download.wickr.com/api/download/me/download/mac | tr '"' '\n' | grep -e '^https://' )
appNewVersion=$( echo ${downloadURL} | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)\..*/\1/g' )
diff --git a/fragments/labels/wickrpro.sh b/fragments/disabled/wickrpro.sh
similarity index 74%
rename from fragments/labels/wickrpro.sh
rename to fragments/disabled/wickrpro.sh
index 6ddec0e..ee0a2b9 100644
--- a/fragments/labels/wickrpro.sh
+++ b/fragments/disabled/wickrpro.sh
@@ -1,6 +1,7 @@
wickrpro)
- # credit: Søren Theilgaard (@theilgaard)
+ # Label not working, haven't found a solution
name="WickrPro"
+ printlog "Label for $name broken in test" WARN
type="dmg"
downloadURL=$( curl -fs https://me-download.wickr.com/api/download/pro/download/mac | tr '"' '\n' | grep -e '^https://' )
appNewVersion=$( echo ${downloadURL} | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)\..*/\1/g' )
diff --git a/fragments/functions.sh b/fragments/functions.sh
index ddbe70f..bbd6bed 100644
--- a/fragments/functions.sh
+++ b/fragments/functions.sh
@@ -14,12 +14,15 @@ cleanupAndExit() { # $1 = exit code, $2 message, $3 level
printlog "Debugging enabled, Deleting tmpDir output was:\n$deleteTmpOut" DEBUG
fi
+
# If we closed any processes, reopen the app again
reopenClosedProcess
if [[ -n $2 && $1 -ne 0 ]]; then
printlog "ERROR: $2" $3
+ updateDialog "fail" "Error ($1; $2)"
else
printlog "$2" $3
+ updateDialog "success" ""
fi
printlog "################## End Installomator, exit code $1 \n" REQ
@@ -61,9 +64,12 @@ displaynotification() { # $1: message $2: title
message=${1:-"Message"}
title=${2:-"Notification"}
manageaction="/Library/Application Support/JAMF/bin/Management Action.app/Contents/MacOS/Management Action"
+ hubcli="/usr/local/bin/hubcli"
if [[ -x "$manageaction" ]]; then
"$manageaction" -message "$message" -title "$title"
+ elif [[ -x "$hubcli" ]]; then
+ "$hubcli" notify -t "$title" -i "$message" -c "Dismiss"
else
runAsUser osascript -e "display notification \"$message\" with title \"$title\""
fi
@@ -156,14 +162,22 @@ downloadURLFromGit() { # $1 git user name, $2 git repo name
fi
if [ -n "$archiveName" ]; then
- downloadURL=$(curl -L --silent --fail "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" \
- | awk -F '"' "/browser_download_url/ && /$archiveName\"/ { print \$4; exit }")
+ downloadURL=$(curl -sfL "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | awk -F '"' "/browser_download_url/ && /$archiveName\"/ { print \$4; exit }")
+ if [[ "$(echo $downloadURL | grep -ioE "https.*$archiveName")" == "" ]]; then
+ printlog "GitHub API not returning URL, trying https://github.com/$gitusername/$gitreponame/releases/latest."
+ #downloadURL=https://github.com$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*$archiveName" | head -1)
+ downloadURL="https://github.com$(curl -sfL "$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "expanded_assets" | head -1)" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*$archiveName" | head -1)"
+ fi
else
- downloadURL=$(curl -L --silent --fail "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" \
- | awk -F '"' "/browser_download_url/ && /$filetype\"/ { print \$4; exit }")
+ downloadURL=$(curl -sfL "https://api.github.com/repos/$gitusername/$gitreponame/releases/latest" | awk -F '"' "/browser_download_url/ && /$filetype\"/ { print \$4; exit }")
+ if [[ "$(echo $downloadURL | grep -ioE "https.*.$filetype")" == "" ]]; then
+ printlog "GitHub API not returning URL, trying https://github.com/$gitusername/$gitreponame/releases/latest."
+ #downloadURL=https://github.com$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)
+ downloadURL="https://github.com$(curl -sfL "$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "expanded_assets" | head -1)" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)"
+ fi
fi
if [ -z "$downloadURL" ]; then
- cleanupAndExit 9 "could not retrieve download URL for $gitusername/$gitreponame" ERROR
+ cleanupAndExit 14 "could not retrieve download URL for $gitusername/$gitreponame" ERROR
else
echo "$downloadURL"
return 0
@@ -176,7 +190,8 @@ versionFromGit() {
gitusername=${1?:"no git user name"}
gitreponame=${2?:"no git repo name"}
- 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')
+ #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')
+ appNewVersion=$(curl -sLI "https://github.com/$gitusername/$gitreponame/releases/latest" | grep -i "^location" | tr "/" "\n" | tail -1 | sed 's/[^0-9\.]//g')
if [ -z "$appNewVersion" ]; then
printlog "could not retrieve version number for $gitusername/$gitreponame" WARN
appNewVersion=""
@@ -278,7 +293,11 @@ getAppVersion() {
printlog "Replacing App Store apps, no matter the version" WARN
appversion=0
else
- cleanupAndExit 1 "App previously installed from App Store, and we respect that" ERROR
+ if [[ $DIALOG_CMD_FILE != "" ]]; then
+ updateDialog "wait" "Already installed from App Store. Not replaced."
+ sleep 4
+ fi
+ cleanupAndExit 23 "App previously installed from App Store, and we respect that" ERROR
fi
fi
else
@@ -427,6 +446,7 @@ installAppWithPath() { # $1: path to app to install in $targetDir
# verify with spctl
printlog "Verifying: $appPath" INFO
+ updateDialog "wait" "Verifying..."
printlog "App size: $(du -sh "$appPath")" DEBUG
appVerify=$(spctl -a -vv "$appPath" 2>&1 )
appVerifyStatus=$(echo $?)
@@ -454,6 +474,10 @@ installAppWithPath() { # $1: path to app to install in $targetDir
printlog "notifying"
displaynotification "$message" "No update for $name!"
fi
+ if [[ $DIALOG_CMD_FILE != "" ]]; then
+ updateDialog "wait" "Latest version already installed..."
+ sleep 2
+ fi
cleanupAndExit 0 "No new version to install" REG
else
printlog "Using force to install anyway."
@@ -475,7 +499,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." ERROR
+ cleanupAndExit 15 "Installed macOS is too old for this app." ERROR
fi
fi
@@ -534,7 +558,7 @@ installAppWithPath() { # $1: path to app to install in $targetDir
deduplicatelogs "$CLIoutput"
if [ $CLIstatus -ne 0 ] ; then
- cleanupAndExit 3 "Error installing $mountname/$CLIInstaller $CLIArguments error:\n$logoutput" ERROR
+ cleanupAndExit 16 "Error installing $mountname/$CLIInstaller $CLIArguments error:\n$logoutput" ERROR
else
printlog "Succesfully ran $mountname/$CLIInstaller $CLIArguments" INFO
fi
@@ -572,6 +596,7 @@ installFromDMG() {
installFromPKG() {
# verify with spctl
printlog "Verifying: $archiveName"
+ updateDialog "wait" "Verifying..."
printlog "File list: $(ls -lh "$archiveName")" DEBUG
printlog "File type: $(file "$archiveName")" DEBUG
spctlOut=$(spctl -a -vv -t install "$archiveName" 2>&1 )
@@ -619,6 +644,10 @@ installFromPKG() {
printlog "notifying"
displaynotification "$message" "No update for $name!"
fi
+ if [[ $DIALOG_CMD_FILE != "" ]]; then
+ updateDialog "wait" "Latest version already installed..."
+ sleep 2
+ fi
cleanupAndExit 0 "No new version to install" REQ
else
printlog "Using force to install anyway."
@@ -639,8 +668,29 @@ installFromPKG() {
# install pkg
printlog "Installing $archiveName to $targetDir"
- pkgInstall=$(installer -verbose -dumplog -pkg "$archiveName" -tgt "$targetDir" 2>&1)
- pkgInstallStatus=$(echo $?)
+
+ if [[ $DIALOG_CMD_FILE != "" ]]; then
+ # pipe
+ pipe="$tmpDir/installpipe"
+ # initialise named pipe for installer output
+ initNamedPipe create $pipe
+
+ # run the pipe read in the background
+ readPKGInstallPipe $pipe "$DIALOG_CMD_FILE" & installPipePID=$!
+ printlog "listening to output of installer with pipe $pipe and command file $DIALOG_CMD_FILE on PID $installPipePID" DEBUG
+
+ pkgInstall=$(installer -verboseR -pkg "$archiveName" -tgt "$targetDir" 2>&1 | tee $pipe)
+ pkgInstallStatus=$pipestatus[1]
+ # because we are tee-ing the output, we want the pipe status of the first command in the chain, not the most recent one
+ killProcess $installPipePID
+
+ else
+ pkgInstall=$(installer -verbose -dumplog -pkg "$archiveName" -tgt "$targetDir" 2>&1)
+ pkgInstallStatus=$(echo $?)
+ fi
+
+
+
sleep 1
pkgEndTime=$(date "+$LogDateFormat")
pkgInstall+=$(echo "\nOutput of /var/log/install.log below this line.\n")
@@ -732,7 +782,7 @@ installPkgInZip() {
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
+ cleanupAndExit 21 "couldn't find pkg in zip $archiveName" ERROR
fi
# it is now safe to overwrite archiveName for installFromPKG
archiveName="${filearray[1]}"
@@ -745,7 +795,7 @@ installPkgInZip() {
findfiles=$(find "$tmpDir" -iname "$pkgName")
filearray=( ${(f)findfiles} )
if [[ ${#filearray} -eq 0 ]]; then
- cleanupAndExit 20 "couldn't find pkg “$pkgName” in zip $archiveName" ERROR
+ cleanupAndExit 21 "couldn't find pkg “$pkgName” in zip $archiveName" ERROR
fi
# it is now safe to overwrite archiveName for installFromPKG
archiveName="${filearray[1]}"
@@ -768,7 +818,7 @@ installAppInDmgInZip() {
findfiles=$(find "$tmpDir" -iname "*.dmg" -maxdepth 2 )
filearray=( ${(f)findfiles} )
if [[ ${#filearray} -eq 0 ]]; then
- cleanupAndExit 20 "couldn't find dmg in zip $archiveName" ERROR
+ cleanupAndExit 22 "couldn't find dmg in zip $archiveName" ERROR
fi
archiveName="$(basename ${filearray[1]})"
# it is now safe to overwrite archiveName for installFromDMG
@@ -820,7 +870,8 @@ runUpdateTool() {
finishing() {
printlog "Finishing..."
- sleep 10 # wait a moment to let spotlight catch up
+
+ sleep 3 # wait a moment to let spotlight catch up
getAppVersion
if [[ -z $appversion ]]; then
@@ -868,3 +919,113 @@ hasDisplaySleepAssertion() {
return 1
}
+initNamedPipe() {
+ # create or delete a named pipe
+ # commands are "create" or "delete"
+
+ local cmd=$1
+ local pipe=$2
+ case $cmd in
+ "create")
+ if [[ -e $pipe ]]; then
+ rm $pipe
+ fi
+ # make named pipe
+ mkfifo -m 644 $pipe
+ ;;
+ "delete")
+ # clean up
+ rm $pipe
+ ;;
+ *)
+ ;;
+ esac
+}
+
+readDownloadPipe() {
+ # reads from a previously created named pipe
+ # output from curl with --progress-bar. % downloaded is read in and then sent to the specified log file
+ local pipe=$1
+ local log=${2:-$DIALOG_CMD_FILE}
+ # set up read from pipe
+ while IFS= read -k 1 -u 0 char; do
+ if [[ $char =~ [0-9] ]]; then
+ keep=1
+ fi
+
+ if [[ $char == % ]]; then
+ updateDialog $progress "Downloading..."
+ progress=""
+ keep=0
+ fi
+
+ if [[ $keep == 1 ]]; then
+ progress="$progress$char"
+ fi
+ done < $pipe
+}
+
+readPKGInstallPipe() {
+ # reads from a previously created named pipe
+ # output from installer with -verboseR. % install status is read in and then sent to the specified log file
+ local pipe=$1
+ local log=${2:-$DIALOG_CMD_FILE}
+ local appname=${3:-$name}
+
+ while read -k 1 -u 0 char; do
+ if [[ $char == % ]]; then
+ keep=1
+ fi
+ if [[ $char =~ [0-9] && $keep == 1 ]]; then
+ progress="$progress$char"
+ fi
+ if [[ $char == . && $keep == 1 ]]; then
+ updateDialog $progress "Installing..."
+ progress=""
+ keep=0
+ fi
+ done < $pipe
+}
+
+killProcess() {
+ # will silently kill the specified PID
+ builtin kill $1 2>/dev/null
+}
+
+updateDialog() {
+ local state=$1
+ local message=$2
+ local listitem=${3:-$DIALOG_LIST_ITEM_NAME}
+ local cmd_file=${4:-$DIALOG_CMD_FILE}
+ local progress=""
+
+ if [[ $state =~ '^[0-9]' \
+ || $state == "reset" \
+ || $state == "increment" \
+ || $state == "complete" \
+ || $state == "indeterminate" ]]; then
+ progress=$state
+ fi
+
+ # when to cmdfile is set, do nothing
+ if [[ $cmd_file == "" ]]; then
+ return
+ fi
+
+ if [[ $listitem == "" ]]; then
+ # no listitem set, update main progress bar and progress text
+ if [[ $progress != "" ]]; then
+ echo "progress: $progress" >> $cmd_file
+ fi
+ if [[ $message != "" ]]; then
+ echo "progresstext: $name - $message" >> $cmd_file
+ fi
+ else
+ # list item has a value, so we update the progress and text in the list
+ if [[ $progress != "" ]]; then
+ echo "listitem: title: $listitem, statustext: $message, progress: $progress" >> $cmd_file
+ else
+ echo "listitem: title: $listitem, statustext: $message, status: $state" >> $cmd_file
+ fi
+ fi
+}
diff --git a/fragments/header.sh b/fragments/header.sh
index 9f4a7cc..e58b48c 100644
--- a/fragments/header.sh
+++ b/fragments/header.sh
@@ -7,7 +7,7 @@ label="" # if no label is sent to the script, this will be used
# 2020-2021 Installomator
#
# inspired by the download scripts from William Smith and Sander Schram
-#
+#
# Contributers:
# Armin Briegel - @scriptingosx
# Isaac Ordonez - @issacatmann
@@ -23,7 +23,7 @@ export PATH=/usr/bin:/bin:/usr/sbin:/sbin
# set to 0 for production, 1 or 2 for debugging
# while debugging, items will be downloaded to the parent directory of this script
# also no actual installation will be performed
-# debug mode 1 will download to the directory the script is run in, but will not check the version
+# debug mode 1 will download to the directory the script is run in, but will not check the version
# debug mode 2 will download to the temp directory, check for blocking processes, check the version, but will not install anything or remove the current version
DEBUG=1
@@ -34,7 +34,6 @@ NOTIFY=success
# - silent no notifications
# - all all notifications (great for Self Service installation)
-
# behavior when blocking processes are found
BLOCKING_PROCESS_ACTION=tell_user
# options:
@@ -81,6 +80,7 @@ LOGO=appstore
# - mosylem Mosyle Manager (Education)
# - addigy Addigy
# - microsoft Microsoft Endpoint Manager (Intune)
+# - ws1 Workspace ONE (AirWatch)
# 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).
@@ -139,6 +139,26 @@ IGNORE_DND_APPS=""
# IGNORE_DND_APPS="firefox,Google Chrome,Safari,Microsoft Edge,Opera,Amphetamine,caffeinate"
+# Swift Dialog integration
+
+# These variables will allow Installomator to communicate progress with Swift Dialog
+# https://github.com/bartreardon/swiftDialog
+
+# This requires Swift Dialog 2.11.2 or higher.
+
+DIALOG_CMD_FILE=""
+# When this variable is set, Installomator will write Swift Dialog commands to this path.
+# Installomator will not launch Swift Dialog. The process calling Installomator will have
+# launch and configure Swift Dialog to listen to this file.
+# See `MDM/swiftdialog_example.sh` for an example.
+
+DIALOG_LIST_ITEM_NAME=""
+# When this variable is set, progress for downloads and installs will be sent to this
+# listitem.
+# When the variable is unset, progress will be sent to Swift Dialog's main progress bar.
+
+
+
# NOTE: How labels work
# Each workflow label needs to be listed in the case statement below.
@@ -184,7 +204,7 @@ IGNORE_DND_APPS=""
# How we get version number from app. Possible values:
# - CFBundleShortVersionString
# - CFBundleVersion
-# Not all software titles uses fields the same.
+# Not all software titles uses fields the same.
# See Opera label.
#
# - appCustomVersion(){}: (optional function)
diff --git a/fragments/labels/abetterfinderrename11.sh b/fragments/labels/abetterfinderrename11.sh
new file mode 100644
index 0000000..015de0a
--- /dev/null
+++ b/fragments/labels/abetterfinderrename11.sh
@@ -0,0 +1,7 @@
+abetterfinderrename11)
+ name="A Better Finder Rename 11"
+ type="dmg"
+ downloadURL="https://www.publicspace.net/download/ABFRX11.dmg"
+ appNewVersion=$(curl -fs "https://www.publicspace.net/app/signed_abfr11.xml" | xpath '(//rss/channel/item/enclosure/@sparkle:version)' 2>/dev/null | cut -d '"' -f 2)
+ expectedTeamID="7Y9KW4ND8W"
+ ;;
diff --git a/fragments/labels/acroniscyberprotectconnect.sh b/fragments/labels/acroniscyberprotectconnect.sh
new file mode 100644
index 0000000..8538bee
--- /dev/null
+++ b/fragments/labels/acroniscyberprotectconnect.sh
@@ -0,0 +1,9 @@
+acroniscyberprotectconnect|\
+remotix)
+ name="Acronis Cyber Protect Connect"
+ type="dmg"
+ downloadURL="https://go.acronis.com/AcronisCyberProtectConnect_ForMac"
+ versionKey="CFBundleVersion"
+ appNewVersion=$(curl -fsIL "${downloadURL}" | grep -i "^location" | sed -E 's/.*\/[a-zA-Z]*-[0-9.]*-([0-9.]*)\.dmg/\1/g')
+ expectedTeamID="ZU2TV78AA6"
+ ;;
diff --git a/fragments/labels/acroniscyberprotectconnectagent.sh b/fragments/labels/acroniscyberprotectconnectagent.sh
new file mode 100644
index 0000000..8310357
--- /dev/null
+++ b/fragments/labels/acroniscyberprotectconnectagent.sh
@@ -0,0 +1,11 @@
+acroniscyberprotectconnectagent|\
+remotixagent)
+ name="Acronis Cyber Protect Connect Agent"
+ type="pkg"
+ #packageID="com.nulana.rxagentmac"
+ downloadURL="https://go.acronis.com/AcronisCyberProtectConnect_AgentForMac"
+ versionKey="CFBundleVersion"
+ appNewVersion=$(curl -fsIL "${downloadURL}" | grep -i "^location" | sed -E 's/.*\/[a-zA-Z]*-[0-9.]*-([0-9.]*)\.pkg/\1/g')
+ expectedTeamID="H629V387SY"
+ blockingProcesses=( NONE )
+ ;;
diff --git a/fragments/labels/adobeacrobatprodc.sh b/fragments/labels/adobeacrobatprodc.sh
new file mode 100644
index 0000000..308648f
--- /dev/null
+++ b/fragments/labels/adobeacrobatprodc.sh
@@ -0,0 +1,8 @@
+adobeacrobatprodc)
+ name="Adobe Acrobat Pro DC"
+ type="pkgInDmg"
+ downloadURL="https://trials.adobe.com/AdobeProducts/APRO/Acrobat_HelpX/osx10/Acrobat_DC_Web_WWMUI.dmg"
+ expectedTeamID="JQ525L2MZD"
+ blockingProcesses=( "Acrobat Pro DC" )
+ Company="Adobe"
+ ;;
diff --git a/fragments/labels/adobecreativeclouddesktop.sh b/fragments/labels/adobecreativeclouddesktop.sh
index 95582db..e12b911 100644
--- a/fragments/labels/adobecreativeclouddesktop.sh
+++ b/fragments/labels/adobecreativeclouddesktop.sh
@@ -1,18 +1,24 @@
adobecreativeclouddesktop)
name="Adobe Creative Cloud"
- #appName="Install.app"
+ appName="Install.app"
type="dmg"
- adobeurl="https://helpx.adobe.com/download-install/kb/creative-cloud-desktop-app-download.html"
- if [[ $(arch) == "arm64" ]]; then
- downloadURL=$(curl -fs "$adobeurl" | xmllint -html -xpath "string(//a[contains(@href,'osx10')][contains(text(),'Download')]/@href)" - 2> /dev/null)
- elif [[ $(arch) == "i386" ]]; then
- downloadURL=$(curl -fs "$adobeurl" | xmllint -html -xpath "string(//a[contains(@href,'macarm64')][contains(text(),'Download')]/@href)" - 2> /dev/null)
+ if pgrep -q "Adobe Installer"; then
+ printlog "Adobe Installer is running, not a good time to update." WARN
+ printlog "################## End $APPLICATION \n\n" INFO
+ exit 75
fi
- #downloadURL=$(curl -fs "https://helpx.adobe.com/download-install/kb/creative-cloud-desktop-app-download.html" | grep -o "https*.*dmg" | head -1)
- appNewVersion=$(curl -fs "https://helpx.adobe.com/creative-cloud/release-note/cc-release-notes.html" | grep "mandatory" | head -1 | grep -o "Version *.* released" | cut -d " " -f2)
+ if [[ "$(arch)" == "arm64" ]]; then
+ downloadURL=$(curl -fs "https://helpx.adobe.com/download-install/kb/creative-cloud-desktop-app-download.html" | grep -o 'https.*macarm64.*dmg' | head -1 | cut -d '"' -f1)
+ else
+ downloadURL=$(curl -fs "https://helpx.adobe.com/download-install/kb/creative-cloud-desktop-app-download.html" | grep -o 'https.*osx10.*dmg' | head -1 | cut -d '"' -f1)
+ fi
+ #appNewVersion=$(curl -fs "https://helpx.adobe.com/creative-cloud/release-note/cc-release-notes.html" | grep "mandatory" | head -1 | grep -o "Version *.* released" | cut -d " " -f2)
+ appNewVersion=$(echo $downloadURL | grep -o '[^x]*$' | cut -d '.' -f 1 | sed 's/_/\./g')
+ targetDir="/Applications/Utilities/Adobe Creative Cloud/ACC/"
installerTool="Install.app"
CLIInstaller="Install.app/Contents/MacOS/Install"
CLIArguments=(--mode=silent)
expectedTeamID="JQ525L2MZD"
+ blockingProcesses=( "Creative Cloud" )
Company="Adobe"
;;
diff --git a/fragments/labels/adobereaderdc-install.sh b/fragments/labels/adobereaderdc-install.sh
new file mode 100644
index 0000000..060e3cc
--- /dev/null
+++ b/fragments/labels/adobereaderdc-install.sh
@@ -0,0 +1,27 @@
+adobereaderdc-install)
+ name="Adobe Acrobat Reader DC"
+ type="pkgInDmg"
+ printlog "Changing IFS for Adobe Reader" INFO
+ SAVEIFS=$IFS
+ IFS=$'\n'
+ versions=( $( curl -s https://www.adobe.com/devnet-docs/acrobatetk/tools/ReleaseNotesDC/index.html | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+"| head -n 30) )
+ local version
+ for version in $versions; do
+ version="${version//.}"
+ printlog "trying version: $version" INFO
+ local httpstatus=$(curl -X HEAD -s "https://ardownload2.adobe.com/pub/adobe/reader/mac/AcrobatDC/${version}/AcroRdrDC_${version}_MUI.dmg" --write-out "%{http_code}")
+ printlog "HTTP status for Adobe Reader full installer URL https://ardownload2.adobe.com/pub/adobe/reader/mac/AcrobatDC/${version}/AcroRdrDC_${version}_MUI.dmg is $httpstatus" DEBUG
+ if [[ "${httpstatus}" == "200" ]]; then
+ downloadURL="https://ardownload2.adobe.com/pub/adobe/reader/mac/AcrobatDC/${version}/AcroRdrDC_${version}_MUI.dmg"
+ unset httpstatus
+ break
+ fi
+ done
+ unset version
+ IFS=$SAVEIFS
+ appNewVersion=$i
+ expectedTeamID="JQ525L2MZD"
+ blockingProcesses=( "AdobeReader" )
+ Company="Adobe"
+ PatchName="AcrobatReader"
+ ;;
diff --git a/fragments/labels/adobereaderdc-update.sh b/fragments/labels/adobereaderdc-update.sh
index a409cf5..7a81c57 100644
--- a/fragments/labels/adobereaderdc-update.sh
+++ b/fragments/labels/adobereaderdc-update.sh
@@ -1,9 +1,44 @@
adobereaderdc-update)
name="Adobe Acrobat Reader DC"
type="pkgInDmg"
- downloadURL=$(adobecurrent=`curl --fail --silent https://armmf.adobe.com/arm-manifests/mac/AcrobatDC/reader/current_version.txt | tr -d '.'` && echo https://ardownload2.adobe.com/pub/adobe/reader/mac/AcrobatDC/"$adobecurrent"/AcroRdrDC_"$adobecurrent"_MUI.dmg)
+ if [[ -d "/Applications/Adobe Acrobat Reader DC.app" ]]; then
+ printlog "Found /Applications/Adobe Acrobat Reader DC.app"
+ mkdir -p "/Library/Application Support/Adobe/Acrobat/11.0"
+ defaults write "/Library/Application Support/Adobe/Acrobat/11.0/com.adobe.Acrobat.InstallerOverrides.plist" ReaderAppPath "/Applications/Adobe Acrobat Reader DC.app"
+ if ! defaults read "/Applications/Adobe Acrobat Reader DC.app/Contents/Resources/AcroLocale.plist" ; then
+ printlog "Missing locale data, this will cause the updater to fail. Deleting Adobe Acrobat Reader DC.app and installing fresh." WARN
+ rm -Rf "/Applications/Adobe Acrobat Reader DC.app"
+ if [[ $1 == "/" ]]; then
+ printlog "Running through Jamf: $0." INFO
+ $0 $1 $2 $3 adobereaderdc-install ${5} ${6} ${7} ${8} ${9} ${10} ${11}
+ else
+ printlog "Installomator running locally: $0." INFO
+ $0 adobereaderdc-install ${2} ${3} ${4} ${5} ${6} ${7} ${8} ${9} ${10} ${11}
+ fi
+ fi
+ fi
+ adobecurrent=$(curl -sL https://armmf.adobe.com/arm-manifests/mac/AcrobatDC/reader/current_version.txt | tr -d '.')
+ if [[ "${adobecurrent}" != <-> ]]; then
+ printlog "Got an invalid response for the Adobe Reader Current Version: ${adobecurrent}" ERROR
+ printlog "################## End $APPLICATION \n\n" INFO
+ exit 50
+ fi
+ downloadURL=$(echo https://ardownload2.adobe.com/pub/adobe/reader/mac/AcrobatDC/"$adobecurrent"/AcroRdrDCUpd"$adobecurrent"_MUI.dmg)
+ reader_preinstall() {
+ if pgrep -a "AdobeReader" >/dev/null 2>&1; then
+ printlog "AdobeReader is still running, forcefully killing." WARN
+ killall AdobeReader
+ fi
+ }
+ preinstall="reader_preinstall"
+ updateTool="/usr/local/bin/RemoteUpdateManager"
+ updateToolArguments=( --productVersions=RDR )
appNewVersion=$(curl -s https://armmf.adobe.com/arm-manifests/mac/AcrobatDC/reader/current_version.txt)
- #appNewVersion=$(curl -s -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15)" https://get.adobe.com/reader/ | grep ">Version" | sed -E 's/.*Version 20([0-9.]*)<.*/\1/g') # credit: Søren Theilgaard (@theilgaard)
+ updateToolLog="/Users/$currentUser/Library/Logs/RemoteUpdateManager.log"
+ updateToolLogDateFormat="%m/%d/%y %H:%M:%S"
expectedTeamID="JQ525L2MZD"
blockingProcesses=( "AdobeReader" )
+ Company=Adobe
+ PatchName=AcrobatReader
+ PatchSkip="YES"
;;
diff --git a/fragments/labels/archiwareb2go.sh b/fragments/labels/archiwareb2go.sh
new file mode 100644
index 0000000..85f30a8
--- /dev/null
+++ b/fragments/labels/archiwareb2go.sh
@@ -0,0 +1,10 @@
+archiwareb2go)
+ name="P5 Workstation"
+ type="pkgInDmg"
+ packageID="com.archiware.presstore"
+ appNewVersion=$(curl -sf https://www.archiware.com/download-p5 | grep -m 1 "ARCHIWARE P5 Version" | sed "s|.*Version \(.*\) -.*|\\1|")
+ downloadURL=$(appNrVersion=`sed 's/[^0-9]//g' <<< $appNewVersion` && echo https://p5-downloads.s3.amazonaws.com/awpst"$appNrVersion"-darwin.dmg)
+ pkgName=$(appNrVersion=`sed 's/[^0-9]//g' <<< $appNewVersion` && echo P5-Workstation-"$appNrVersion"-Install.pkg)
+ expectedTeamID="5H5EU6F965"
+ # blockingProcesses=( nsd )
+ ;;
diff --git a/fragments/labels/archiwarepst.sh b/fragments/labels/archiwarepst.sh
new file mode 100644
index 0000000..9ce9b29
--- /dev/null
+++ b/fragments/labels/archiwarepst.sh
@@ -0,0 +1,10 @@
+archiwarepst)
+ name="P5"
+ type="pkgInDmg"
+ packageID="com.archiware.presstore"
+ appNewVersion=$(curl -sf https://www.archiware.com/download-p5 | grep -m 1 "ARCHIWARE P5 Version" | sed "s|.*Version \(.*\) -.*|\\1|")
+ downloadURL=$(appNrVersion=`sed 's/[^0-9]//g' <<< $appNewVersion` && echo https://p5-downloads.s3.amazonaws.com/awpst"$appNrVersion"-darwin.dmg)
+ pkgName=$(appNrVersion=`sed 's/[^0-9]//g' <<< $appNewVersion` && echo P5-"$appNrVersion"-Install.pkg)
+ expectedTeamID="5H5EU6F965"
+ # blockingProcesses=( nsd )
+ ;;
diff --git a/fragments/labels/audacity.sh b/fragments/labels/audacity.sh
index a5868d3..3a49708 100644
--- a/fragments/labels/audacity.sh
+++ b/fragments/labels/audacity.sh
@@ -1,7 +1,13 @@
audacity)
name="Audacity"
type="dmg"
- downloadURL=$(downloadURLFromGit audacity audacity)
+ if [[ $(arch) == "arm64" ]]; then
+ archiveName="audacity-macOS-[0-9.]*-arm64.dmg"
+ downloadURL=$(downloadURLFromGit audacity audacity)
+ elif [[ $(arch) == "i386" ]]; then
+ archiveName="audacity-macOS-[0-9.]*-x86_64.dmg"
+ downloadURL=$(downloadURLFromGit audacity audacity)
+ fi
appNewVersion=$(versionFromGit audacity audacity)
expectedTeamID="AWEYX923UX"
;;
diff --git a/fragments/labels/awsvpnclient.sh b/fragments/labels/awsvpnclient.sh
index dbc4885..1e97833 100644
--- a/fragments/labels/awsvpnclient.sh
+++ b/fragments/labels/awsvpnclient.sh
@@ -3,5 +3,5 @@ awsvpnclient)
type="pkg"
downloadURL="https://d20adtppz83p9s.cloudfront.net/OSX/latest/AWS_VPN_Client.pkg"
expectedTeamID="94KV3E626L"
- appNewVersion=$(curl -is "https://beta2.communitypatch.com/jamf/v1/ba1efae22ae74a9eb4e915c31fef5dd2/patch/AWSVPNClient" | grep currentVersion | tr ',' '\n' | grep currentVersion | cut -d '"' -f 4)
+ #appNewVersion=$(curl -is "https://beta2.communitypatch.com/jamf/v1/ba1efae22ae74a9eb4e915c31fef5dd2/patch/AWSVPNClient" | grep currentVersion | tr ',' '\n' | grep currentVersion | cut -d '"' -f 4)
;;
diff --git a/fragments/labels/bitrix24.sh b/fragments/labels/bitrix24.sh
new file mode 100644
index 0000000..033cb81
--- /dev/null
+++ b/fragments/labels/bitrix24.sh
@@ -0,0 +1,8 @@
+bitrix24)
+ name="Bitrix24"
+ type="dmg"
+ archiveName="bitrix24_desktop.dmg"
+ downloadURL="https://dl.bitrix24.com/b24/bitrix24_desktop.dmg"
+ expectedTeamID="5B3T3A994N"
+ blockingProcesses=( "Bitrix24" )
+ ;;
\ No newline at end of file
diff --git a/fragments/labels/boxtools.sh b/fragments/labels/boxtools.sh
index 11690f5..c6d3cb1 100644
--- a/fragments/labels/boxtools.sh
+++ b/fragments/labels/boxtools.sh
@@ -2,5 +2,6 @@ boxtools)
name="Box Tools"
type="pkg"
downloadURL="https://box-installers.s3.amazonaws.com/boxedit/mac/currentrelease/BoxToolsInstaller.pkg"
+ packageID="com.box.boxtools.installer.boxedit"
expectedTeamID="M683GB7CPW"
;;
diff --git a/fragments/labels/carboncopycloner.sh b/fragments/labels/carboncopycloner.sh
new file mode 100644
index 0000000..a7fb869
--- /dev/null
+++ b/fragments/labels/carboncopycloner.sh
@@ -0,0 +1,7 @@
+carboncopycloner)
+ name="Carbon Copy Cloner"
+ type="zip"
+ downloadURL=$(curl -fsIL "https://bombich.com/software/download_ccc.php?v=latest" | grep -i ^location | sed -E 's/.*(https.*\.zip).*/\1/g')
+ appNewVersion=$(sed -E 's/.*-([0-9.]*)\.zip/\1/g' <<< $downloadURL | sed 's/\.[^.]*$//')
+ expectedTeamID="L4F2DED5Q7"
+ ;;
diff --git a/fragments/labels/charles.sh b/fragments/labels/charles.sh
new file mode 100644
index 0000000..0c70782
--- /dev/null
+++ b/fragments/labels/charles.sh
@@ -0,0 +1,7 @@
+charles)
+ name="Charles"
+ type="dmg"
+ appNewVersion=$(curl -fs https://www.charlesproxy.com/download/latest-release/ | sed -nE 's/.*version.*value="([^"]*).*/\1/p')
+ downloadURL="https://www.charlesproxy.com/assets/release/$appNewVersion/charles-proxy-$appNewVersion.dmg"
+ expectedTeamID="9A5PCU4FSD"
+ ;;
\ No newline at end of file
diff --git a/fragments/labels/chronoagent.sh b/fragments/labels/chronoagent.sh
new file mode 100644
index 0000000..124238d
--- /dev/null
+++ b/fragments/labels/chronoagent.sh
@@ -0,0 +1,11 @@
+chronoagent)
+ name="ChronoAgent"
+ type="pkgInDmg"
+ # packageID="com.econtechnologies.preference.chronoagent"
+ # versionKey="CFBundleVersion"
+ # None of the above can read out the installed version
+ releaseURL="https://www.econtechnologies.com/UC/updatecheck.php?prod=ChronoAgent&lang=en&plat=mac&os=10.14.1&hw=i64&req=1&vers=#"
+ appNewVersion=$(curl -sf $releaseURL | sed -r 's/.*VERSION=([^<]+).*/\1/')
+ downloadURL="https://downloads.econtechnologies.com/CA_Mac_Download.dmg"
+ expectedTeamID="9U697UM7YX"
+ ;;
diff --git a/fragments/labels/chronosync.sh b/fragments/labels/chronosync.sh
new file mode 100644
index 0000000..dcec55a
--- /dev/null
+++ b/fragments/labels/chronosync.sh
@@ -0,0 +1,8 @@
+chronosync)
+ name="ChronoSync"
+ type="pkgInDmg"
+ releaseURL="https://www.econtechnologies.com/UC/updatecheck.php?prod=ChronoSync&lang=en&plat=mac&os=10.14.1&hw=i64&req=1&vers=#"
+ appNewVersion=$(curl -sf $releaseURL | sed -r 's/.*VERSION=([^<]+).*/\1/')
+ downloadURL="https://downloads.econtechnologies.com/CS4_Download.dmg"
+ expectedTeamID="9U697UM7YX"
+ ;;
diff --git a/fragments/labels/clevershare2.sh b/fragments/labels/clevershare2.sh
index 452ffde..a26d7b3 100644
--- a/fragments/labels/clevershare2.sh
+++ b/fragments/labels/clevershare2.sh
@@ -1,7 +1,8 @@
clevershare2)
name="Clevershare"
type="dmg"
- downloadURL=$(curl -fs https://www.clevertouch.com/eu/clevershare2g | grep -i -o -E "https.*Mac.*\.dmg")
- appNewVersion=$( echo "${downloadURL}" | sed -E 's/.*\/[a-zA-Z-]*_Mac\.([0-9.]*)\.[0-9]*\.dmg$/\1/g' )
+ printlog "Label for $name broken in test" ERROR
+ downloadURL=$(curl -fs https://www.clevertouch.com/eu/clevershare2g | grep -i -o -E "https.*notarized.*\.dmg")
+ appNewVersion=$(echo "${downloadURL}" | sed -E 's/.*\/([0-9.]*)\/[0-9]*\/.*\.dmg$/\1/')
expectedTeamID="P76M9BE8DQ"
;;
diff --git a/fragments/labels/cocoapods.sh b/fragments/labels/cocoapods.sh
new file mode 100644
index 0000000..1ebc7a3
--- /dev/null
+++ b/fragments/labels/cocoapods.sh
@@ -0,0 +1,7 @@
+cocoapods)
+ name="CocoaPods"
+ type="bz2"
+ downloadURL="$(downloadURLFromGit CocoaPods CocoaPods-app)"
+ appNewVersion="$(versionFromGit CocoaPods CocoaPods-app)"
+ expectedTeamID="AX2Q2BH2XR"
+ ;;
diff --git a/fragments/labels/coconutbattery.sh b/fragments/labels/coconutbattery.sh
new file mode 100644
index 0000000..efdf088
--- /dev/null
+++ b/fragments/labels/coconutbattery.sh
@@ -0,0 +1,7 @@
+coconutbattery)
+ name="coconutBattery"
+ type="zip"
+ downloadURL="https://coconut-flavour.com/downloads/coconutBattery_latest.zip"
+ appNewVersion=$(curl -fs https://www.coconut-flavour.com/coconutbattery/ | grep "" | sed -e 's/.*coconutBattery \(.*\) - by coconut-flavour.co.*/\1/')
+ expectedTeamID="R5SC3K86L5"
+ ;;
diff --git a/fragments/labels/coderunner.sh b/fragments/labels/coderunner.sh
index 5794101..e52ca0f 100644
--- a/fragments/labels/coderunner.sh
+++ b/fragments/labels/coderunner.sh
@@ -1,7 +1,7 @@
coderunner)
- # credit: Erik Stam (@erikstam)
name="CodeRunner"
type="zip"
downloadURL="https://coderunnerapp.com/download"
+ appNewVersion=$(curl -fsIL ${downloadURL} | grep -i "^location" | cut -d " " -f2 | sed -E 's/.*CodeRunner-([0-9.]*).zip/\1/')
expectedTeamID="R4GD98AJF9"
;;
diff --git a/fragments/labels/colourcontrastanalyser.sh b/fragments/labels/colourcontrastanalyser.sh
index 086569c..15413c4 100644
--- a/fragments/labels/colourcontrastanalyser.sh
+++ b/fragments/labels/colourcontrastanalyser.sh
@@ -1,5 +1,5 @@
colourcontrastanalyser)
- name="Colour Contrast Analyser (CCA)"
+ name="Colour Contrast Analyser"
type="dmg"
downloadURL=$(downloadURLFromGit ThePacielloGroup CCAe)
appNewVersion=$(versionFromGit ThePacielloGroup CCAe)
diff --git a/fragments/labels/cricutdesignspace.sh b/fragments/labels/cricutdesignspace.sh
new file mode 100644
index 0000000..e512bba
--- /dev/null
+++ b/fragments/labels/cricutdesignspace.sh
@@ -0,0 +1,7 @@
+cricutdesignspace)
+ name="Cricut Design Space"
+ type="dmg"
+ appNewVersion=$(getJSONValue "$(curl -fsL https://s3-us-west-2.amazonaws.com/staticcontent.cricut.com/a/software/osx-native/latest.json)" "rolloutVersion")
+ downloadURL=$(getJSONValue $(curl -fsL "https://apis.cricut.com/desktopdownload/InstallerFile?shard=a&operatingSystem=osxnative&fileName=CricutDesignSpace-Install-v${appNewVersion}.dmg") "result")
+ expectedTeamID="25627ZFVT7"
+ ;;
diff --git a/fragments/labels/cryptomator.sh b/fragments/labels/cryptomator.sh
index 1f3572f..2a76cf1 100644
--- a/fragments/labels/cryptomator.sh
+++ b/fragments/labels/cryptomator.sh
@@ -1,6 +1,12 @@
cryptomator)
name="Cryptomator"
type="dmg"
+ if [[ $(arch) == "arm64" ]]; then
+ archiveName="Cryptomator-[0-9.]*-arm64.dmg"
+
+ elif [[ $(arch) == "i386" ]]; then
+ archiveName="Cryptomator-[0-9.]*.dmg"
+ fi
downloadURL=$(downloadURLFromGit cryptomator cryptomator)
appNewVersion=$(versionFromGit cryptomator cryptomator)
expectedTeamID="YZQJQUHA3L"
diff --git a/fragments/labels/cytoscape.sh b/fragments/labels/cytoscape.sh
new file mode 100644
index 0000000..7b722ef
--- /dev/null
+++ b/fragments/labels/cytoscape.sh
@@ -0,0 +1,11 @@
+cytoscape)
+ name="Cytoscape"
+ #appName="Cytoscape Installer.app"
+ type="dmg"
+ downloadURL="$(downloadURLFromGit cytoscape cytoscape)"
+ appNewVersion="$(versionFromGit cytoscape cytoscape)"
+ installerTool="Cytoscape Installer.app"
+ CLIInstaller="Cytoscape Installer.app/Contents/MacOS/JavaApplicationStub"
+ CLIArguments=(-q)
+ expectedTeamID="35LDCJ33QT"
+ ;;
diff --git a/fragments/labels/dangerzone.sh b/fragments/labels/dangerzone.sh
index 1bdeada..730ae3d 100644
--- a/fragments/labels/dangerzone.sh
+++ b/fragments/labels/dangerzone.sh
@@ -1,7 +1,7 @@
dangerzone)
name="Dangerzone"
type="dmg"
- downloadURL="$(downloadURLFromGit firstlookmedia dangerzone)"
- appNewVersion="$(versionFromGit firstlookmedia dangerzone)"
+ downloadURL="$(downloadURLFromGit freedomofpress dangerzone)"
+ appNewVersion="$(versionFromGit freedomofpress dangerzone)"
expectedTeamID="N9B95FDWH4"
;;
diff --git a/fragments/labels/drawio.sh b/fragments/labels/drawio.sh
index bd0241b..d15772b 100644
--- a/fragments/labels/drawio.sh
+++ b/fragments/labels/drawio.sh
@@ -1,7 +1,7 @@
drawio)
name="draw.io"
type="dmg"
- archiveName="draw.io-universal-[0-9.]*.dmg"
+ archiveName="draw.io-universal-[0-9.]*.dmg$"
downloadURL="$(downloadURLFromGit jgraph drawio-desktop)"
appNewVersion="$(versionFromGit jgraph drawio-desktop)"
expectedTeamID="UZEUFB4N53"
diff --git a/fragments/labels/duckduckgo.sh b/fragments/labels/duckduckgo.sh
index a5cb4e0..e2a0768 100644
--- a/fragments/labels/duckduckgo.sh
+++ b/fragments/labels/duckduckgo.sh
@@ -2,9 +2,9 @@ duckduckgo)
name="DuckDuckGo"
type="dmg"
#downloadURL="https://staticcdn.duckduckgo.com/macos-desktop-browser/duckduckgo.dmg"
- #downloadURL=$(curl -fs https://staticcdn.duckduckgo.com/macos-desktop-browser/appcast.xml | xpath '(//rss/channel/item/enclosure/@url)[last()]' 2>/dev/null | cut -d '"' -f2)
- downloadURL=$(curl -fs https://staticcdn.duckduckgo.com/macos-desktop-browser/appcast.xml | xpath '(//rss/channel/item/enclosure/@url)[1]' 2>/dev/null | cut -d '"' -f2)
- #appNewVersion=$(curl -fs https://staticcdn.duckduckgo.com/macos-desktop-browser/appcast.xml | xpath '(//rss/channel/item/enclosure/@sparkle:version)[last()]' 2>/dev/null | cut -d '"' -f2)
- appNewVersion=$(curl -fs https://staticcdn.duckduckgo.com/macos-desktop-browser/appcast.xml | xpath '(//rss/channel/item/sparkle:shortVersionString)[1]' 2>/dev/null | cut -d ">" -f2 | cut -d "<" -f1)
+ downloadURL=$(curl -fs https://staticcdn.duckduckgo.com/macos-desktop-browser/appcast.xml | xpath '(//rss/channel/item/enclosure/@url)[last()]' 2>/dev/null | cut -d '"' -f2)
+ #downloadURL=$(curl -fs https://staticcdn.duckduckgo.com/macos-desktop-browser/appcast.xml | xpath '(//rss/channel/item/enclosure/@url)[1]' 2>/dev/null | cut -d '"' -f2)
+ appNewVersion=$(curl -fs https://staticcdn.duckduckgo.com/macos-desktop-browser/appcast.xml | xpath '(//rss/channel/item/enclosure/@sparkle:version)[last()]' 2>/dev/null | cut -d '"' -f2)
+ #appNewVersion=$(curl -fs https://staticcdn.duckduckgo.com/macos-desktop-browser/appcast.xml | xpath '(//rss/channel/item/sparkle:shortVersionString)[1]' 2>/dev/null | cut -d ">" -f2 | cut -d "<" -f1)
expectedTeamID="HKE973VLUW"
;;
diff --git a/fragments/labels/duodevicehealth.sh b/fragments/labels/duodevicehealth.sh
new file mode 100644
index 0000000..c863652
--- /dev/null
+++ b/fragments/labels/duodevicehealth.sh
@@ -0,0 +1,9 @@
+duodevicehealth)
+ name="Duo Device Health"
+ type="pkgInDmg"
+ downloadURL="https://dl.duosecurity.com/DuoDeviceHealth-latest.dmg"
+ appNewVersion=$(curl -fsLIXGET "https://dl.duosecurity.com/DuoDeviceHealth-latest.dmg" | grep -i "^content-disposition" | sed -e 's/.*filename\=\"DuoDeviceHealth\-\(.*\)\.dmg\".*/\1/')
+ appName="Duo Device Health.app"
+ expectedTeamID="FNN8Z5JMFP"
+ ;;
+
diff --git a/fragments/labels/dynalist.sh b/fragments/labels/dynalist.sh
new file mode 100644
index 0000000..58d8681
--- /dev/null
+++ b/fragments/labels/dynalist.sh
@@ -0,0 +1,7 @@
+dynalist)
+ name="Dynalist"
+ type="dmg"
+ downloadURL="https://dynalist.io/standalone/download?file=Dynalist.dmg"
+ appNewVersion=""
+ expectedTeamID="6JSW4SJWN9"
+ ;;
diff --git a/fragments/labels/fellow b/fragments/labels/fellow
new file mode 100644
index 0000000..9fddce1
--- /dev/null
+++ b/fragments/labels/fellow
@@ -0,0 +1,7 @@
+fellow)
+ name="Fellow"
+ type="dmg"
+ downloadURL="https://fellow.app/desktop/download/darwin/latest/"
+ appNewVersion="$(curl -fsIL "${downloadURL}" | grep -i ^location | sed 's/^.*[^0-9]\([0-9]*\.[0-9]*\.[0-9]*\).*$/\1/' | head -1)"
+ expectedTeamID="2NF46HY8D8"
+ ;;
diff --git a/fragments/labels/fellow.sh b/fragments/labels/fellow.sh
new file mode 100644
index 0000000..c5a1660
--- /dev/null
+++ b/fragments/labels/fellow.sh
@@ -0,0 +1,7 @@
+fellow)
+ name="Fellow"
+ type="dmg"
+ downloadURL="https://cdn.fellow.app/desktop/1.3.11/darwin/stable/universal/Fellow-1.3.11-universal.dmg"
+ appNewVersion=""
+ expectedTeamID="2NF46HY8D8"
+ ;;
diff --git a/fragments/labels/filemakerpro.sh b/fragments/labels/filemakerpro.sh
new file mode 100644
index 0000000..f6c7a80
--- /dev/null
+++ b/fragments/labels/filemakerpro.sh
@@ -0,0 +1,8 @@
+filemakerpro)
+ name="FileMaker Pro"
+ type="dmg"
+ versionKey="BuildVersion"
+ downloadURL=$(curl -fs https://www.filemaker.com/redirects/ss.txt | grep '\"PRO..MAC\"' | tail -1 | sed "s|.*url\":\"\(.*\)\".*|\\1|")
+ appNewVersion=$(curl -fs https://www.filemaker.com/redirects/ss.txt | grep '\"PRO..MAC\"' | tail -1 | sed "s|.*fmp_\(.*\).dmg.*|\\1|")
+ expectedTeamID="J6K4T76U7W"
+ ;;
diff --git a/fragments/labels/flexoptixapp.sh b/fragments/labels/flexoptixapp.sh
new file mode 100644
index 0000000..449c22b
--- /dev/null
+++ b/fragments/labels/flexoptixapp.sh
@@ -0,0 +1,7 @@
+flexoptixapp)
+ name="FLEXOPTIX App"
+ type="dmg"
+ downloadURL="https://flexbox.reconfigure.me/download/electron/mac/x64/current"
+ appNewVersion=$(curl -fsIL "${downloadURL}" | grep -i ^location | sed -E 's/.*-([0-9.]*)\.dmg/\1/g')
+ expectedTeamID="C5JETSFPHL"
+ ;;
diff --git a/fragments/labels/fujifilmwebcam.sh b/fragments/labels/fujifilmwebcam.sh
new file mode 100644
index 0000000..26d29a2
--- /dev/null
+++ b/fragments/labels/fujifilmwebcam.sh
@@ -0,0 +1,7 @@
+fujifilmwebcam)
+ name="FUJIFILM X Webcam 2"
+ type="pkg"
+ downloadURL=$(curl -fs "https://fujifilm-x.com/en-us/support/download/software/x-webcam/" | grep "https.*pkg" | sed -E 's/.*(https:\/\/dl.fujifilm-x\.com\/support\/software\/.*\.pkg[^\<]).*/\1/g' | sed -e 's/^"//' -e 's/"$//')
+ appNewVersion=$( echo “${downloadURL}” | sed -E 's/.*XWebcamIns([0-9]*).*/\1/g' | sed -E 's/([0-9])([0-9]).*/\1\.\2/g')
+ expectedTeamID="34LRP8AV2M"
+ ;;
diff --git a/fragments/labels/gfxcardstatus.sh b/fragments/labels/gfxcardstatus.sh
new file mode 100644
index 0000000..84a3422
--- /dev/null
+++ b/fragments/labels/gfxcardstatus.sh
@@ -0,0 +1,7 @@
+gfxcardstatus)
+ name="gfxCardStatus"
+ type="zip"
+ downloadURL="$(downloadURLFromGit codykrieger gfxCardStatus)"
+ appNewVersion="$(versionFromGit codykrieger gfxCardStatus)"
+ expectedTeamID="LF22FTQC25"
+ ;;
diff --git a/fragments/labels/golang.sh b/fragments/labels/golang.sh
index 007c423..d401a04 100644
--- a/fragments/labels/golang.sh
+++ b/fragments/labels/golang.sh
@@ -2,7 +2,11 @@ golang)
name="GoLang"
type="pkg"
packageID="org.golang.go"
- downloadURL="https://go.dev$(curl -fs "https://go.dev/dl/" | grep -i "downloadBox" | grep "pkg" | tr '"' '\n' | grep "pkg")"
+ if [[ $(arch) == "arm64" ]]; then
+ downloadURL="https://go.dev$(curl -fs "https://go.dev/dl/" | grep -i "downloadBox" | grep "darwin-arm" | tr '"' '\n' | grep "pkg")"
+ elif [[ $(arch) == "i386" ]]; then
+ downloadURL="https://go.dev$(curl -fs "https://go.dev/dl/" | grep -i "downloadBox" | grep "darwin-amd" | tr '"' '\n' | grep "pkg")"
+ fi
appNewVersion="$( echo "${downloadURL}" | sed -E 's/.*\/(go[0-9.]*)\..*/\1/g' )" # Version includes letters "go" in the beginning
expectedTeamID="EQHXZ8M8AV"
blockingProcesses=( NONE )
diff --git a/fragments/labels/googleadseditor.sh b/fragments/labels/googleadseditor.sh
new file mode 100644
index 0000000..9c2600b
--- /dev/null
+++ b/fragments/labels/googleadseditor.sh
@@ -0,0 +1,7 @@
+googleadseditor)
+ name="Google Ads Editor"
+ type="dmg"
+ downloadURL="https://dl.google.com/adwords_editor/google_ads_editor.dmg"
+ appNewVersion=""
+ expectedTeamID="EQHXZ8M8AV"
+ ;;
diff --git a/fragments/labels/googledrive.sh b/fragments/labels/googledrive.sh
index 16faa2c..6132e6b 100644
--- a/fragments/labels/googledrive.sh
+++ b/fragments/labels/googledrive.sh
@@ -3,8 +3,13 @@ googledrivefilestream)
# credit: Isaac Ordonez, Mann consulting (@mannconsulting)
name="Google Drive File Stream"
type="pkgInDmg"
- packageID="com.google.drivefs"
+ if [[ $(arch) == "arm64" ]]; then
+ packageID="com.google.drivefs.arm64"
+ elif [[ $(arch) == "i386" ]]; then
+ packageID="com.google.drivefs.x86_64"
+ fi
downloadURL="https://dl.google.com/drive-file-stream/GoogleDriveFileStream.dmg" # downloadURL="https://dl.google.com/drive-file-stream/GoogleDrive.dmg"
blockingProcesses=( "Google Docs" "Google Drive" "Google Sheets" "Google Slides" )
+ appName="Google Drive.app"
expectedTeamID="EQHXZ8M8AV"
;;
diff --git a/fragments/labels/grammarly.sh b/fragments/labels/grammarly.sh
index 4534682..7dfcb93 100644
--- a/fragments/labels/grammarly.sh
+++ b/fragments/labels/grammarly.sh
@@ -2,9 +2,8 @@ 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)
+ downloadURL="https://download-mac.grammarly.com/Grammarly.dmg"
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"
installerTool="Grammarly Installer.app"
CLIInstaller="Grammarly Installer.app/Contents/MacOS/Grammarly Desktop"
diff --git a/fragments/labels/horos.sh b/fragments/labels/horos.sh
new file mode 100644
index 0000000..96b70b0
--- /dev/null
+++ b/fragments/labels/horos.sh
@@ -0,0 +1,14 @@
+horos)
+ name="Horos"
+ type="dmg"
+ versionKey="CFBundleGetInfoString"
+ appNewVersion=$(curl -fs https://github.com/horosproject/horos/blob/horos/Horos/Info.plist | grep -A 4 "CFBundleGetInfoString" | tail -1 | sed -r 's/.*Horos v([^<]+).*/\1/' | sed 's/ //g')
+ if [[ $(arch) == "arm64" ]]; then
+ downloadURL="https://horosproject.org/horos-content/Horos"$appNewVersion"_Apple.dmg"
+ TeamID="8NDFEW7285"
+ elif [[ $(arch) == "i386" ]]; then
+ downloadURL="https://horosproject.org/horos-content/Horos"$appNewVersion".dmg"
+ TeamID="TPT6TVH8UY"
+ fi
+ expectedTeamID=$TeamID
+ ;;
diff --git a/fragments/labels/icons.sh b/fragments/labels/icons.sh
index 87fa428..a319cb9 100644
--- a/fragments/labels/icons.sh
+++ b/fragments/labels/icons.sh
@@ -1,8 +1,7 @@
icons)
- # credit: Mischa van der Bent (@mischavdbent)
name="Icons"
type="zip"
- downloadURL=$(downloadURLFromGit sap macOS-icon-generator )
- appNewVersion=$(versionFromGit sap macOS-icon-generator )
+ downloadURL=$(downloadURLFromGit SAP macOS-icon-generator )
+ appNewVersion=$(versionFromGit SAP macOS-icon-generator )
expectedTeamID="7R5ZEU67FQ"
;;
diff --git a/fragments/labels/insomnia.sh b/fragments/labels/insomnia.sh
index 9de4706..ed0f6c8 100644
--- a/fragments/labels/insomnia.sh
+++ b/fragments/labels/insomnia.sh
@@ -1,7 +1,9 @@
insomnia)
- name="insomnia"
+ name="Insomnia"
type="dmg"
- downloadURL=$(downloadURLFromGit kong insomnia)
- appNewVersion=$(versionFromGit kong insomnia)
+ #downloadURL=$(downloadURLFromGit kong insomnia)
+ downloadURL=$(curl -fs "https://updates.insomnia.rest/downloads/mac/latest?app=com.insomnia.app&source=website" | grep -o "https.*\.dmg")
+ #appNewVersion=$(versionFromGit kong insomnia)
+ appNewVersion=$(echo "$downloadURL" | sed -E 's/.*\/Insomnia.Core.([0-9.]*)\.dmg/\1/')
expectedTeamID="FX44YY62GV"
;;
diff --git a/fragments/labels/ipswupdater.sh b/fragments/labels/ipswupdater.sh
new file mode 100644
index 0000000..bd6c024
--- /dev/null
+++ b/fragments/labels/ipswupdater.sh
@@ -0,0 +1,8 @@
+ipswupdater)
+ name="IPSW Updater"
+ type="zip"
+ ipswupdaterVersions=$(curl -fs "https://ipsw.app/download/updates.php?current_version=0.9.16")
+ downloadURL=$(getJSONValue "$ipswupdaterVersions" "[0].url")
+ appNewVersion=$(getJSONValue "$ipswupdaterVersions" "[0].version")
+ expectedTeamID="YRW6NUGA63"
+ ;;
diff --git a/fragments/labels/kap.sh b/fragments/labels/kap.sh
new file mode 100644
index 0000000..7b6fe1d
--- /dev/null
+++ b/fragments/labels/kap.sh
@@ -0,0 +1,14 @@
+kap)
+ # credit: Lance Stephens (@pythoninthegrass on MacAdmins Slack)
+ name="Kap"
+ type="dmg"
+ if [[ $(arch) = "i386" ]]; then
+ archiveName="${name}-[0-9.]*-x64.${type}"
+ downloadURL=$(downloadURLFromGit wulkano kap | grep -i x64)
+ else
+ archiveName="${name}-[0-9.]*-arm64.${type}"
+ downloadURL=$(downloadURLFromGit wulkano kap | grep -i arm64)
+ fi
+ appNewVersion=$(versionFromGit wulkano Kap)
+ expectedTeamID="2KEEHXF6R6"
+ ;;
diff --git a/fragments/labels/keepingyouawake.sh b/fragments/labels/keepingyouawake.sh
new file mode 100644
index 0000000..6c5aa38
--- /dev/null
+++ b/fragments/labels/keepingyouawake.sh
@@ -0,0 +1,8 @@
+keepingyouawake)
+ name="KeepingYouAwake"
+ type="zip"
+ downloadURL=$(downloadURLFromGit newmarcel KeepingYouAwake)
+ appNewVersion=$(versionFromGit newmarcel KeepingYouAwake)
+ expectedTeamID="5KESHV9W85"
+ blockingProcesses=( "KeepingYouAwake" )
+ ;;
diff --git a/fragments/labels/knockknock.sh b/fragments/labels/knockknock.sh
index 8f351f4..35f854e 100644
--- a/fragments/labels/knockknock.sh
+++ b/fragments/labels/knockknock.sh
@@ -1,7 +1,7 @@
knockknock)
name="KnockKnock"
type="zip"
- downloadURL=$( curl -fs "https://objective-see.com/products/knockknock.html" | grep https | grep "$type" | head -1 | tr '"' "\n" | grep "^http" )
- appNewVersion=$( echo "${downloadURL}" | sed -E 's/.*\/[a-zA-Z]*_([0-9.]*)\..*/\1/g' )
+ downloadURL="$(downloadURLFromGit objective-see KnockKnock)"
+ appNewVersion="$(versionFromGit objective-see KnockKnock)"
expectedTeamID="VBG97UB4TA"
;;
diff --git a/fragments/labels/latexit.sh b/fragments/labels/latexit.sh
new file mode 100644
index 0000000..c6a91f9
--- /dev/null
+++ b/fragments/labels/latexit.sh
@@ -0,0 +1,7 @@
+latexit)
+ name="LaTeXiT"
+ type="dmg"
+ downloadURL="$(curl -fs "https://pierre.chachatelier.fr/latexit/downloads/latexit-sparkle-en.rss" | xpath '(//rss/channel/item/enclosure/@url)[last()]' 2>/dev/null | cut -d '"' -f 2)"
+ appNewVersion="$(curl -fs "https://pierre.chachatelier.fr/latexit/downloads/latexit-sparkle-en.rss" | xpath '(//rss/channel/item/enclosure/@sparkle:shortVersionString)[last()]' 2>/dev/null | cut -d '"' -f 2)"
+ expectedTeamID="7SFX84GNR7"
+ ;;
diff --git a/fragments/labels/lcadvancedvpnclient.sh b/fragments/labels/lcadvancedvpnclient.sh
new file mode 100644
index 0000000..9674336
--- /dev/null
+++ b/fragments/labels/lcadvancedvpnclient.sh
@@ -0,0 +1,7 @@
+lcadvancedvpnclient)
+ name="LANCOM Advanced VPN Client"
+ type="pkgInDmg"
+ appNewVersion=$(curl -fs https://www.ncp-e.com/de/service/download-vpn-client/ | grep -m 1 "NCP Secure Entry macOS Client" -A 1 | grep -i Version | sed "s|.*Version \(.*\) Rev.*|\\1|")
+ downloadURL=$(appShortVersion=`sed 's/[^0-9]//g' <<< $appNewVersion` && echo https://ftp.lancom.de/LANCOM-Releases/LC-VPN-Client/LC-Advanced-VPN-Client-macOS-"${appShortVersion}"-Rel-x86-64.dmg)
+ expectedTeamID="LL3KBL2M3A"
+ ;;
diff --git a/fragments/labels/macports.sh b/fragments/labels/macports.sh
index 6a473a1..9f3c7be 100644
--- a/fragments/labels/macports.sh
+++ b/fragments/labels/macports.sh
@@ -13,7 +13,7 @@ macports)
archiveName="Catalina.pkg"
;;
*)
- cleanupAndExit 1 "macOS 10.14 or earlier not supported by Installomator."
+ cleanupAndExit 98 "macOS 10.14 or earlier not supported by Installomator."
;;
esac
downloadURL=$(downloadURLFromGit macports macports-base)
diff --git a/fragments/labels/masv.sh b/fragments/labels/masv.sh
new file mode 100644
index 0000000..d614f70
--- /dev/null
+++ b/fragments/labels/masv.sh
@@ -0,0 +1,6 @@
+masv)
+ name="MASV"
+ type="dmg"
+ downloadURL="https://dl.massive.io/MASV.dmg"
+ expectedTeamID="VHKX7RCAY7"
+ ;;
diff --git a/fragments/labels/merlinproject.sh b/fragments/labels/merlinproject.sh
new file mode 100644
index 0000000..e5e4949
--- /dev/null
+++ b/fragments/labels/merlinproject.sh
@@ -0,0 +1,7 @@
+merlinproject)
+ name="Merlin Project"
+ type="zip"
+ downloadURL="https://www.projectwizards.net/downloads/MerlinProject.zip"
+ appNewVersion="$(curl -fs "https://www.projectwizards.net/de/support/release-notes" | grep Version | head -n 6 | tail -n 1 | sed 's/[^0-9.]*//g')"
+ expectedTeamID="9R6P9VZV27"
+ ;;
diff --git a/fragments/labels/microsoftyammer.sh b/fragments/labels/microsoftyammer.sh
deleted file mode 100644
index 2fc47ee..0000000
--- a/fragments/labels/microsoftyammer.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-microsoftyammer)
- name="Yammer"
- type="dmg"
- downloadURL="https://aka.ms/yammer_desktop_mac"
- #appNewVersion=$(curl -fs https://macadmins.software/latest.xml | xpath '//latest/oldpackage[id="com.microsoft.yammer.standalone"]/cfbundleshortversionstring' 2>/dev/null | sed -E 's/([0-9.]*)<.*/\1/')
- appNewVersion=$(curl -fsIL "$downloadURL" | grep -i location: | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)\..*/\1/g')
- expectedTeamID="UBF8T346G9"
- #updateTool="/Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate --list; /Library/Application Support/Microsoft/MAU2.0/Microsoft AutoUpdate.app/Contents/MacOS/msupdate"
- #updateToolArguments=( --install --apps ?????? )
- ;;
diff --git a/fragments/labels/mongodbcompass.sh b/fragments/labels/mongodbcompass.sh
new file mode 100644
index 0000000..6aa8e33
--- /dev/null
+++ b/fragments/labels/mongodbcompass.sh
@@ -0,0 +1,8 @@
+mongodbcompass)
+ name="MongoDB Compass"
+ type="dmg"
+ archiveName="mongodb-compass-[0-9.]*-darwin-x64.dmg"
+ downloadURL="$(downloadURLFromGit mongodb-js compass)"
+ appNewVersion="$(versionFromGit mongodb-js compass)"
+ expectedTeamID="4XWMY46275"
+ ;;
diff --git a/fragments/labels/netspot.sh b/fragments/labels/netspot.sh
new file mode 100644
index 0000000..a68c14f
--- /dev/null
+++ b/fragments/labels/netspot.sh
@@ -0,0 +1,7 @@
+netspot)
+ name="NetSpot"
+ type="dmg"
+ downloadURL="https://cdn.netspotapp.com/download/NetSpot.dmg"
+ appNewVersion=$(curl -fs "https://www.netspotapp.com/updates/netspot2-appcast.xml" | xpath '(//rss/channel/item/enclosure/@sparkle:version)' 2>/dev/null | cut -d '"' -f 2)
+ expectedTeamID="5QLDY8TU83"
+ ;;
diff --git a/fragments/labels/nudge.sh b/fragments/labels/nudge.sh
index 804872d..aafacad 100644
--- a/fragments/labels/nudge.sh
+++ b/fragments/labels/nudge.sh
@@ -1,8 +1,9 @@
nudge)
name="Nudge"
type="pkg"
+ archiveName="Nudge-[0-9.]*.pkg"
downloadURL=$(downloadURLFromGit macadmins Nudge )
appNewVersion=$(versionFromGit macadmins Nudge )
expectedTeamID="9GQZ7KUFR6"
- archiveName="Nudge-[0-9.]*.pkg"
+
;;
diff --git a/fragments/labels/nudgesuite.sh b/fragments/labels/nudgesuite.sh
new file mode 100644
index 0000000..698cf2e
--- /dev/null
+++ b/fragments/labels/nudgesuite.sh
@@ -0,0 +1,10 @@
+nudgesuite)
+ name="Nudge Suite"
+ appName="Nudge.app"
+ type="pkg"
+ archiveName="Nudge_Suite-[0-9.]*.pkg"
+ downloadURL=$(downloadURLFromGit macadmins Nudge )
+ appNewVersion=$(versionFromGit macadmins Nudge )
+ expectedTeamID="9GQZ7KUFR6"
+ blockingProcesses=( "Nudge" )
+ ;;
diff --git a/fragments/labels/obs.sh b/fragments/labels/obs.sh
index 4685446..d932046 100644
--- a/fragments/labels/obs.sh
+++ b/fragments/labels/obs.sh
@@ -1,7 +1,12 @@
obs)
- # credit: Gabe Marchan (gabemarchan.com - @darklink87)
name="OBS"
type="dmg"
- downloadURL=$(curl -fs "https://obsproject.com/download" | awk -F '"' "/dmg/ {print \$10}")
+ if [[ $(arch) == "arm64" ]]; then
+ archiveName="obs-studio-[0-9.]*-macos-arm64.dmg"
+ elif [[ $(arch) == "i386" ]]; then
+ archiveName="obs-studio-[0-9.]*-macos-x86_64.dmg"
+ fi
+ downloadURL=$(downloadURLFromGit obsproject obs-studio )
+ appNewVersion=$(versionFromGit obsproject obs-studio )
expectedTeamID="2MMRE5MTB8"
;;
diff --git a/fragments/labels/opera.sh b/fragments/labels/opera.sh
index 78eda31..fc40e27 100644
--- a/fragments/labels/opera.sh
+++ b/fragments/labels/opera.sh
@@ -1,8 +1,8 @@
opera)
name="Opera"
type="dmg"
- downloadURL=$(curl -fsIL "$(curl -fs "$(curl -fsIL "https://download.opera.com/download/get/?partner=www&opsys=MacOS" | grep -i "^location" | cut -d " " -f2 | tail -1 | tr -d '\r')" | grep download.opera.com | grep -io "https.*yes" | sed 's/\&/\&/g')" | grep -i "^location" | cut -d " " -f2 | tr -d '\r')
- appNewVersion="$(curl -fs "https://get.geo.opera.com/ftp/pub/opera/desktop/" | grep "href=\"\d" | sort -V | tail -1 | tr '"' '\n' | grep "/" | head -1 | tr -d '/')"
+ downloadURL="$(curl -fsIL "$(curl -fs "$(curl -fsL "https://download.opera.com/download/get/?partner=www&opsys=MacOS" | tr '"' "\n" | grep -e "www.opera.com.*thanks.*opera" | sed 's/\&\;/\&/g')" | tr '"' "\n" | grep "download.opera.com" | sed 's/\&\;/\&/g')" | grep -i "^location" | grep -io "https.*dmg")"
+ appNewVersion="$(printf "$downloadURL" | sed -E 's/https.*\/([0-9.]*)\/mac\/.*/\1/')"
versionKey="CFBundleVersion"
expectedTeamID="A2P9LX4JPN"
;;
diff --git a/fragments/labels/origin.sh b/fragments/labels/origin.sh
new file mode 100644
index 0000000..2fbdb90
--- /dev/null
+++ b/fragments/labels/origin.sh
@@ -0,0 +1,7 @@
+origin)
+ name="Origin"
+ type="dmg"
+ downloadURL="https://www.dm.origin.com/mac/download/Origin.dmg"
+ expectedTeamID="TSTV75T6Q5"
+ blockingProcesses=( "Origin" )
+ ;;
\ No newline at end of file
diff --git a/fragments/labels/parallelsrasclient sh b/fragments/labels/parallelsrasclient sh
new file mode 100644
index 0000000..0aa5306
--- /dev/null
+++ b/fragments/labels/parallelsrasclient sh
@@ -0,0 +1,7 @@
+parallelsrasclient)
+ name="Parallels Client"
+ type="pkg"
+ appNewVersion=$(curl -sf "https://download.parallels.com/ras/v18/RAS%20Client%20for%20Mac%20Changelog.txt" | grep -m 1 "Parallels Client for Mac Version" | sed "s|.*Version \(.*\) -.*|\\1|" | sed 's/ /./g' | sed 's/[^0-9.]//g')
+ downloadURL=$(appMajorVersion=`sed 's/\..*//' <<< $appNewVersion` && appHyphenVersion=`curl -sf "https://download.parallels.com/ras/v18/RAS%20Client%20for%20Mac%20Changelog.txt" | grep -m 1 "Parallels Client for Mac Version" | sed "s|.*Version \(.*\) -.*|\\1|" | sed 's/ /-/g' | sed 's/[^0-9.-]//g'` && echo https://download.parallels.com/ras/v"$appMajorVersion"/"$appNewVersion"/RasClient-Mac-Notarized-"$appHyphenVersion".pkg)
+ expectedTeamID="4C6364ACXT"
+ ;;
diff --git a/fragments/labels/polylens.sh b/fragments/labels/polylens.sh
new file mode 100644
index 0000000..54cd0b3
--- /dev/null
+++ b/fragments/labels/polylens.sh
@@ -0,0 +1,7 @@
+polylens)
+ name="Poly Lens"
+ type="dmg"
+ appNewVersion=$(curl -fs "https://info.lens.poly.com/lens-dt-rn/atom.xml" | grep "Version" | head -1 | cut -d "[" -f3 | sed 's/Version //g' | sed 's/]]\>\<\/title\>//g')
+ downloadURL="https://swupdate.lens.poly.com/lens-desktop-mac/$appNewVersion/$appNewVersion/PolyLens-$appNewVersion.dmg"
+ expectedTeamID="SKWK2Q7JJV"
+ ;;
diff --git a/fragments/labels/prune.sh b/fragments/labels/prune.sh
new file mode 100644
index 0000000..2b76dd0
--- /dev/null
+++ b/fragments/labels/prune.sh
@@ -0,0 +1,7 @@
+prune)
+ name="Prune"
+ type="zip"
+ downloadURL=$(downloadURLFromGit BIG-RAT Prune)
+ appNewVersion=$(versionFromGit BIG-RAT Prune)
+ expectedTeamID="PS2F6S478M"
+;;
diff --git a/fragments/labels/r.sh b/fragments/labels/r.sh
index 1c98852..fd9e6b4 100644
--- a/fragments/labels/r.sh
+++ b/fragments/labels/r.sh
@@ -1,7 +1,12 @@
r)
name="R"
type="pkg"
- downloadURL="https://cloud.r-project.org/bin/macosx/$( curl -fsL https://cloud.r-project.org/bin/macosx/ | grep -m 1 -o '' | sed -E 's/.+"(.+)".+/\1/g' )"
- appNewVersion=$(echo "${downloadURL}" | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)\..*/\1/g')
+ if [[ $(arch) == "arm64" ]]; then
+ downloadURL="https://cloud.r-project.org/bin/macosx/$( curl -fsL https://cloud.r-project.org/bin/macosx/ | grep -m 1 -o '' | sed -E 's/.+"(.+)".+/\1/g' )"
+ appNewVersion=$(echo "${downloadURL}" | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)-.*\..*/\1/g')
+ elif [[ $(arch) == "i386" ]]; then
+ downloadURL="https://cloud.r-project.org/bin/macosx/$( curl -fsL https://cloud.r-project.org/bin/macosx/ | grep -o '' | grep -m 1 -v "arm64" | sed -E 's/.+"(.+)".+/\1/g' )"
+ appNewVersion=$(echo "${downloadURL}" | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)\..*/\1/g')
+ fi
expectedTeamID="VZLD955F6P"
;;
diff --git a/fragments/labels/relatel.sh b/fragments/labels/relatel.sh
new file mode 100644
index 0000000..91cb609
--- /dev/null
+++ b/fragments/labels/relatel.sh
@@ -0,0 +1,7 @@
+relatel)
+ name="Relatel"
+ type="dmg"
+ downloadURL="https://cdn.rela.tel/www/public/junotron/Relatel.dmg"
+ appNewVersion="$(curl -fs "https://cdn.firmafon.dk/www/public/junotron/latest-mac.yml" | grep -i "version" | cut -w -f2)"
+ expectedTeamID="B9358QF55B"
+ ;;
diff --git a/fragments/labels/remotix.sh b/fragments/labels/remotix.sh
deleted file mode 100644
index 4a095d3..0000000
--- a/fragments/labels/remotix.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-remotix)
- name="Remotix"
- type="dmg"
- downloadURL="https://remotix.com/downloads/latest-remotix-mac/"
- appNewVersion=$( curl -fsIL "${downloadURL}" | grep -i "^location" | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)-.*\.dmg/\1/g' )
- expectedTeamID="K293Y6CVN4"
- ;;
diff --git a/fragments/labels/remotixagent.sh b/fragments/labels/remotixagent.sh
deleted file mode 100644
index 25539b5..0000000
--- a/fragments/labels/remotixagent.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-remotixagent)
- name="RemotixAgent"
- type="pkg"
- packageID="com.nulana.rxagentmac"
- downloadURL="https://remotix.com/downloads/latest-agent-mac/"
- appNewVersion=$( curl -fsIL "${downloadURL}" | grep -i "^location" | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)-.*\.pkg/\1/g' )
- expectedTeamID="K293Y6CVN4"
- ;;
diff --git a/fragments/labels/rstudio.sh b/fragments/labels/rstudio.sh
index 22f735e..6ff3755 100644
--- a/fragments/labels/rstudio.sh
+++ b/fragments/labels/rstudio.sh
@@ -2,6 +2,6 @@ rstudio)
name="RStudio"
type="dmg"
downloadURL=$(curl -s -L "https://rstudio.com/products/rstudio/download/" | grep -m 1 -Eio 'href="https://download1.rstudio.org/desktop/macos/RStudio-(.*).dmg"' | cut -c7- | sed -e 's/"$//')
- appNewVersion=$( echo "${downloadURL}" | sed -E 's/.*\/[a-zA-Z]*-([0-9.]*)\..*/\1/g' )
+ appNewVersion=$( echo "${downloadURL}" | sed -E 's/.*\/[a-zA-Z]*-([0-9.-]*)\..*/\1/g' | sed 's/-/+/' )
expectedTeamID="FYF2F5GFX4"
;;
diff --git a/fragments/labels/screamingfrogseospider.sh b/fragments/labels/screamingfrogseospider.sh
index 1a2aaf6..39ab342 100644
--- a/fragments/labels/screamingfrogseospider.sh
+++ b/fragments/labels/screamingfrogseospider.sh
@@ -1,7 +1,12 @@
screamingfrogseospider)
name="Screaming Frog SEO Spider"
type="dmg"
- downloadURL=$(curl -fs "https://www.screamingfrog.co.uk/wp-content/themes/screamingfrog/inc/download-modal.php" | grep -i -o "https.*\.dmg" | head -1)
+ if [[ $(arch) == i386 ]]; then
+ platform="Mac - (intel)"
+ elif [[ $(arch) == arm64 ]]; then
+ platform="Mac - (apple silicon)"
+ fi
+ downloadURL=$(curl -fs "https://www.screamingfrog.co.uk/wp-content/themes/screamingfrog/inc/download-modal.php" | grep "${platform}" | grep -i -o "https.*\.dmg" | head -1)
appNewVersion=$(print "$downloadURL" | sed -E 's/https.*\/[a-zA-Z]*-([0-9.]*)\.dmg/\1/g')".0"
expectedTeamID="CAHEVC3HZC"
;;
diff --git a/fragments/labels/sonicvisualiser.sh b/fragments/labels/sonicvisualiser.sh
new file mode 100644
index 0000000..14e0a7a
--- /dev/null
+++ b/fragments/labels/sonicvisualiser.sh
@@ -0,0 +1,7 @@
+sonicvisualiser)
+ name="Sonic Visualiser"
+ type="dmg"
+ downloadURL="$(downloadURLFromGit sonic-visualiser sonic-visualiser)"
+ appNewVersion="$(versionFromGit sonic-visualiser sonic-visualiser)"
+ expectedTeamID="73F996B92S"
+ ;;
diff --git a/fragments/labels/splashtopbusiness.sh b/fragments/labels/splashtopbusiness.sh
new file mode 100644
index 0000000..e9da7fd
--- /dev/null
+++ b/fragments/labels/splashtopbusiness.sh
@@ -0,0 +1,8 @@
+splashtopbusiness)
+ name="Splashtop Business"
+ type="pkgInDmg"
+ splashtopbusinessVersions=$(curl -fsL "https://www.splashtop.com/wp-content/themes/responsive/downloadx.php?product=stb&platform=mac-client")
+ downloadURL=$(getJSONValue "$splashtopbusinessVersions" "url")
+ appNewVersion="${${downloadURL#*INSTALLER_v}%*.dmg}"
+ expectedTeamID="CPQQ3AW49Y"
+ ;;
diff --git a/fragments/labels/strongdm.sh b/fragments/labels/strongdm.sh
new file mode 100644
index 0000000..5d04dcb
--- /dev/null
+++ b/fragments/labels/strongdm.sh
@@ -0,0 +1,9 @@
+strongdm)
+ name="strongDM"
+ type="dmg"
+ downloadURL="https://app.strongdm.com/downloads/client/darwin"
+ appNewVersion=$(curl -fsLIXGET "https://app.strongdm.com/downloads/client/darwin" | grep -i "^content-disposition" | sed -e 's/.*filename\=\"SDM\-\(.*\)\.dmg\".*/\1/')
+ appName="SDM.app"
+ blockingProcesses=( "SDM" )
+ expectedTeamID="W5HSYBBJGA"
+ ;;
diff --git a/fragments/labels/sublimetext.sh b/fragments/labels/sublimetext.sh
index 5f63257..1fda13f 100644
--- a/fragments/labels/sublimetext.sh
+++ b/fragments/labels/sublimetext.sh
@@ -2,7 +2,7 @@ sublimetext)
# credit: Søren Theilgaard (@theilgaard)
name="Sublime Text"
type="zip"
- downloadURL="$(curl -fs https://www.sublimetext.com/download | grep -io "https://download.*_mac.zip")"
+ downloadURL="$(curl -fs "https://www.sublimetext.com/download_thanks?target=mac#direct-downloads" | grep -io "https://download.*_mac.zip" | head -1)"
appNewVersion=$(curl -fs https://www.sublimetext.com/download | grep -i -A 4 "id.*changelog" | grep -io "Build [0-9]*")
expectedTeamID="Z6D26JE4Y4"
;;
diff --git a/fragments/labels/supportapp.sh b/fragments/labels/supportapp.sh
index 04be84c..7bd48a0 100644
--- a/fragments/labels/supportapp.sh
+++ b/fragments/labels/supportapp.sh
@@ -5,6 +5,5 @@ supportapp)
downloadURL=$(downloadURLFromGit root3nl SupportApp)
appNewVersion=$(versionFromGit root3nl SupportApp)
expectedTeamID="98LJ4XBGYK"
- uid=$(id -u "$currentUser")
- launchctl bootout gui/${uid} "/Library/LaunchAgents/nl.root3.support.plist"
+ blockingProcesses=( NONE )
;;
diff --git a/fragments/labels/synologyassistant.sh b/fragments/labels/synologyassistant.sh
new file mode 100644
index 0000000..ad6e61b
--- /dev/null
+++ b/fragments/labels/synologyassistant.sh
@@ -0,0 +1,8 @@
+synologyassistant)
+ name="SynologyAssistant"
+ type="dmg"
+ packageID="com.synology.DSAssistant"
+ appNewVersion="$(curl -sf https://archive.synology.com/download/Utility/Assistant | grep -m 1 /download/Utility/Assistant/ | sed "s|.*>\(.*\)<.*|\\1|")"
+ downloadURL="https://global.download.synology.com/download/Utility/Assistant/${appNewVersion}/Mac/synology-assistant-${appNewVersion}.dmg"
+ expectedTeamID="X85BAK35Y4"
+ ;;
diff --git a/fragments/labels/synologydriveclient.sh b/fragments/labels/synologydriveclient.sh
new file mode 100644
index 0000000..430f4ef
--- /dev/null
+++ b/fragments/labels/synologydriveclient.sh
@@ -0,0 +1,8 @@
+synologydriveclient)
+ name="Synology Drive Client"
+ type="pkgInDmg"
+ packageID="com.synology.CloudStation"
+ downloadURL=$(appVersion=`curl -sf https://archive.synology.com/download/Utility/SynologyDriveClient | grep -m 1 /download/Utility/SynologyDriveClient/ | sed "s|.*>\(.*\)<.*|\\1|"` && appShortVersion=`sed 's#.*-\(\)#\1#' <<< $appVersion` && echo https://global.download.synology.com/download/Utility/SynologyDriveClient/"$appVersion"/Mac/Installer/synology-drive-client-"${appShortVersion}".dmg)
+ appNewVersion=$(appVersionP1=`curl -sf https://archive.synology.com/download/Utility/SynologyDriveClient | grep -m 1 /download/Utility/SynologyDriveClient/ | sed "s|.*>\(.*\)-.*|\\1|"` && sed 's/\(.\{0\}\)./\17/' <<< $appVersionP1)
+ expectedTeamID="X85BAK35Y4"
+ ;;
diff --git a/fragments/labels/tailscale.sh b/fragments/labels/tailscale.sh
new file mode 100644
index 0000000..02852f5
--- /dev/null
+++ b/fragments/labels/tailscale.sh
@@ -0,0 +1,8 @@
+tailscale)
+ name="Tailscale"
+ type="zip"
+ appNewVersion="$(curl -s https://pkgs.tailscale.com/stable/ | awk -F- '/Tailscale.*macos.zip/ {print $2}')"
+ downloadURL="https://pkgs.tailscale.com/stable/Tailscale-${appNewVersion}-macos.zip"
+ expectedTeamID="W5364U7YZB"
+ versionKey="CFBundleShortVersionString"
+ ;;
diff --git a/fragments/labels/talkdeskcallbar.sh b/fragments/labels/talkdeskcallbar.sh
index fb773b4..dbc9135 100644
--- a/fragments/labels/talkdeskcallbar.sh
+++ b/fragments/labels/talkdeskcallbar.sh
@@ -1,7 +1,8 @@
talkdeskcallbar)
name="Callbar"
type="dmg"
- appNewVersion=$(curl -fsL https://downloadcallbar.talkdesk.com/release_metadata.json | sed -n 's/^.*"version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*$/\1/p')
+ talkdeskcallbarVersions=$(curl -fsL "https://downloadcallbar.talkdesk.com/release_metadata.json")
+ appNewVersion=$(getJSONValue "$talkdeskcallbarVersions" "version")
downloadURL=https://downloadcallbar.talkdesk.com/Callbar-${appNewVersion}.dmg
expectedTeamID="YGGJX44TB8"
;;
diff --git a/fragments/labels/talkdeskcxcloud.sh b/fragments/labels/talkdeskcxcloud.sh
index 2326146..889dd13 100644
--- a/fragments/labels/talkdeskcxcloud.sh
+++ b/fragments/labels/talkdeskcxcloud.sh
@@ -1,7 +1,8 @@
talkdeskcxcloud)
name="Talkdesk"
type="dmg"
- appNewVersion=$(curl -fs https://td-infra-prd-us-east-1-s3-atlaselectron.s3.amazonaws.com/talkdesk-latest-metadata.json | sed -n -e 's/^.*"version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*$/\1/p' | head -n 1)
+ talkdeskcxcloudVersions=$(curl -fs "https://td-infra-prd-us-east-1-s3-atlaselectron.s3.amazonaws.com/talkdesk-latest-metadata.json")
+ appNewVersion=$(getJSONValue "$talkdeskcxcloudVersions" "[0].version")
downloadURL="https://td-infra-prd-us-east-1-s3-atlaselectron.s3.amazonaws.com/talkdesk-${appNewVersion}.dmg"
expectedTeamID="YGGJX44TB8"
;;
diff --git a/fragments/labels/tencentmeeting.sh b/fragments/labels/tencentmeeting.sh
new file mode 100644
index 0000000..bb90f8f
--- /dev/null
+++ b/fragments/labels/tencentmeeting.sh
@@ -0,0 +1,15 @@
+tencentmeeting)
+ name="TencentMeeting"
+ type="dmg"
+ if [[ $(arch) == "arm64" ]]; then
+ downloadURL="$(curl -fs 'https://meeting.tencent.com/web-service/query-download-info?q=%5B%7B%22package-type%22%3A%22app%22%2C%22channel%22%3A%220300000000%22%2C%22platform%22%3A%22mac%22%2C%22arch%22%3A%22arm64%22%7D%5D&c_os=web&c_os_version=1&c_os_model=web&c_timestamp=1653366550252&c_instance_id=5&c_nonce=DcaDam4y&c_app_id=1400143280&c_app_version=1&c_lang=zh-cn&c_district=0&nonce=miwSceJNQaSZttma' -H 'authority: meeting.tencent.com' -H 'referer: https://meeting.tencent.com/download-mac.html?from=1000&fromSource=1&macType=apple' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Safari/605.1.15' | grep -o "https://updatecdn.meeting.qq.com[^']*\.publish.arm64.dmg")"
+ appNewVersion=$(curl -fs 'https://meeting.tencent.com/web-service/query-download-info?q=%5B%7B%22package-type%22%3A%22app%22%2C%22channel%22%3A%220300000000%22%2C%22platform%22%3A%22mac%22%2C%22arch%22%3A%22arm64%22%7D%5D&c_os=web&c_os_version=1&c_os_model=web&c_timestamp=1653366550252&c_instance_id=5&c_nonce=DcaDam4y&c_app_id=1400143280&c_app_version=1&c_lang=zh-cn&c_district=0&nonce=miwSceJNQaSZttma' -H 'authority: meeting.tencent.com' -H 'referer: https://meeting.tencent.com/download-mac.html?from=1000&fromSource=1&macType=apple' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Safari/605.1.15' | grep -o "https://updatecdn.meeting.qq.com[^']*\.publish.arm64.dmg" | sed -e 's/.*TencentMeeting\_0300000000\_\(.*\)\.publish\.arm64\.dmg.*/\1/')
+ elif [[ $(arch) == "i386" ]]; then
+ downloadURL="$(curl -fs 'https://meeting.tencent.com/web-service/query-download-info?q=%5B%7B%22package-type%22%3A%22app%22%2C%22channel%22%3A%220300000000%22%2C%22platform%22%3A%22mac%22%2C%22arch%22%3A%22x86_64%22%7D%5D&c_os=web&c_os_version=1&c_os_model=web&c_timestamp=1653366500890&c_instance_id=5&c_nonce=jA4P4JPY&c_app_id=1400143280&c_app_version=1&c_lang=zh-cn&c_district=0&nonce=tF6Bm4FYHJwdPeGH' -H 'authority: meeting.tencent.com' -H 'referer: https://meeting.tencent.com/download-mac.html?from=1000&fromSource=1' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Safari/605.1.15' | grep -o "https://updatecdn.meeting.qq.com[^']*\.publish.x86_64.dmg")"
+ appNewVersion=$(curl -fs 'https://meeting.tencent.com/web-service/query-download-info?q=%5B%7B%22package-type%22%3A%22app%22%2C%22channel%22%3A%220300000000%22%2C%22platform%22%3A%22mac%22%2C%22arch%22%3A%22x86_64%22%7D%5D&c_os=web&c_os_version=1&c_os_model=web&c_timestamp=1653366500890&c_instance_id=5&c_nonce=jA4P4JPY&c_app_id=1400143280&c_app_version=1&c_lang=zh-cn&c_district=0&nonce=tF6Bm4FYHJwdPeGH' -H 'authority: meeting.tencent.com' -H 'referer: https://meeting.tencent.com/download-mac.html?from=1000&fromSource=1' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Safari/605.1.15' | grep -o "https://updatecdn.meeting.qq.com[^']*\.publish.x86_64.dmg" | sed -e 's/.*TencentMeeting\_0300000000\_\(.*\)\.publish\.x86_64\.dmg.*/\1/')
+ fi
+ curlOptions=( -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.5 Safari/605.1.15" )
+ appCustomVersion() { echo "$(defaults read /Applications/TencentMeeting.app/Contents/Info.plist CFBundleShortVersionString)$(echo ".")$(defaults read /Applications/TencentMeeting.app/Contents/Info.plist CFBundleVersion)" }
+ expectedTeamID="88L2Q4487U"
+ ;;
+
diff --git a/fragments/labels/typinator.sh b/fragments/labels/typinator.sh
new file mode 100644
index 0000000..648f77c
--- /dev/null
+++ b/fragments/labels/typinator.sh
@@ -0,0 +1,7 @@
+typinator)
+ name="Typinator"
+ type="zip"
+ downloadURL=https://update.ergonis.com/downloads/products/typinator/Typinator.app.zip
+ appNewVersion="$(curl -fs https://update.ergonis.com/vck/typinator.xml | grep -i Program_Version | sed "s|.*>\(.*\)<.*|\\1|")"
+ expectedTeamID="TU7D9Y7GTQ"
+ ;;
diff --git a/fragments/labels/vlc.sh b/fragments/labels/vlc.sh
index 8fe2487..dae2c67 100644
--- a/fragments/labels/vlc.sh
+++ b/fragments/labels/vlc.sh
@@ -3,10 +3,11 @@ vlc)
type="dmg"
if [[ $(arch) == "arm64" ]]; then
downloadURL=$(curl -fs http://update.videolan.org/vlc/sparkle/vlc-arm64.xml | xpath '//rss/channel/item[last()]/enclosure/@url' 2>/dev/null | cut -d '"' -f 2 )
- appNewVersion=$(curl -fs http://update.videolan.org/vlc/sparkle/vlc-arm64.xml | xpath '//rss/channel/item[last()]/enclosure/@sparkle:version' 2>/dev/null | cut -d '"' -f 2 )
+ #appNewVersion=$(curl -fs http://update.videolan.org/vlc/sparkle/vlc-arm64.xml | xpath '//rss/channel/item[last()]/enclosure/@sparkle:version' 2>/dev/null | cut -d '"' -f 2 )
elif [[ $(arch) == "i386" ]]; then
downloadURL=$(curl -fs http://update.videolan.org/vlc/sparkle/vlc-intel64.xml | xpath '//rss/channel/item[last()]/enclosure/@url' 2>/dev/null | cut -d '"' -f 2 )
- appNewVersion=$(curl -fs http://update.videolan.org/vlc/sparkle/vlc-intel64.xml | xpath '//rss/channel/item[last()]/enclosure/@sparkle:version' 2>/dev/null | cut -d '"' -f 2 )
+ #appNewVersion=$(curl -fs http://update.videolan.org/vlc/sparkle/vlc-intel64.xml | xpath '//rss/channel/item[last()]/enclosure/@sparkle:version' 2>/dev/null | cut -d '"' -f 2 )
fi
+ appNewVersion=$(echo ${downloadURL} | sed -E 's/.*\/vlc-([0-9.]*).*\.dmg/\1/' )
expectedTeamID="75GAHG3SZQ"
;;
diff --git a/fragments/labels/vmwarehorizonclient.sh b/fragments/labels/vmwarehorizonclient.sh
index 428af60..24d8139 100644
--- a/fragments/labels/vmwarehorizonclient.sh
+++ b/fragments/labels/vmwarehorizonclient.sh
@@ -1,7 +1,8 @@
vmwarehorizonclient)
name="VMware Horizon Client"
type="dmg"
- downloadURL=$(curl -fsL "https://my.vmware.com/channel/public/api/v1.0/dlg/details?locale=en_US&downloadGroup=CART21FQ2_MAC_800&productId=1027&rPId=48989" | grep -o 'Url.*..dmg"' | cut -d '"' -f3)
- appNewVersion=$(curl -fsL "https://my.vmware.com/channel/public/api/v1.0/dlg/details?locale=en_US&downloadGroup=CART21FQ2_MAC_800&productId=1027&rPId=48989" | sed 's/.*-\(.*\)-.*/\1/')
- expectedTeamID="EG7KH642X6"
+ downloadGroup=$(curl -fsL "https://my.vmware.com/channel/public/api/v1.0/products/getRelatedDLGList?locale=en_US&category=desktop_end_user_computing&product=vmware_horizon_clients&version=horizon_8&dlgType=PRODUCT_BINARY" | grep -o '[^"]*_MAC_[^"]*')
+ fileName=$(curl -fsL "https://my.vmware.com/channel/public/api/v1.0/dlg/details?locale=en_US&category=desktop_end_user_computing&product=vmware_horizon_clients&dlgType=PRODUCT_BINARY&downloadGroup=${downloadGroup}" | grep -o '"fileName":"[^"]*"' | cut -d: -f2 | sed 's/"//g')
+ downloadURL="https://download3.vmware.com/software/$downloadGroup/${fileName}"
+ appNewVersion=$(curl -fsL "https://my.vmware.com/channel/public/api/v1.0/dlg/details?locale=en_US&downloadGroup=${downloadGroup}" | grep -o '[^"]*\.dmg[^"]*' | sed 's/.*-\(.*\)-.*/\1/') expectedTeamID="EG7KH642X6"
;;
diff --git a/fragments/labels/wireshark.sh b/fragments/labels/wireshark.sh
index d293dd8..6932319 100644
--- a/fragments/labels/wireshark.sh
+++ b/fragments/labels/wireshark.sh
@@ -1,11 +1,11 @@
wireshark)
name="Wireshark"
type="dmg"
- if [[ $(arch) == i386 ]]; then
- downloadURL="https://1.as.dl.wireshark.org/osx/Wireshark%20Latest%20Intel%2064.dmg"
- elif [[ $(arch) == arm64 ]]; then
- downloadURL="https://1.as.dl.wireshark.org/osx/Wireshark%20Latest%20Arm%2064.dmg"
- fi
appNewVersion=$(curl -fs https://www.wireshark.org/download.html | grep -i "href.*_stable" | sed -E 's/.*\(([0-9.]*)\).*/\1/g')
+ if [[ $(arch) == i386 ]]; then
+ downloadURL="https://1.as.dl.wireshark.org/osx/Wireshark%20$appNewVersion%20Intel%2064.dmg"
+ elif [[ $(arch) == arm64 ]]; then
+ downloadURL="https://1.as.dl.wireshark.org/osx/Wireshark%20$appNewVersion%20Arm%2064.dmg"
+ fi
expectedTeamID="7Z6EMTD2C6"
;;
diff --git a/fragments/labels/xcreds.sh b/fragments/labels/xcreds.sh
new file mode 100644
index 0000000..8a71fd0
--- /dev/null
+++ b/fragments/labels/xcreds.sh
@@ -0,0 +1,14 @@
+xcreds)
+ name="XCreds"
+ # Downloading from twocanoes homepage
+ #type="pkgInDmg"
+ #packageID="com.twocanoes.pkg.secureremoteaccess"
+ #downloadURL=$(curl -fs "https://twocanoes.com/products/mac/xcreds/" | grep -ioE "https://.*\.zip" | head -1)
+ #appNewVersion=$(curl -fs "https://twocanoes.com/products/mac/xcreds/" | grep -io "Current Version:.*" | sed -E 's/.*XCreds *([0-9.]*)<.*/\1/g')
+ # GitHub download
+ type="pkg"
+ downloadURL="$(downloadURLFromGit twocanoes xcreds)"
+ #appNewVersion="$(versionFromGit twocanoes xcreds)" # GitHub tag contain “_” and not “.” so our function fails to get the right version
+ appNewVersion=$(echo "$downloadURL" | sed -E 's/.*XCreds_.*-([0-9.]*)\.pkg/\1/')
+ expectedTeamID="UXP6YEHSPW"
+ ;;
diff --git a/fragments/labels/zoomoutlookplugin.sh b/fragments/labels/zoomoutlookplugin.sh
new file mode 100644
index 0000000..15d45d5
--- /dev/null
+++ b/fragments/labels/zoomoutlookplugin.sh
@@ -0,0 +1,10 @@
+zoomoutlookplugin)
+ name="Zoom Outlook Plugin"
+ appName="PluginLauncher.app"
+ targetDir="/Applications/ZoomOutlookPlugin"
+ type="pkg"
+ downloadURL="https://zoom.us/client/latest/ZoomMacOutlookPlugin.pkg"
+ appNewVersion="$(curl -fsIL ${downloadURL} | grep -i ^location | cut -d "/" -f5 | cut -d "." -f1-3)"
+ expectedTeamID="BJ4HAAB9B3"
+ blockingProcesses=( "PluginLauncher" )
+ ;;
diff --git a/fragments/labels/zotero.sh b/fragments/labels/zotero.sh
new file mode 100644
index 0000000..ef54e67
--- /dev/null
+++ b/fragments/labels/zotero.sh
@@ -0,0 +1,8 @@
+zotero)
+ name="Zotero"
+ type="dmg"
+ downloadURL="https://www.zotero.org/download/client/dl?channel=release&platform=mac&version=$(curl -fs "https://www.zotero.org/download/" | grep -Eio '"mac":"(.*)' | cut -d '"' -f 4)"
+ expectedTeamID="8LAYR367YV"
+ appNewVersion=$(curl -fs "https://www.zotero.org/download/" | grep -Eio '"mac":"(.*)' | cut -d '"' -f 4)
+ #Company="Corporation for Digital Scholarship"
+ ;;
diff --git a/fragments/main.sh b/fragments/main.sh
index 9a665c7..daf6b78 100644
--- a/fragments/main.sh
+++ b/fragments/main.sh
@@ -15,10 +15,33 @@ fi
# MARK: application download and installation starts here
+# Debug output of all variables in a label
+printlog "name=${name}" DEBUG
+printlog "appName=${appName}" DEBUG
+printlog "type=${type}" DEBUG
+printlog "archiveName=${archiveName}" DEBUG
+printlog "downloadURL=${downloadURL}" DEBUG
+printlog "curlOptions=${curlOptions}" DEBUG
+printlog "appNewVersion=${appNewVersion}" DEBUG
+printlog "appCustomVersion function: $(if type 'appCustomVersion' 2>/dev/null | grep -q 'function'; then echo "Defined. ${appCustomVersion}"; else; echo "Not defined"; fi)" DEBUG
+printlog "versionKey=${versionKey}" DEBUG
+printlog "packageID=${packageID}" DEBUG
+printlog "pkgName=${pkgName}" DEBUG
+printlog "choiceChangesXML=${choiceChangesXML}" DEBUG
+printlog "expectedTeamID=${expectedTeamID}" DEBUG
+printlog "blockingProcesses=${blockingProcesses}" DEBUG
+printlog "installerTool=${installerTool}" DEBUG
+printlog "CLIInstaller=${CLIInstaller}" DEBUG
+printlog "CLIArguments=${CLIArguments}" DEBUG
+printlog "updateTool=${updateTool}" DEBUG
+printlog "updateToolArguments=${updateToolArguments}" DEBUG
+printlog "updateToolRunAsCurrentUser=${updateToolRunAsCurrentUser}" DEBUG
+#printlog "Company=${Company}" DEBUG # Not used
+
if [[ ${INTERRUPT_DND} = "no" ]]; then
# Check if a fullscreen app is active
if hasDisplaySleepAssertion; then
- cleanupAndExit 1 "active display sleep assertion detected, aborting" ERROR
+ cleanupAndExit 24 "active display sleep assertion detected, aborting" ERROR
fi
fi
@@ -60,6 +83,11 @@ case $LOGO in
LOGO="/Library/Intune/Microsoft Intune Agent.app/Contents/Resources/AppIcon.icns"
if [[ -z $MDMProfileName ]]; then; MDMProfileName="Management Profile"; fi
;;
+ ws1)
+ # Workspace ONE (AirWatch)
+ LOGO="/Applications/Workspace ONE Intelligent Hub.app/Contents/Resources/AppIcon.icns"
+ if [[ -z $MDMProfileName ]]; then; MDMProfileName="Device Manager"; fi
+ ;;
esac
if [[ ! -a "${LOGO}" ]]; then
if [[ $(sw_vers -buildVersion) > "19" ]]; then
@@ -75,7 +103,7 @@ printlog "Label type: $type" INFO
# MARK: extract info from data
if [ -z "$archiveName" ]; then
case $type in
- dmg|pkg|zip|tbz)
+ dmg|pkg|zip|tbz|bz2)
archiveName="${name}.$type"
;;
pkgInDmg)
@@ -101,7 +129,7 @@ fi
if [ -z "$targetDir" ]; then
case $type in
- dmg|zip|tbz|app*)
+ dmg|zip|tbz|bz2|app*)
targetDir="/Applications"
;;
pkg*)
@@ -132,7 +160,7 @@ fi
# MARK: change directory to temporary working directory
printlog "Changing directory to $tmpDir" DEBUG
if ! cd "$tmpDir"; then
- cleanupAndExit 1 "error changing directory $tmpDir" ERROR
+ cleanupAndExit 13 "error changing directory $tmpDir" ERROR
fi
# MARK: get installed version
@@ -155,6 +183,10 @@ if [[ -n $appNewVersion ]]; then
printlog "notifying"
displaynotification "$message" "No update for $name!"
fi
+ if [[ $DIALOG_CMD_FILE != "" ]]; then
+ updateDialog "complete" "Latest version already installed..."
+ sleep 2
+ fi
cleanupAndExit 0 "No newer version." REQ
fi
else
@@ -168,6 +200,8 @@ fi
# MARK: check if this is an Update and we can use updateTool
if [[ (-n $appversion && -n "$updateTool") || "$type" == "updateronly" ]]; then
printlog "appversion & updateTool"
+ updateDialog "wait" "Updating..."
+
if [[ $DEBUG -ne 1 ]]; then
if runUpdateTool; then
finishing
@@ -194,8 +228,28 @@ else
displaynotification "Downloading new $name" "Download in progress …"
fi
fi
- curlDownload=$(curl -v -fsL --show-error ${curlOptions} "$downloadURL" -o "$archiveName" 2>&1)
- curlDownloadStatus=$(echo $?)
+
+ if [[ $DIALOG_CMD_FILE != "" ]]; then
+ # pipe
+ pipe="$tmpDir/downloadpipe"
+ # initialise named pipe for curl output
+ initNamedPipe create $pipe
+
+ # run the pipe read in the background
+ readDownloadPipe $pipe "$DIALOG_CMD_FILE" & downloadPipePID=$!
+ printlog "listening to output of curl with pipe $pipe and command file $DIALOG_CMD_FILE on PID $downloadPipePID" DEBUG
+
+ curlDownload=$(curl -fL -# --show-error ${curlOptions} "$downloadURL" -o "$archiveName" 2>&1 | tee $pipe)
+ # because we are tee-ing the output, we want the pipe status of the first command in the chain, not the most recent one
+ curlDownloadStatus=$(echo $pipestatus[1])
+ killProcess $downloadPipePID
+
+ else
+ printlog "No Dialog connection, just download" DEBUG
+ curlDownload=$(curl -v -fsL --show-error ${curlOptions} "$downloadURL" -o "$archiveName" 2>&1)
+ curlDownloadStatus=$(echo $?)
+ fi
+
deduplicatelogs "$curlDownload"
if [[ $curlDownloadStatus -ne 0 ]]; then
#if ! curl --location --fail --silent "$downloadURL" -o "$archiveName"; then
@@ -237,8 +291,10 @@ if [[ $currentUser != "loginwindow" && $NOTIFY == "all" ]]; then
printlog "notifying"
if [[ $updateDetected == "YES" ]]; then
displaynotification "Updating $name" "Installation in progress …"
+ updateDialog "wait" "Updating..."
else
displaynotification "Installing $name" "Installation in progress …"
+ updateDialog "wait" "Installing..."
fi
fi
@@ -258,7 +314,7 @@ case $type in
zip)
installFromZIP
;;
- tbz)
+ tbz|bz2)
installFromTBZ
;;
pkgInDmg)
@@ -275,6 +331,8 @@ case $type in
;;
esac
+updateDialog "wait" "Finishing..."
+
# MARK: Finishing — print installed application location and version
finishing
diff --git a/fragments/version.sh b/fragments/version.sh
index cdefeb2..a243768 100644
--- a/fragments/version.sh
+++ b/fragments/version.sh
@@ -1 +1 @@
-10.0beta
+10.0beta3
diff --git a/utils/assemble.sh b/utils/assemble.sh
index 834a0c1..e92a9f3 100755
--- a/utils/assemble.sh
+++ b/utils/assemble.sh
@@ -120,6 +120,7 @@ chmod +x $destination_file
# run script with remaining arguments
if [[ $runScript -eq 1 ]]; then
$destination_file "$@"
+ exit_code=$?
fi
# copy the script to root of repo when flag is set
@@ -186,3 +187,5 @@ if [[ $notarizePkg -eq 1 ]]; then
echo "# Stapling $productpath"
xcrun stapler staple "$productpath"
fi
+
+exit $exit_code
diff --git a/utils/buildLabel.sh b/utils/buildLabel.sh
index 6b200df..17b2663 100755
--- a/utils/buildLabel.sh
+++ b/utils/buildLabel.sh
@@ -265,7 +265,7 @@ echo "archivePath: $archivePath"
# So we want to investigate which one has the filename
try1archiveName=${${archiveTempName##*/}%%\?*}
try2archiveName=${${archivePath##*/}%%\?*}
-fileName_re='^([a-zA-Z0-9\_.%-]*)\.(dmg|pkg|zip|tbz|gz)$' # regular expression for matching
+fileName_re='^([a-zA-Z0-9\_.%-]*)\.(dmg|pkg|zip|tbz|gz|bz2)$' # regular expression for matching
if [[ "${try1archiveName}" =~ $fileName_re ]]; then
archiveName=${try1archiveName}
elif [[ "${try2archiveName}" =~ $fileName_re ]]; then
@@ -293,7 +293,7 @@ if [ "$archiveExt" = "pkg" ]; then
elif [ "$archiveExt" = "dmg" ]; then
echo "Diskimage found"
dmgInvestigation
-elif [ "$archiveExt" = "zip" ] || [ "$archiveExt" = "tbz" ]; then
+elif [ "$archiveExt" = "zip" ] || [ "$archiveExt" = "tbz" ] || [ "$archiveExt" = "bz2" ]; then
echo "Compressed file found"
# unzip the archive
tar -xf "$archiveName"
diff --git a/utils/checkLabels.sh b/utils/checkLabels.sh
index c682717..3063846 100755
--- a/utils/checkLabels.sh
+++ b/utils/checkLabels.sh
@@ -52,9 +52,22 @@ downloadURLFromGit() { # $1 git user name, $2 git repo name
gitusername=${1?:"no git user name"}
gitreponame=${2?:"no git repo name"}
+ if [[ $type == "pkgInDmg" ]]; then
+ filetype="dmg"
+ elif [[ $type == "pkgInZip" ]]; then
+ filetype="zip"
+ else
+ filetype=$type
+ fi
+
#githubPart="$gitusername/$gitreponame/releases/download"
#echo "$githubPart"
- downloadURL="https://github.com/$gitusername/$gitreponame/releases/latest"
+ #downloadURL="https://github.com/$gitusername/$gitreponame/releases/latest"
+ if [ -n "$archiveName" ]; then
+ downloadURL=https://github.com$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*$archiveName" | head -1)
+ else
+ downloadURL=https://github.com$(curl -sfL "https://github.com/$gitusername/$gitreponame/releases/latest" | tr '"' "\n" | grep -i "^/.*\/releases\/download\/.*\.$filetype" | head -1)
+ fi
echo "$downloadURL"
return 0
}
@@ -63,7 +76,7 @@ versionFromGit() { # $1 git user name, $2 git repo name
gitusername=${1?:"no git user name"}
gitreponame=${2?:"no git repo name"}
- appNewVersion=$(curl --silent --fail "https://github.com/$gitusername/$gitreponame/releases/latest" | sed -E 's/.*tag\/(.*)\">.*/\1/g' | sed 's/[^0-9\.]//g')
+ appNewVersion=$(curl -sLI "https://github.com/$gitusername/$gitreponame/releases/latest" | grep -i "^location" | tr "/" "\n" | tail -1 | sed 's/[^0-9\.]//g')
if [ -z "$appNewVersion" ]; then
printlog "could not retrieve version number for $gitusername/$gitreponame: $appNewVersion"
exit 9
@@ -182,13 +195,14 @@ for fixedArch in i386 arm64; do
#caseLabel
if cat "${labels_dir}/${label}.sh" | grep -v -E '^[a-z0-9\_-]*(\)|\|\\)$' | grep -v ";;" > checkLabelCurrent.sh; then
+ INSTALL=force # This is only to prevent various Microsoft labels from running "msupdate --list"
source checkLabelCurrent.sh
echo "Name: $name"
echo "Download URL: $downloadURL"
echo "Type: $type"
case $type in
- dmg|pkg|zip|tbz)
+ dmg|pkg|zip|tbz|bz2)
expectedExtension="$type"
;;
pkgInDmg)
diff --git a/utils/test-pr.sh b/utils/test-pr.sh
new file mode 100755
index 0000000..526ee56
--- /dev/null
+++ b/utils/test-pr.sh
@@ -0,0 +1,31 @@
+#!/bin/zsh
+
+# this will checkout and test a pr
+
+# requires the gh tool and the cwd to be the repo base
+#
+# usage: utils/test-pr.sh