06-10-2022 05:43 AM - edited 06-10-2022 05:44 AM
Hello Jamf Community,
I previously posted this a couple weeks ago but still am struggling to figure out exactly how to get it working.
I am trying to create a script that will prompt a user with a popup box on which application they'd like to uninstall (only apps we deem approved). For example, a popup would come up and ask someone "Select an app you'd like to uninstall" with a list of apps such as, Google Chrome, Firefox, Adobe, etc.
Currently I have script that I feel is about 90% of the way there but still can't figure out how to get it completely working. I'll post it below.
Also, if there's any easier way to do this, please do let me know as well!
Any help is greatly appreciated! There may be some unnecessary lines in the script just FYI. Here's the script:
#!/bin/bash
# Parameters
app1="$4"
app2="$5"
app3="$6"
app4="$7"
app5="$8"
appList="$4
$5
$6
$7
$8"
uninstallApp="choose from list every paragraph of \"$appList\" with title \"Application Uninstaller\" with prompt \"Select which application you'd like to uninstall: \" multiple selections allowed false empty selection allowed false"
chosenApp=$( /usr/bin/osascript -e "$uninstallApp" )
exit
# Jamf helper information
jamfHelper="/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper"
description1="Select one of the following approved applications to uninstall:"
description2="The software you selected has been uninstalled."
invalidEntry="Invalid Entry"
########Functions###########
uninstallSuccessful(){
buttonClicked=$("$jamfHelper" -windowType hud -lockHUD -windowPosition "center" -title "Software Uninstalled" -description "${description2}" -alignDescription "Left" -button1 "OK")
}
invalidEntry(){
buttonClicked=$("$jamfHelper" -windowType hud -lockHUD -windowPosition "center" -title "Invalid Entry" -description "$invalidEntry" -alignDescription "Left" -button1 "OK")
}
initializeUninstaller1(){
# Force Quit the app
ps aux | grep "$4.app" | grep -v "grep" | awk '{print $2}' | xargs kill -15
# Remove the App
/bin/rm -Rf "/Applications/$4.app"
}
initializeUninstaller2(){
# Force Quit the app
ps aux | grep "$5.app" | grep -v "grep" | awk '{print $2}' | xargs kill -15
# Remove the App
/bin/rm -Rf "/Applications/$5.app"
}
initializeUninstaller3(){
# Force Quit the app
ps aux | grep "$6.app" | grep -v "grep" | awk '{print $2}' | xargs kill -15
# Remove the App
/bin/rm -Rf "/Applications/$6.app"
}
appCheck(){
if [[ $chosenApp == $4 ]]; then
echo "User selected $4"
echo "Initializing Software Uninstaller"
initializeUninstaller1
uninstallSuccessful
elif [[ $chosenApp == $5 ]]; then
echo "User selected $5"
echo "Initializing Software Uninstaller"
initializeUninstaller2
uninstallSuccessful
elif [[ $chosenApp == $6 ]]; then
echo "User selected $6"
echo "Initializing Software Uninstaller"
initializeUninstaller3
uninstallSuccessful
elif [[ $chosenApp != "2745wnfeljf23490" ]]; then
echo "Invalid Entry"
invalidEntry
exit 0
fi
}
appCheck
exit 0 ## Success
exit 1 ## Failure
Solved! Go to Solution.
Posted on 06-10-2022 07:52 AM
I updated the script. The `pgrep` call was looking for the full app name and not the process name.
`pgrep $1` is getting the variable that was passed to the function. Inside a shell script when you send a variable to a function, you can access that variable as `$1`. Make sense?
#!/bin/bash
appList="$4
$5
$6
$7
$8"
uninstallApp="choose from list every paragraph of \"$appList\" with title \"Application Uninstaller\" with prompt \"Select which application you'd like to uninstall: \" multiple selections allowed false empty selection allowed false"
chosenApp=$( /usr/bin/osascript -e "$uninstallApp" )
# Jamf helper information
jamfHelper="/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper"
description1="Select one of the following approved applications to uninstall:"
description2="The software you selected has been uninstalled."
invalidEntry="Invalid Entry"
########Functions###########
uninstallSuccessful(){
buttonClicked=$("$jamfHelper" -windowType hud -lockHUD -windowPosition "center" -title "Software Uninstalled" -description "${description2}" -alignDescription "Left" -button1 "OK")
}
invalidEntry(){
buttonClicked=$("$jamfHelper" -windowType hud -lockHUD -windowPosition "center" -title "Invalid Entry" -description "$invalidEntry" -alignDescription "Left" -button1 "OK")
}
initializeUninstaller(){
# Force Quit the app
pgrep $1 | xargs kill -15
# Remove the App
/bin/rm -Rf "/Applications/$1.app"
}
if [[ -d "/Applications/$chosenApp.app" ]]; then
echo "User selected $chosenApp"
echo "Initializing Software Uninstaller"
initializeUninstaller "$chosenApp" # pass the app name to the function
uninstallSuccessful
exit 0
else
invalidEntry
exit 1
fi
Posted on 06-10-2022 06:19 AM
Where exactly is it failing?
I would recommend adding echo commands to confirm your variables as your script runs to see if something isn't coming out as it should.
And I may be missing something, but what is the purpose of the grep -v "grep" command in your initializeUninstaller functions?
06-10-2022 06:38 AM - edited 06-10-2022 06:39 AM
Hey Fluffy,
Thanks for the reply! I actually grabbed that from another script someone provided me a couple weeks ago in a previous post. I'm not too familiar with writing scripts so I just left it there. Do you think it should be removed?
So running the policy currently provides a prompt (screenshot below) on which app to uninstall. The issue is after the apple script policy, it doesn't actually process the uninstallation. The policy fails because of "done" in the apple script. Not sure how to get it to feed to the next part of the script where it runs (post user selection) "appcheck".
Screenshot:
Policy Results:
[STEP 1 of 4]
Executing Policy Universal App Uninstaller - Testing
[STEP 2 of 4]
Running script Universal Applications Uninstaller...
Script exit code: 2
Script result: /Library/Application Support/JAMF/tmp/Universal Applications Uninstaller: line 20: syntax error near unexpected token `done'
/Library/Application Support/JAMF/tmp/Universal Applications Uninstaller: line 20: `done'
Error running script: return code was 2.
[STEP 3 of 4]
[STEP 4 of 4]
Posted on 06-10-2022 07:11 AM
You have an `exit` command on line 22, right after you call the `osascript` on line 20. That will stop your script from moving forward. Not sure why you're receiving that error on line 20 though. I ran this without issue on my machine.
You can, however, cleanup your script a bit and make it more compact. There's no need for the parameter list at the top. You never use it, unless you have plans for it in the future. And if you do, why not use those variables when creating your `appList` array?
You can generalize your `initializeUninstaller` function so that you just pass the `$chosenApp` variable to the function. No need for an individual uninstall function for each app.
The `grep -v "grep"` command is to ignore the output of your `grep` command prior. Confusing, I know, but if you were to issue `ps aux | grep "Safari.app"` you'd see that one of the items returned would be that `grep "Safari.app"` command. Instead you can use `pgrep` which looks for the process ID of any running process with the name passed. So the above becomes `pgrep Safari`.
I've cleaned up the code a little and tested on my Monterey device and this seems to work. Granted I am running this from Code Runner and not via a policy, so you may need to test in Jamf Pro.
#!/bin/bash
appList="$4
$5
$6
$7
$8"
uninstallApp="choose from list every paragraph of \"$appList\" with title \"Application Uninstaller\" with prompt \"Select which application you'd like to uninstall: \" multiple selections allowed false empty selection allowed false"
chosenApp=$( /usr/bin/osascript -e "$uninstallApp" )
chosenApp=$chosenApp.app
# Jamf helper information
jamfHelper="/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper"
description1="Select one of the following approved applications to uninstall:"
description2="The software you selected has been uninstalled."
invalidEntry="Invalid Entry"
########Functions###########
uninstallSuccessful(){
buttonClicked=$("$jamfHelper" -windowType hud -lockHUD -windowPosition "center" -title "Software Uninstalled" -description "${description2}" -alignDescription "Left" -button1 "OK")
}
invalidEntry(){
buttonClicked=$("$jamfHelper" -windowType hud -lockHUD -windowPosition "center" -title "Invalid Entry" -description "$invalidEntry" -alignDescription "Left" -button1 "OK")
}
initializeUninstaller(){
# Force Quit the app
pgrep $1 | xargs kill -15
# Remove the App
/bin/rm -Rf "/Applications/$1"
}
if [[ -d "/Applications/$chosenApp" ]]; then
echo "User selected $chosenApp"
echo "Initializing Software Uninstaller"
initializeUninstaller "$chosenApp" # pass the app name to the function
uninstallSuccessful
exit 0
else
invalidEntry
exit 1
fi
06-10-2022 07:44 AM - edited 06-10-2022 07:48 AM
@stevewood This is almost perfect!!! Thank you so much!
The one issue I still see happening is it's not quitting the app prior to uninstallation. Is there a reason for that?
In the script, just out of curiosity, I see the "pgrep $1"...what is that grabbing? The mount point? Or should that be changed to $chosenApp or $4, $5 etc?
Also if you can, how would you add an "invalid entry" or "app not found" popup, let's say if a user selects to uninstall Firefox but they didn't have Firefox on their system?
Posted on 06-10-2022 07:52 AM
I updated the script. The `pgrep` call was looking for the full app name and not the process name.
`pgrep $1` is getting the variable that was passed to the function. Inside a shell script when you send a variable to a function, you can access that variable as `$1`. Make sense?
#!/bin/bash
appList="$4
$5
$6
$7
$8"
uninstallApp="choose from list every paragraph of \"$appList\" with title \"Application Uninstaller\" with prompt \"Select which application you'd like to uninstall: \" multiple selections allowed false empty selection allowed false"
chosenApp=$( /usr/bin/osascript -e "$uninstallApp" )
# Jamf helper information
jamfHelper="/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper"
description1="Select one of the following approved applications to uninstall:"
description2="The software you selected has been uninstalled."
invalidEntry="Invalid Entry"
########Functions###########
uninstallSuccessful(){
buttonClicked=$("$jamfHelper" -windowType hud -lockHUD -windowPosition "center" -title "Software Uninstalled" -description "${description2}" -alignDescription "Left" -button1 "OK")
}
invalidEntry(){
buttonClicked=$("$jamfHelper" -windowType hud -lockHUD -windowPosition "center" -title "Invalid Entry" -description "$invalidEntry" -alignDescription "Left" -button1 "OK")
}
initializeUninstaller(){
# Force Quit the app
pgrep $1 | xargs kill -15
# Remove the App
/bin/rm -Rf "/Applications/$1.app"
}
if [[ -d "/Applications/$chosenApp.app" ]]; then
echo "User selected $chosenApp"
echo "Initializing Software Uninstaller"
initializeUninstaller "$chosenApp" # pass the app name to the function
uninstallSuccessful
exit 0
else
invalidEntry
exit 1
fi
Posted on 06-10-2022 08:31 AM
Awesome thank you so much. I really appreciate it! Finally got it fully working :D.
Yep that makes complete sense!
Thanks again!!
Posted on 06-22-2022 11:59 AM
I added this script to a self-service policy to test, but when I run it, it doesn't do anything. I think I'm missing something.
Posted on 06-22-2022 12:21 PM
Did you provide the application name(s) to remove as Parameter 4, 5, 6, 7, and 8 in Jamf Pro? Or you can hardcode the applications by putting that in the 'appList' variable.
For example, if you wanted to remove Google Chrome and Microsoft Edge, you could set 'appList' like this:
appList="Google Chrome
Microsoft Edge"
Posted on 06-22-2022 01:15 PM
Whoops! Works great.
Posted on 06-22-2022 04:08 PM
Is it possible to configure the script to uninstall the app when running it in self-service instead of selecting the app and then uninstall?
Posted on 06-23-2022 03:29 PM
If you want to place a policy to uninstall a specific app, like Google Chrome, in Self Service, you can hard code that app and remove the 'appList' and remove the notifications that ask the user to choose.
This is a very simple (and untested) script that could accomplish that. Use Parameter 4 in Jamf Pro to pass the application that you want to uninstall.
#!/bin/bash
appToUninstall="$4"
########Functions###########
initializeUninstaller(){
# Force Quit the app
pgrep $1 | xargs kill -15
# Remove the App
/bin/rm -Rf "/Applications/$1.app"
}
if [[ -d "/Applications/$appToUninstall.app" ]]; then
initializeUninstaller "$appToUninstall" # pass the app name to the function
exit 0
else
echo "Application is not installed on system."
exit 1
fi
This has no messaging at all, so you would want to add something via the policy or add to the script.
Posted on 11-12-2022 05:52 PM
@stevewood This works perfectly for what I need! Amazing approach - short, sweet, and simple!
Posted on 11-28-2022 08:06 AM
Hello @stevewood - Please I need a little more assistance on this as I'm very new to Jamf. Your approach worked perfectly but I realized that I still have a left-over app and folder that I would like to remove when I run the policy.
Avast has an Uninstaller app called "Avast One Uninstaller" or "Avast Uninstaller" for some of our old machines in --> \Applications\Avast
There is also an Avast folder that I would like to remove in --> \Library\Application Support\Avast
Please any help here is appreciated!
#!/bin/bash
appToUninstall="$4"
########Functions###########
initializeUninstaller(){
# Force Quit the app
pgrep $1 | xargs kill -15
# Remove the App
/bin/rm -Rf "/Applications/$1.app"
rm -R /Applications/*Avast*
rm -R /Library/Application\ Support/*Avast*
}
if [[ -d "/Applications/$appToUninstall.app" ]]; then
initializeUninstaller "$appToUninstall" # pass the app name to the function
exit 0
else
echo "Application is not installed on system."
exit 1
fi
Posted on 11-30-2022 09:14 AM
Have you checked the Avast app bundle for an uninstall script? I found this old Jamf Nation post that references an uninstall.sh in "/Applications/Avast.app/Contents/Backend/utils/com.avast.uninstall.app/Contents/Resources/uninstall.sh". If that script is available I would try using that instead of the script I posted. Using the one provided by Avast should get all of the bits removed.
You can also check in the app bundles for those Uninstaller apps. There may be an uninstall script in there. You can use an if/then to test for the presence of the different versions of Uninstaller apps.
Posted on 12-03-2022 10:19 PM
Thanks so much for your response. Since your respond, I have been looking for the Uninstall script all over and I have not been successful in locating any script -- Seems that Avast have made some changes there - Avast and Avast one, both have an uninstallation app, is there a way to add a script line to call that Uninstallation file instead? If Jamf can run that uninstallation app, it will solve my issue. I'm just a month into Jamf, so I'm a newbie with scripting :) Thanks!
Posted on 12-04-2022 12:00 AM
Hi @stevewood So, started reading every document if in the Avast app and I ran into this segment of Uninstaller paths that caught my eyes (eyes were wide open!)
-------------------------------------------
see attached.
------------------------------------------
so based on the above area of interest, I focused on these two paths to play with:
(1) /Applications/Avast.app/Contents/Backend/hub/uninstalluser.sh
(2) /Applications/Avast.app/Contents/Backend/hub/uninstall_wrapper.sh
None worked from my Mac Terminal, so I stared manipulating few things and I discovered that running this command on terminal did clean out Avast from my system -->
sudo /Applications/Avast.app/Contents/Backend/hub/uninstall.sh
How do I set this up as a policy in Jamf to run silently in the background. Someone wrote to configure it in Files and Process.
Thanks again.
Posted on 12-04-2022 12:01 AM
-------------------------------------------
com.avast.one.uninstaller.xpc/Library/LaunchDaemons/com.avast.one.uninstaller.xpc.plist/ Applications/Avast.app/Contents/Backend/hub/uninstall_wrapper.sh
/Applications/Avast.app/Contents/Backend/hub/uninstalluser.sh/Library/Application Support/Avast/config/license.avastlicdata/Applications/Avast.app/Contents/Backend/version.tag
/Applications/Avast.app/Contents/Backend/variant.tagContents/Resources/com.avast.one.uninstaller.xpc.cleanup.sh/Library/PrivilegedHelperTools/%@/bin/launchctlremove//
------------------------------------------
Posted on 12-05-2022 08:10 AM
Thanks again for creating the path! All looks good on my end, using the simple File and Process policy did the job! I'm all set now.
06-23-2022 05:24 AM - edited 06-23-2022 05:29 AM
@SMR1 The script I use currently uninstalls the app during the self service policy run. I've made some changes to the original script above but I'll post my fully working script that we have in production below in case you want to take a look. Added a JAMF inventory update post uninstall, added some icons, added parameters 10/11, and changed the window type, etc.
#!/bin/bash
appList="$4
$5
$6
$7
$8
$9
${10}
${11}"
uninstallApp="choose from list every paragraph of \"$appList\" with title \"Application Uninstaller\" with prompt \"Select which approved application you'd like to uninstall: \" multiple selections allowed false empty selection allowed false"
chosenApp=$( /usr/bin/osascript -e "$uninstallApp" )
# Jamf helper information
jamfHelper="/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper"
description1="The $chosenApp application has been uninstalled."
invalidEntry="You either cancelled or the selection you made was invalid.
If the application you'd like to remove is not listed, reach out to the IT Support Team for further assistance."
########Functions###########
uninstallSuccessful(){
buttonClicked=$("$jamfHelper" -windowType utility -windowPosition "center" -title "Software Uninstalled" -description "${description1}" -alignDescription "Left" -icon "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/ErasingIcon.icns" -button1 "OK")
}
invalidEntry(){
buttonClicked=$("$jamfHelper" -windowType utility -windowPosition "center" -title "Invalid Entry" -description "$invalidEntry" -alignDescription "Left" -icon "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/ToolbarDeleteIcon.icns" -button1 "OK")
}
initializeUninstaller(){
# Force Quit the app
pgrep $1 | xargs kill -15
# Remove the App
/bin/rm -Rf "/Applications/$1.app"
# Force Quit the app again (for redundancy)
pgrep $1 | xargs kill -15
# Update JAMF Inventory
sudo jamf recon
}
########End of Functions###########
if [[ -d "/Applications/$chosenApp.app" ]]; then
echo "User selected $chosenApp"
echo "Initializing Software Uninstaller..."
initializeUninstaller "$chosenApp" # pass the app name to the function
uninstallSuccessful
echo "$chosenApp uninstalled"
exit 0
else
echo "Invalid Entry"
invalidEntry
echo "User cancelled or made an invalid selection"
exit 0
fi
Posted on 07-21-2022 04:31 PM
Great script! Has anyone found a way to change it so it will return all apps, but exclude apps in the app list instead?
I got this this to return all apps, but it seems to be ignoring my exclusion list.
excludeAppList="Google Chrome.app
Microsoft Edge.app
"
appList=$(mdfind -onlyin /Applications "kMDItemCFBundleIdentifier != com.apple.* && kMDItemFSName != "$excludeAppList" && kMDItemKind = Application" | awk -F'/' '{print $NF}' | sort -f)
Posted on 07-22-2022 06:31 AM
I don't think mdfind likes having multiple lines fed to it. Instead you can pipe it into grep -v to take out what you have in your variable.
excludeAppList="Google Chrome.app
Microsoft Edge.app"
appList=$(mdfind -onlyin /Applications "kMDItemCFBundleIdentifier != com.apple.* && kMDItemKind = Application" | grep -v "$excludeAppList" | awk -F'/' '{print $NF}' | sort -f)
Make sure to take out the new line in your excludeAppList variable as I did above or grep -v will remove everything piped from mdfind instead.
07-24-2022 02:50 PM - edited 07-24-2022 06:54 PM
That worked perfectly, thanks!
I did have to also remove the file extension, otherwise I ended up with "Application.app.app".
So for anyone else that comes across this, this is the final working solution to show the user all apps in "/Applications", except apps listed in your "excludeAppList":
excludeAppList="Google Chrome.app
Microsoft Edge.app"
appList=$(mdfind -onlyin /Applications "kMDItemCFBundleIdentifier != com.apple.* && kMDItemKind = Application" | grep -v "$excludeAppList" | awk -F'/' '{print $NF}' | cut -f 1 -d '.' | sort -f)
07-24-2022 04:29 PM - edited 07-25-2022 04:06 PM
Edit:
I've tidied things up a bit and added a function to handle if the returned list is empty.
This will show all apps in "/Applications" with the file extension ".app", but without the "com.apple.*" bundle identifier and it will also exclude any apps in your exclusion list.
#!/bin/bash
# List of apps to exculde from being able to uninstall
excludeAppList=".Trash
Google Chrome.app
Citrix Workspace.app
OneDrive.app
Self Service.app
Jamf*
Microsoft*"
# Build App list
appList=$(mdfind -onlyin /Applications "kMDItemCFBundleIdentifier != com.apple.* && kMDItemFSName == *.app" | grep -v "$excludeAppList" | awk -F'/' '{print $NF}' | cut -f 1 -d '.' | sort -f)
# Jamf helper
jamfHelper="/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper"
########Functions###########
uninstallSuccessful(){
description1="The $chosenApp application has been successfully uninstalled."
buttonClicked=$("$jamfHelper" -windowType utility -windowPosition "center" -title "Application Uninstalled" -description "${description1}" -alignDescription "Left" -icon "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/ErasingIcon.icns" -button1 "OK")
}
invalidEntry(){
invalidEntry="You either cancelled or the selection you made was invalid.
If the application you'd like to remove is not listed, please reach out to your IT Support Team for further assistance."
buttonClicked=$("$jamfHelper" -windowType utility -windowPosition "center" -title "Invalid Entry" -description "$invalidEntry" -alignDescription "Left" -icon "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/ToolbarDeleteIcon.icns" -button1 "OK")
}
listEmpty(){
listEmpty="No applications were found or all installed applications are required on your computer."
buttonClicked=$("$jamfHelper" -windowType utility -windowPosition "center" -title "No Applications Found" -description "$listEmpty" -alignDescription "Left" -icon "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/ToolbarInfo.icns" -button1 "OK")
}
initializeUninstaller(){
# Force Quit the app
pgrep $1 | xargs kill -15
# Remove the App
/bin/rm -Rf "/Applications/$1.app"
# Force Quit the app again (for redundancy)
pgrep $1 | xargs kill -15
# Update JAMF Inventory
sudo jamf recon
}
########End of Functions###########
#######Begin Main Routine##########
# If list is emtpy, prompt user and exit
if [ -z "${appList}" ]; then
echo "No apps available for removal"
listEmpty
echo "App list returned as empty. Exiting..."
exit 0
# If list is not empty, show list for user selection.
else
echo "Apps are available for removal. Prompting user with app list..."
uninstallApp="choose from list every paragraph of \"$appList\" with title \"Application Remover\" with prompt \"Select which application you'd like to uninstall:
Please note: Applications that are required to be on your computer will not be listed. \" multiple selections allowed false empty selection allowed false"
chosenApp=$( /usr/bin/osascript -e "$uninstallApp" )
# If selected app exists, uninstall, prompt user and exit.
if [[ -d "/Applications/$chosenApp.app" ]]; then
echo "User selected $chosenApp"
echo "Initializing Software Uninstaller..."
initializeUninstaller "$chosenApp" # pass the app name to the function
uninstallSuccessful
echo "$chosenApp uninstalled"
exit 0
# If user cancelled or selection was invalid, prompt user and exit.
else
echo "Invalid Entry"
invalidEntry
echo "User cancelled or made an invalid selection"
exit 0
fi
fi
Posted on 12-11-2023 05:40 AM
Hello! Tried this script and it works great except one thing :) Its seems to not understans app name with a "." in the name. For example zoom.us
Is there a way to fix this? :)
12-17-2023 06:50 PM - edited 12-18-2023 12:27 PM
Hi, My script is specifically looking for apps with the extension ".app". It's not that can't find anything with "." in the name. The ".us" extension will be the issue for you.
I've modified it so it should now find everything in the "/Applications/" directory except apps with the "com.apple.*" bundle identifier. You may have to update your exclude list depending on what it returns.
#!/bin/bash
# List of apps to exculde from being able to uninstall
excludeAppList=".Trash
Google Chrome.app
Citrix Workspace.app
OneDrive.app
Self Service.app
Jamf*
Microsoft*"
# Build App list
appList=$(mdfind -onlyin /Applications "kMDItemCFBundleIdentifier != com.apple.* | grep -v "$excludeAppList" | awk -F'/' '{print $NF}' | cut -f 1 -d '.' | sort -f)
# Jamf helper
jamfHelper="/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper"
########Functions###########
uninstallSuccessful(){
description1="The $chosenApp application has been successfully uninstalled."
buttonClicked=$("$jamfHelper" -windowType utility -windowPosition "center" -title "Application Uninstalled" -description "${description1}" -alignDescription "Left" -icon "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/ErasingIcon.icns" -button1 "OK")
}
invalidEntry(){
invalidEntry="You either cancelled or the selection you made was invalid.
If the application you'd like to remove is not listed, please reach out to your IT Support Team for further assistance."
buttonClicked=$("$jamfHelper" -windowType utility -windowPosition "center" -title "Invalid Entry" -description "$invalidEntry" -alignDescription "Left" -icon "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/ToolbarDeleteIcon.icns" -button1 "OK")
}
listEmpty(){
listEmpty="No applications were found or all installed applications are required on your computer."
buttonClicked=$("$jamfHelper" -windowType utility -windowPosition "center" -title "No Applications Found" -description "$listEmpty" -alignDescription "Left" -icon "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/ToolbarInfo.icns" -button1 "OK")
}
initializeUninstaller(){
# Force Quit the app
pgrep $1 | xargs kill -15
# Remove the App
/bin/rm -Rf "/Applications/$1.*"
# Force Quit the app again (for redundancy)
pgrep $1 | xargs kill -15
# Update JAMF Inventory
sudo jamf recon
}
########End of Functions###########
#######Begin Main Routine##########
# If list is emtpy, prompt user and exit
if [ -z "${appList}" ]; then
echo "No apps available for removal"
listEmpty
echo "App list returned as empty. Exiting..."
exit 0
# If list is not empty, show list for user selection.
else
echo "Apps are available for removal. Prompting user with app list..."
uninstallApp="choose from list every paragraph of \"$appList\" with title \"Application Remover\" with prompt \"Select which application you'd like to uninstall:
Please note: Applications that are required to be on your computer will not be listed. \" multiple selections allowed false empty selection allowed false"
chosenApp=$( /usr/bin/osascript -e "$uninstallApp" )
# If selected app exists, uninstall, prompt user and exit.
if [[ -d "/Applications/$chosenApp.*" ]]; then
echo "User selected $chosenApp"
echo "Initializing Software Uninstaller..."
initializeUninstaller "$chosenApp" # pass the app name to the function
uninstallSuccessful
echo "$chosenApp uninstalled"
exit 0
# If user cancelled or selection was invalid, prompt user and exit.
else
echo "Invalid Entry"
invalidEntry
echo "User cancelled or made an invalid selection"
exit 0
fi
fi
Posted on 12-17-2023 11:32 PM
Thanks, I will try it out! :) 😃
Posted on 12-20-2023 04:10 AM
The problem was the Zoom app was called zoom.us.app and it did not show up :( I tried the new script but it throws an error lite this. Any ideas? :)
Script result: /Library/Application Support/JAMF/tmp/RV Universal uninstaller: line 87: unexpected EOF while looking for matching `"'
/Library/Application Support/JAMF/tmp/RV Universal uninstaller: line 93: syntax error: unexpected end of file
Posted on 01-09-2024 05:30 AM
Did it work for you? I get an error with the new script :S
Posted on 01-25-2024 07:12 PM
Sorry for the late response. You might have figured it out already, but I left out a quotation that was producing a syntax error and yes, "zoom.us.app" was messing it up as it contains two dots. It should now extract everything before the last dot. Give it a try.
#!/bin/bash
# List of apps to exclude from being able to uninstall
excludeAppList=".Trash
Google Chrome.app
Citrix Workspace.app
OneDrive.app
Self Service.app
Jamf*
Microsoft*"
# Build App list
appList=$(mdfind -onlyin /Applications "kMDItemCFBundleIdentifier != com.apple.*" | grep -v "$excludeAppList" | awk -F'/' '{print $NF}' | rev | cut -d '.' -f 2- | rev | sort -f)
# Jamf helper
jamfHelper="/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper"
######## Functions ###########
uninstallSuccessful() {
description1="The $chosenApp application has been successfully uninstalled."
buttonClicked=$("$jamfHelper" -windowType utility -windowPosition "center" -title "Application Uninstalled" -description "${description1}" -alignDescription "Left" -icon "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/ErasingIcon.icns" -button1 "OK")
}
invalidEntry() {
invalidEntry="You either cancelled or the selection you made was invalid.
If the application you'd like to remove is not listed, please reach out to your IT Support Team for further assistance."
buttonClicked=$("$jamfHelper" -windowType utility -windowPosition "center" -title "Invalid Entry" -description "$invalidEntry" -alignDescription "Left" -icon "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/ToolbarDeleteIcon.icns" -button1 "OK")
}
listEmpty() {
listEmpty="No applications were found or all installed applications are required on your computer."
buttonClicked=$("$jamfHelper" -windowType utility -windowPosition "center" -title "No Applications Found" -description "$listEmpty" -alignDescription "Left" -icon "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/ToolbarInfo.icns" -button1 "OK")
}
initializeUninstaller() {
# Force Quit the app
pgrep "$1" | xargs kill -15
# Remove the App
/bin/rm -Rf "/Applications/$1.app"
# Force Quit the app again (for redundancy)
pgrep "$1" | xargs kill -15
# Update JAMF Inventory
sudo jamf recon
}
######## End of Functions ###########
####### Begin Main Routine ##########
# If list is empty, prompt user and exit
if [ -z "${appList}" ]; then
echo "No apps available for removal"
listEmpty
echo "App list returned as empty. Exiting..."
exit 0
else
echo "Apps are available for removal. Prompting user with app list..."
uninstallApp="choose from list every paragraph of \"$appList\" with title \"Application Remover\" with prompt \"Select which application you'd like to uninstall:
Please note: Applications that are required to be on your computer will not be listed. \" multiple selections allowed false empty selection allowed false"
chosenApp=$( /usr/bin/osascript -e "$uninstallApp" )
# If selected app exists, uninstall, prompt user and exit.
if [[ -d "/Applications/$chosenApp.app" ]]; then
echo "User selected $chosenApp"
echo "Initializing Software Uninstaller..."
initializeUninstaller "$chosenApp" # pass the app name to the function
uninstallSuccessful
echo "$chosenApp uninstalled"
exit 0
else
echo "Invalid Entry"
invalidEntry
echo "User cancelled or made an invalid selection"
exit 0
fi
fi
Posted on 11-29-2022 08:07 AM
Hello Jamf Community!
Please I need a little more assistance on this as I'm very new to Jamf. I had used this approach by @stevewood that worked perfectly but I realized that I still have a left-over app and folder that I would like to remove when I run the Jamf policy.
Avast has an Uninstaller app called "Avast One Uninstaller" or "Avast Uninstaller" for some of our old machines in --> \Applications\Avast
There is also an Avast folder that I would like to remove in --> \Library\Application Support\Avast
Please any help is appreciated!
Here is the script -- the two "rm -R" are where I'm having some issues :(
#!/bin/bash
appToUninstall="$4"
########Functions###########
initializeUninstaller(){
# Force Quit the app
pgrep $1 | xargs kill -15
# Remove the App
/bin/rm -Rf "/Applications/$1.app"
rm -R /Applications/*Avast*
rm -R /Library/Application\ Support/Avast
}
if [[ -d "/Applications/$appToUninstall.app" ]]; then
initializeUninstaller "$appToUninstall" # pass the app name to the function
exit 0
else
echo "Application is not installed on system."
exit 1
fi