In the past I have had a master Kitchen Sink
Python script that will call the jamf API and return every single policy ID that is tied to a software install and then install it. Then run local code to build a CSV of all 32bit apps, their file path, and what they are. If your users are admin and can install anything, then not sure how you are supposed to be on the hook to validate all 32bit apps. I know you can put forth best effort for this but tossing your entire app install base into an EA, that runs every recon forever, just sounds like a whole lot of pain waiting to happen.
I have also been communicating to end users for the past 18 months that with Catalina 32 bit apps are probably going to be dead.
My end users for Mac, in general, never even read emails regarding stuff to be wary of with Mac's. I could talk to them till I'm blue in the face about needing to update 32-bit software to 64-bit software and all I would get from them is a deer in the headlights look...they don't know what it is, what it means, or care. So, the onus is on me to get this done. The folks that used to manage the Mac's on our campus are all PC guys and don't like to do anything with Mac's. Whenever they would get a ticket for something Mac related, it usually sat for a bit before they worked on it. Even know, if someone needs something installed, they just go and do it on the unit, without even thinking, "Hey, we have a tool that manages the Mac's! Perhaps we should have the Mac guy (me) add this to Jamf to make this easier in the future." So, I'm coming into a mess and am trying to get it going smoothly. I have a long way to go, but I'm learning and would rather follow best practices from the get-go. So far this has been the biggest issue I have run into and I have 90 replacement computers that are more than likely going to ship with Catalina installed, so I need this 32-bit inventory done ASAP. My thought when running this EA is to only run it for a week, to give all computers time to report in (I have a lot of laptops that are used offline), then disable it.
For your situation if time is the biggest factor, then you might be right, your only option might be the EA route. Just remember to turn it off when you're done.
Am I missing something? I could have swore that when I read through Jamf's solution that it was stripping out the application names and only reported back the number of 32 bit applications. Aside from the fact that I don't find that number to be all that useful in the grand scheme of things, from a technical standpoint we're only talking about a single number being housed in the database from the EA, aren't we?
@jhuls You are not incorrect, technically. The example script Jamf posts on that blog only captures the total number of 32 bit apps on the device as an integer, which has little impact to the database I'd imagine. But... as @kwoodard mentioned above, they do say the method explained can be used to list all installed 32-bit applications as well. I don't really recommend doing it, but Jamf's article doesn't specifically mention NOT to do it.
It's kind of left up to the reader to determine the best course of action and what they feel comfortable with.
So the data isn't really actionable, you cannot run reports on what 32bit apps are installed, only if they exist. Then what? If you don't know what apps, and you cannot report on it, and it is an EA, are you going to hand roll through all device records to find out which apps are 32bit? I typically try to build data I can use and is actionable, and scales to something better than me manually digging through device records.
I know not everyone is afforded their own decision making, but to me dropping a report on an end users Desktop, or installing all the software on a test system and running your own report ended up being the better methods for me to get actionable data. Otherwise, I would have not known all the details of the 32bit apps that were being installed.
@bassic If you don't mind me asking how did you tweak the script to add it to the users Desktop when ran. I think this would be the best solution for us as well. But would like to make sure it puts the file on their desktop. Looking at the script the only thing I can think of is changing the Variable to the correct path but I am not sure.
Hi @JarvisUno
I basically modded rrouton's script so that it creates the list of 32 bit apps, then moves it to the current logged in user's desktop. I then made this available in Self Service. I have to say it has worked pretty well here, but my users are mainly scientists, so are fairly technical. Here is the script I used-
!/bin/bash
Detect all 32-bit apps installed in /Applications, /Library
or /usr/local and output list to logfile stored in /var/log, then move to the logged in user's Desktop.
ThirtyTwoBit_app_logfile="/var/log/32bit_apps_installed.log"
ERROR=0
this script must be run with root privileges
if [[ "$(/usr/bin/id -u)" -eq 0 ]]; then
# Create log file if not present
if [[ -f "$ThirtyTwoBit_app_logfile" ]]; then
echo "$ThirtyTwoBit_app_logfile found. Proceeding..."
else
echo "Creating $ThirtyTwoBit_app_logfile log. Proceeding..."
touch "$ThirtyTwoBit_app_logfile"
fi
# Get a list of all installed applications
ThirtyTwoBit_app_list=$(/usr/sbin/system_profiler SPApplicationsDataType)
if [[ -n "$ThirtyTwoBit_app_list" ]]; then
# get all non-64 Bit applications from the initial list
ThirtyTwoBit_app_list=$(echo "$ThirtyTwoBit_app_list" | /usr/bin/grep -A3 "64-Bit (Intel): No")
# filter out all applications in /Applications, /Library and /usr/local
ThirtyTwoBit_app_list=$(echo "$ThirtyTwoBit_app_list" | /usr/bin/grep -E "Location:[^/]*/(Applications|Library|usr/local)/")
# remove everything except the path
ThirtyTwoBit_app_list=$(echo "$ThirtyTwoBit_app_list" | /usr/bin/sed -n 's/.Location:[[:space:]](.*)/1/p')
if [[ -n "$ThirtyTwoBit_app_list" ]]; then
echo "$ThirtyTwoBit_app_list" > "$ThirtyTwoBit_app_logfile"
echo "List of detected applications available in $ThirtyTwoBit_app_logfile"
else
echo "No 32-bit applications found in /Applications, /Library or /usr/local." > "$ThirtyTwoBit_app_logfile"
fi
get logged in user
loggedInUser=/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }'
move the file to the desktop of logged in user
mv "/var/log/32bit_apps_installed.log" /Users/$loggedInUser/Desktop
exit 0 ## Success
exit 1 ## Failure
fi
else
log "ERROR! You must be root in order to run this script!"
ERROR=1
fi
exit $ERROR
@bassic Ok, I cleaned it up a bit but does this look correct to you?
#!/bin/bash
# Detect all 32-bit apps installed in /Applications, /Library
# or /usr/local and output list to logfile stored in /var/log.
ThirtyTwoBit_app_logfile="/var/log/32bit_apps_installed.log"
ERROR=0
# this script must be run with root privileges
if [[ "$(/usr/bin/id -u)" -eq 0 ]]; then
# Create log file if not present
if [[ -f "$ThirtyTwoBit_app_logfile" ]]; then
echo "$ThirtyTwoBit_app_logfile found. Proceeding..."
else
echo "Creating $ThirtyTwoBit_app_logfile log. Proceeding..."
touch "$ThirtyTwoBit_app_logfile"
fi
# Get a list of all installed applications
ThirtyTwoBit_app_list=$(/usr/sbin/system_profiler SPApplicationsDataType)
if [[ -n "$ThirtyTwoBit_app_list" ]]; then
# get all non-64 Bit applications from the initial list
ThirtyTwoBit_app_list=$(echo "$ThirtyTwoBit_app_list" | /usr/bin/grep -A3 "64-Bit (Intel): No")
# filter out all applications in /Applications, /Library and /usr/local
ThirtyTwoBit_app_list=$(echo "$ThirtyTwoBit_app_list" | /usr/bin/grep -E "Location:[^/]*/(Applications|Library|usr/local)/")
# remove everything except the path
ThirtyTwoBit_app_list=$(echo "$ThirtyTwoBit_app_list" | /usr/bin/sed -n 's/.*Location:[[:space:]]*(.*)/1/p')
if [[ -n "$ThirtyTwoBit_app_list" ]]; then
echo "$ThirtyTwoBit_app_list" > "$ThirtyTwoBit_app_logfile"
echo "List of detected applications available in $ThirtyTwoBit_app_logfile"
else
echo "No 32-bit applications found in /Applications, /Library or /usr/local." > "$ThirtyTwoBit_app_logfile"
fi
# Get logged in user
loggedInUser=/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }'
#move the file to the desktop of logged in user
mv "/var/log/32bit_apps_installed.log" /Users/$loggedInUser/Desktop
exit 0 ## Success
exit 1 ## Failure
fi
else log "ERROR! You must be root in order to run this script!" ERROR=1
fi
exit $ERROR
Instead of putting the log on the desktop, you can upload the .log file as an attachment to your jamf pro server.
#!/bin/sh
curl -sku $JSSUSERNAME:$JSSPW $YourURL/JSSResource/fileuploads/computers/id/$ID -F name=@/var/log/32_bit_apps_installed -X POST
This assumes that your script logic can already identify the computers ID in Jamf, and that your API user creds are passed securely, and that your API User has the create attachments permission.
@sdamiano thanks for that, I like the idea of the end user seeing the apps that will no longer work when they upgrade to Catalina. I just want to make sure the syntax is sound before I start testing it.
@JarvisUno sounds good, and thats admirable. Not everyone has technically savvy users who would understand. You may still want to curl the file back to you/your jamf server just in case of user error or discrepancy.
here is a nice pretty applescript you could use, it will actually display to the end user a list of just the applications, path to application omitted. Looks nice if you need to alert end users upgrading themselves. My end product is very different but this gives you a nice base to work around, pop up message & dialog box with the applications.
#!/usr/bin/osascript
set theuser to do shell script "echo $USER"
do shell script "echo 'Applications You will Need to Update' >> /Users/$USER/Desktop/32bitapps.txt"
do shell script "echo '_____________________________' >> /Users/$USER/Desktop/32bitapps.txt"
do shell script "cat /var/log/32bit_apps_installed.log | sed 's|.*/||' >> /Users/$USER/Desktop/32bitapps.txt"
set appalert to read "/Users/" & theuser & "/Desktop/32bitapps.txt"
display dialog "Application Scan complete. Before upgrading to macOS, please be aware that some applications may not work. The following list, if populated, contains the name of Applications that will need to be updated when you upgrade to macOS Catalina." with title ("Applications Notice") buttons {"Okay"} default button "Okay" with icon alias (POSIX file "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/ApplicationsFolderIcon.icns")
display dialog appalert with title ("Applications Notice") buttons {"Okay"} default button "Okay" with icon alias (POSIX file "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/ApplicationsFolderIcon.icns")
do shell script "rm -rf /Users/$USER/Desktop/32bitapps.txt"
I think listing all the applications in an EA is fine if you aren't running it daily. I set it at once a month and made it available in Self Service for techs.
#!/bin/bash
# Detect all 32-bit apps installed in /Applications, /Library
# or /usr/local and output list to logfile stored in /var/log.
ThirtyTwoBit_app_logfile="/var/log/32bit_apps_installed.log"
ERROR=0
# this script must be run with root privileges
if [[ "$(/usr/bin/id -u)" -eq 0 ]]; then
# Create log file if not present
if [[ -f "$ThirtyTwoBit_app_logfile" ]]; then
echo "$ThirtyTwoBit_app_logfile found. Proceeding..."
else
echo "Creating $ThirtyTwoBit_app_logfile log. Proceeding..."
touch "$ThirtyTwoBit_app_logfile"
fi
# Get a list of all installed applications
ThirtyTwoBit_app_list=$(/usr/sbin/system_profiler SPApplicationsDataType)
if [[ -n "$ThirtyTwoBit_app_list" ]]; then
# Get all non-64 Bit applications from the initial list
ThirtyTwoBit_app_list=$(echo "$ThirtyTwoBit_app_list" | /usr/bin/grep -A3 "64-Bit (Intel): No")
# Filter out all applications in /Applications, /Library and /usr/local
ThirtyTwoBit_app_list=$(echo "$ThirtyTwoBit_app_list" | /usr/bin/grep -E "Location:[^/]*/(Applications|Library|usr/local)/")
# Remove everything except the path
ThirtyTwoBit_app_list=$(echo "$ThirtyTwoBit_app_list" | /usr/bin/sed -n 's/.*Location:[[:space:]]*(.*)/1/p')
if [[ -n "$ThirtyTwoBit_app_list" ]]; then
echo "$ThirtyTwoBit_app_list" > "$ThirtyTwoBit_app_logfile"
echo "List of detected applications available in $ThirtyTwoBit_app_logfile"
else
echo "No 32-bit applications found in /Applications, /Library or /usr/local." > "$ThirtyTwoBit_app_logfile"
fi
# Get logged in user
loggedInUser=/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }'
#move the file to the desktop of logged in user
mv "/var/log/32bit_apps_installed.log" /Users/$loggedInUser/Desktop
exit 0 ## Success
exit 1 ## Failure
fi
else log "ERROR! You must be root in order to run this script!" ERROR=1
fi
exit $ERROR
The following script did not work, created a file called Desktop in the users directory and when opened I see the echo'ed: No 32-bit applications found in /Applications, /Library or /usr/local.
@bassic can you post the script again using the correct forum post formatting?
Hi @JarvisUno is this any better? It works perfectly for me...
#!/bin/bash
# Detect all 32-bit apps installed in /Applications, /Library
# or /usr/local and output list to logfile stored in /var/log.
ThirtyTwoBit_app_logfile="/var/log/32bit_apps_installed.log"
ERROR=0
# this script must be run with root privileges
if [[ "$(/usr/bin/id -u)" -eq 0 ]]; then
# Create log file if not present
if [[ -f "$ThirtyTwoBit_app_logfile" ]]; then
echo "$ThirtyTwoBit_app_logfile found. Proceeding..."
else
echo "Creating $ThirtyTwoBit_app_logfile log. Proceeding..."
touch "$ThirtyTwoBit_app_logfile"
fi
# Get a list of all installed applications
ThirtyTwoBit_app_list=$(/usr/sbin/system_profiler SPApplicationsDataType)
if [[ -n "$ThirtyTwoBit_app_list" ]]; then
# get all non-64 Bit applications from the initial list
ThirtyTwoBit_app_list=$(echo "$ThirtyTwoBit_app_list" | /usr/bin/grep -A3 "64-Bit (Intel): No")
# filter out all applications in /Applications, /Library and /usr/local
ThirtyTwoBit_app_list=$(echo "$ThirtyTwoBit_app_list" | /usr/bin/grep -E "Location:[^/]*/(Applications|Library|usr/local)/")
# remove everything except the path
ThirtyTwoBit_app_list=$(echo "$ThirtyTwoBit_app_list" | /usr/bin/sed -n 's/.*Location:[[:space:]]*(.*)/1/p')
if [[ -n "$ThirtyTwoBit_app_list" ]]; then
echo "$ThirtyTwoBit_app_list" > "$ThirtyTwoBit_app_logfile"
echo "List of detected applications available in $ThirtyTwoBit_app_logfile"
else
echo "No 32-bit applications found in /Applications, /Library or /usr/local." > "$ThirtyTwoBit_app_logfile"
fi
# get logged in user
loggedInUser=`/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }'`
# move the file to the desktop of logged in user
mv "/var/log/32bit_apps_installed.log" /Users/$loggedInUser/Desktop
exit 0 ## Success
exit 1 ## Failure
fi
else
log "ERROR! You must be root in order to run this script!"
ERROR=1
fi
exit $ERROR
@bassic Thank you very much I found my syntax error.
/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }'
Is where I went wrong. I forgot to add the back quote to the variable. I only noticed it after I had made the initial post. And after proof reading the code noticed that, that the -l switch was not acting as an option.
When I added the back quote the issue resolved.
`/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }'`
@Hugonaut
Just tried your script and deployed it with Jamf - but if fails
#!/bin/sh
Script result: /Library/Application Support/JAMF/tmp/32bit appls listed 31 jan:46:145: execution error: sh: /Users/root/Desktop/32bitapps.txt: No such file or directory (1)
I don´t have any root user and it cannot find this directory. Think the issue is that the script should be run in the logged in user mode?. Jamf run it as sudo so that is where the root account come from
I ran this script and added it to Self Service. This way if a teacher plans to update they can see if they are running any apps which won't work in Catalina. They are in control of running it and if they have questions about the report they contact tech. This is working out well.
!/bin/bash
Detect all 32-bit apps installed in /Applications, /Library
or /usr/local and output list to logfile stored in /var/log.
ThirtyTwoBit_app_logfile="/var/log/32bit_apps_installed.log"
ERROR=0
this script must be run with root privileges
if [[ "$(/usr/bin/id -u)" -eq 0 ]]; then
# Create log file if not present
if [[ -f "$ThirtyTwoBit_app_logfile" ]]; then
echo "$ThirtyTwoBit_app_logfile found. Proceeding..."
else
echo "Creating $ThirtyTwoBit_app_logfile log. Proceeding..."
touch "$ThirtyTwoBit_app_logfile"
fi
# Get a list of all installed applications
ThirtyTwoBit_app_list=$(/usr/sbin/system_profiler SPApplicationsDataType)
if [[ -n "$ThirtyTwoBit_app_list" ]]; then
# get all non-64 Bit applications from the initial list
ThirtyTwoBit_app_list=$(echo "$ThirtyTwoBit_app_list" | /usr/bin/grep -A3 "64-Bit (Intel): No")
# filter out all applications in /Applications, /Library and /usr/local
ThirtyTwoBit_app_list=$(echo "$ThirtyTwoBit_app_list" | /usr/bin/grep -E "Location:[^/]*/(Applications|Library|usr/local)/")
# remove everything except the path
ThirtyTwoBit_app_list=$(echo "$ThirtyTwoBit_app_list" | /usr/bin/sed -n 's/.Location:[[:space:]](.*)/1/p')
if [[ -n "$ThirtyTwoBit_app_list" ]]; then
echo "$ThirtyTwoBit_app_list" > "$ThirtyTwoBit_app_logfile"
echo "List of detected applications available in $ThirtyTwoBit_app_logfile"
else
echo "No 32-bit applications found in /Applications, /Library or /usr/local." > "$ThirtyTwoBit_app_logfile"
fi
get logged in user
loggedInUser=/bin/ls -l /dev/console | /usr/bin/awk '{ print $3 }'
move the file to the desktop of logged in user
mv "/var/log/32bit_apps_installed.log" /Users/$loggedInUser/Desktop
exit 0 ## Success
exit 1 ## Failure
fi
else
log "ERROR! You must be root in order to run this script!"
ERROR=1
fi
exit $ERROR
So Cannot work as policy but only Self service ?
No, it is a policy but I place it in Self service, because I don't need every teacher getting reports on their desktop because the questions would be incessant. The self-service policy gives the tech or the teacher the information they require, when they require it.
@bassic
I tried your script and if I run it manual through command line as sudo it works.
But when adding it as script, it just everytime write failed - without any kind of info in the log ?
Do you run it through Jamf ?
Hi @jameson
Yes I run the script via a Self-Service policy. How are you deploying it?
I've used Go64 (https://www.stclairsoft.com/Go64/index.html) which works well on an individual basis (I've already checked and updated most of our apps first which covers 95% of the app out users have installed).
I was tired of seing all bunch of nonsense listed in the EA, typical some adobe/microsoft that is rapported as 32bit, but will be no issue after upgrade.
So to clean up, i´ve used sed to delete those application I do not want to see ( or users should think off)
#!/bin/bash
cat /var/log/32bit_apps_installed.log | sed -e '/Adobe/d' -e '/LWMacClient/d' -e '/Remote/d' -e '/TeamViewer/d' -e '/Microsoft/d' -e '/Google/d' > /var/log/32bit_apps_installed_edited.log