Tuesday
Hi All
Hoping someone can help.
Have found a script for collecting log files using jamf pro API thanks @Travid @david_maestre for updating the script to work with Jamf pro API I belive its based on this https://github.com/kc9wwh/logCollection which no longer seems to work. I belive due to changes in the API.
Im getting the below errror is there anyway to make it work without needing Xcode, seems to be using some tools which are part of Xcode. My coding skills arent up to much so struggling to find whats bits of Xcode its using as dont appear to be reference in the script.
no developer tools were found at '/Applications/Xcode.app', and no install could be requested (perhaps no UI is present), please install manually from 'developer.apple.com'. Failed to retrieve Jamf Pro Computer ID.
#!/bin/bash
## User Variables
jamfProURL="$4"
jamfProUser="$5"
jamfProPass="$6"
logFiles="$7"
## System Variables
mySerial=$(system_profiler SPHardwareDataType | awk '/Serial Number/{print $4}')
currentUser=$(stat -f%Su /dev/console)
compHostName=$(scutil --get LocalHostName)
timeStamp=$(date '+%Y-%m-%d-%H-%M-%S')
## Debugging Outputs (Optional)
echo "Jamf Pro URL: $jamfProURL"
echo "Jamf Pro User: $jamfProUser"
# Do not echo the password for security
echo "Log Files: $logFiles"
echo "Serial Number: $mySerial"
echo "Current User: $currentUser"
echo "Computer Hostname: $compHostName"
## Log Collection
fileName="$compHostName-$currentUser-$timeStamp.zip"
echo "Creating zip file: /private/tmp/$fileName"
zip -r /private/tmp/"$fileName" $logFiles
## Obtain API Auth Token
authResponse=$(curl -sku "$jamfProUser:$jamfProPass" -X POST "$jamfProURL/api/v1/auth/token")
apiAuthToken=$(echo "$authResponse" | plutil -extract token raw -)
tokenExpiration=$(echo "$authResponse" | plutil -extract expires raw -)
if [ -z "$apiAuthToken" ]; then
echo "Failed to obtain API authentication token."
echo "Response: $authResponse"
exit 1
fi
echo "API Authentication Token obtained. Token expires: $tokenExpiration"
## Corrected Filter Field for Serial Number
encodedSerial=$(printf '%s' "$mySerial" | python3 -c 'import sys, urllib.parse; print(urllib.parse.quote(sys.stdin.read().strip()))')
filterQuery="hardware.serialNumber%3D%3D$encodedSerial"
## Get Jamf Pro Computer ID using the Jamf Pro API
computerIDResponse=$(curl -sk --header "Authorization: Bearer $apiAuthToken" "$jamfProURL/api/v1/computers-inventory?filter=$filterQuery")
jamfProID=$(echo "$computerIDResponse" | python3 -c "
import sys, json
data = json.load(sys.stdin)
if data['totalCount'] > 0:
print(data['results'][0]['id'])
else:
sys.exit(1)
" 2>/dev/null)
if [ -z "$jamfProID" ]; then
echo "Failed to retrieve Jamf Pro Computer ID."
echo "Response: $computerIDResponse"
exit 1
fi
echo "Jamf Pro Computer ID: $jamfProID"
## Upload Log File
uploadResponse=$(curl -sk --header "Authorization: Bearer $apiAuthToken" -X POST "$jamfProURL/api/v1/computers-inventory/$jamfProID/attachments" -F file=@/private/tmp/$fileName)
echo "Upload Response: $uploadResponse"
## Check for successful upload
if [[ "$uploadResponse" == *"id"* ]]; then
echo "Log file uploaded successfully."
else
echo "Failed to upload log file."
exit 1
fi
## Invalidate API Auth Token
curl -sk --header "Authorization: Bearer $apiAuthToken" "$jamfProURL/api/v1/auth/invalidate-token" -X POST
## Cleanup
rm /private/tmp/"$fileName"
exit 0
Thanks
Solved! Go to Solution.
Tuesday - last edited Tuesday
@tdenton Where did the python call in that script come from? It is not part of the https://github.com/kc9wwh/logCollection script and isn't necessary to get a Mac's serial number.
And here's an updated version of the log collections script that uses Bearer Token auth since Basic Auth is no longer supported for the API:
#!/bin/bash
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# Copyright (c) 2020 Jamf. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the Jamf nor the names of its contributors may be
# used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY JAMF SOFTWARE, LLC "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL JAMF SOFTWARE, LLC BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# This script was designed to be used in a Self Service policy to allow the facilitation
# or log collection by the end-user and upload the logs to the device record in Jamf Pro
# as an attachment.
#
# REQUIREMENTS:
# - Jamf Pro
# - macOS Clients running version 10.13 or later
#
#
# For more information, visit https://github.com/kc9wwh/logCollection
#
# Written by: Joshua Roskos | Jamf
# Revised by: Alton Brailovskiy | Martin Cox (Jamf)
#
# Revision History
# 2024-07-23: Updated Script - https://github.com/kc9wwh/logCollection/blob/master/BearerAuth.sh
# 2023-11-30: Added support for bearer auth and invalidating bearer token once done.
# 2020-12-01: Added support for macOS Big Sur
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
## User Variables
## Ensure not to include the / at the end of the JamfProURL parameter. ex https://instance.jamfcloud.com is the parameter NOT https://instance.jamfcloud.com/
## Suggested Logs to pull: /private/var/log/install.log* /private/var/log/jamf.log* /private/var/log/system.log*
jamfProURL="$4"
jamfProUser="$5"
jamfProPass="$6"
logFiles="$7"
bearerTokenResponse=$(curl -s -u "$jamfProUser":"$jamfProPass" "$jamfProURL/api/v1/auth/token" -X POST)
if [[ $? -eq 0 ]]; then
bearerToken=$(echo "$bearerTokenResponse" | plutil -extract token raw -)
echo "Bearer token: $bearerToken"
else
echo "Authentication failed. Check credentials or endpoint."
fi
## System Variables
mySerial=$(system_profiler SPHardwareDataType | grep 'Serial Number' | awk '{print $NF}')
currentUser=$( stat -f%Su /dev/console )
compHostName=$( scutil --get LocalHostName )
timeStamp=$( date '+%Y-%m-%d-%H-%M-%S' )
osMajor=$(/usr/bin/sw_vers -productVersion | awk -F . '{print $1}')
osMinor=$(/usr/bin/sw_vers -productVersion | awk -F . '{print $2}')
## Log Collection
fileName=$compHostName-$currentUser-$timeStamp.zip
zip /private/tmp/$fileName $logFiles
## Upload Log File
if [[ "$osMajor" -ge 11 ]]; then
jamfProID=$( curl -k -H "Authorization: Bearer ${bearerToken}" $jamfProURL/JSSResource/computers/serialnumber/$mySerial/subset/general | xpath -e "//computer/general/id/text()" )
elif [[ "$osMajor" -eq 10 && "$osMinor" -gt 12 ]]; then
jamfProID=$( curl -k -H "Authorization: Bearer ${bearerToken}" $jamfProURL/JSSResource/computers/serialnumber/$mySerial/subset/general | xpath "//computer/general/id/text()" )
fi
curl -k -H "Authorization: Bearer ${bearerToken}" $jamfProURL/JSSResource/fileuploads/computers/id/$jamfProID -F name=@/private/tmp/$fileName -X POST
## Cleanup
rm /private/tmp/$fileName
# Invalidate the bearer token after file upload
invalidateResponse=$(curl -s -u "$jamfProUser":"$jamfProPass" "$jamfProURL/api/v1/auth/invalidateToken" -X POST -H "Authorization: Bearer $bearerToken")
if [[ $? -eq 0 ]]; then
echo "Bearer token invalidated successfully."
else
echo "Failed to invalidate bearer token. Response: $invalidateResponse"
fi
exit 0
Tuesday
if you wanted to run this device on the end user's machine, Python was removed from macOS long ago, I don't think it will execute. it gives an error as command line tools are not installed, you can install the same using the command "xcode-select --install"
Tuesday
Thanks @Shyamsundar just testing with deploying xcode via vpp apps.
Did try xcode-select --install but prompts the users not sure if there away to install in silently
Tuesday - last edited Tuesday
@tdenton Where did the python call in that script come from? It is not part of the https://github.com/kc9wwh/logCollection script and isn't necessary to get a Mac's serial number.
And here's an updated version of the log collections script that uses Bearer Token auth since Basic Auth is no longer supported for the API:
#!/bin/bash
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# Copyright (c) 2020 Jamf. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the Jamf nor the names of its contributors may be
# used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY JAMF SOFTWARE, LLC "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL JAMF SOFTWARE, LLC BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# This script was designed to be used in a Self Service policy to allow the facilitation
# or log collection by the end-user and upload the logs to the device record in Jamf Pro
# as an attachment.
#
# REQUIREMENTS:
# - Jamf Pro
# - macOS Clients running version 10.13 or later
#
#
# For more information, visit https://github.com/kc9wwh/logCollection
#
# Written by: Joshua Roskos | Jamf
# Revised by: Alton Brailovskiy | Martin Cox (Jamf)
#
# Revision History
# 2024-07-23: Updated Script - https://github.com/kc9wwh/logCollection/blob/master/BearerAuth.sh
# 2023-11-30: Added support for bearer auth and invalidating bearer token once done.
# 2020-12-01: Added support for macOS Big Sur
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
## User Variables
## Ensure not to include the / at the end of the JamfProURL parameter. ex https://instance.jamfcloud.com is the parameter NOT https://instance.jamfcloud.com/
## Suggested Logs to pull: /private/var/log/install.log* /private/var/log/jamf.log* /private/var/log/system.log*
jamfProURL="$4"
jamfProUser="$5"
jamfProPass="$6"
logFiles="$7"
bearerTokenResponse=$(curl -s -u "$jamfProUser":"$jamfProPass" "$jamfProURL/api/v1/auth/token" -X POST)
if [[ $? -eq 0 ]]; then
bearerToken=$(echo "$bearerTokenResponse" | plutil -extract token raw -)
echo "Bearer token: $bearerToken"
else
echo "Authentication failed. Check credentials or endpoint."
fi
## System Variables
mySerial=$(system_profiler SPHardwareDataType | grep 'Serial Number' | awk '{print $NF}')
currentUser=$( stat -f%Su /dev/console )
compHostName=$( scutil --get LocalHostName )
timeStamp=$( date '+%Y-%m-%d-%H-%M-%S' )
osMajor=$(/usr/bin/sw_vers -productVersion | awk -F . '{print $1}')
osMinor=$(/usr/bin/sw_vers -productVersion | awk -F . '{print $2}')
## Log Collection
fileName=$compHostName-$currentUser-$timeStamp.zip
zip /private/tmp/$fileName $logFiles
## Upload Log File
if [[ "$osMajor" -ge 11 ]]; then
jamfProID=$( curl -k -H "Authorization: Bearer ${bearerToken}" $jamfProURL/JSSResource/computers/serialnumber/$mySerial/subset/general | xpath -e "//computer/general/id/text()" )
elif [[ "$osMajor" -eq 10 && "$osMinor" -gt 12 ]]; then
jamfProID=$( curl -k -H "Authorization: Bearer ${bearerToken}" $jamfProURL/JSSResource/computers/serialnumber/$mySerial/subset/general | xpath "//computer/general/id/text()" )
fi
curl -k -H "Authorization: Bearer ${bearerToken}" $jamfProURL/JSSResource/fileuploads/computers/id/$jamfProID -F name=@/private/tmp/$fileName -X POST
## Cleanup
rm /private/tmp/$fileName
# Invalidate the bearer token after file upload
invalidateResponse=$(curl -s -u "$jamfProUser":"$jamfProPass" "$jamfProURL/api/v1/auth/invalidateToken" -X POST -H "Authorization: Bearer $bearerToken")
if [[ $? -eq 0 ]]; then
echo "Bearer token invalidated successfully."
else
echo "Failed to invalidate bearer token. Response: $invalidateResponse"
fi
exit 0
Wednesday
@sdagley didnt spot that, thanks so much this is working perfectley.
Thanks also for posting your version @david_maestre
Tuesday
The above looks accurate./
I'll attach mine just incase -- currently working just fine.
Thanks
#!/bin/bash
## User Variables
jamfProURL="$4"
jamfProUser="$5"
jamfProPass="$6"
logFiles="$7"
## System Variables
mySerial=$(system_profiler SPHardwareDataType | awk '/Serial Number/{print $4}')
currentUser=$(stat -f%Su /dev/console)
compHostName=$(scutil --get LocalHostName)
timeStamp=$(date '+%Y-%m-%d-%H-%M-%S')
## Debugging Outputs (Optional)
echo "Jamf Pro URL: $jamfProURL"
echo "Jamf Pro User: $jamfProUser"
# Do not echo the password for security
echo "Log Files: $logFiles"
echo "Serial Number: $mySerial"
echo "Current User: $currentUser"
echo "Computer Hostname: $compHostName"
## Log Collection
fileName="$compHostName-$currentUser-$timeStamp.zip"
echo "Creating zip file: /private/tmp/$fileName"
zip -r /private/tmp/"$fileName" $logFiles
## Obtain API Auth Token
authResponse=$(curl -sku "$jamfProUser:$jamfProPass" -X POST "$jamfProURL/api/v1/auth/token")
apiAuthToken=$(echo "$authResponse" | plutil -extract token raw -)
tokenExpiration=$(echo "$authResponse" | plutil -extract expires raw -)
if [ -z "$apiAuthToken" ]; then
echo "Failed to obtain API authentication token."
echo "Response: $authResponse"
exit 1
fi
echo "API Authentication Token obtained. Token expires: $tokenExpiration"
## Corrected Filter Field for Serial Number
encodedSerial=$(printf '%s' "$mySerial" | python3 -c 'import sys, urllib.parse; print(urllib.parse.quote(sys.stdin.read().strip()))')
filterQuery="hardware.serialNumber%3D%3D$encodedSerial"
## Get Jamf Pro Computer ID using the Jamf Pro API
computerIDResponse=$(curl -sk --header "Authorization: Bearer $apiAuthToken" "$jamfProURL/api/v1/computers-inventory?filter=$filterQuery")
jamfProID=$(echo "$computerIDResponse" | python3 -c "
import sys, json
data = json.load(sys.stdin)
if data['totalCount'] > 0:
print(data['results'][0]['id'])
else:
sys.exit(1)
" 2>/dev/null)
if [ -z "$jamfProID" ]; then
echo "Failed to retrieve Jamf Pro Computer ID."
echo "Response: $computerIDResponse"
exit 1
fi
echo "Jamf Pro Computer ID: $jamfProID"
## Upload Log File
uploadResponse=$(curl -sk --header "Authorization: Bearer $apiAuthToken" -X POST "$jamfProURL/api/v1/computers-inventory/$jamfProID/attachments" -F file=@/private/tmp/$fileName)
echo "Upload Response: $uploadResponse"
## Check for successful upload
if [[ "$uploadResponse" == *"id"* ]]; then
echo "Log file uploaded successfully."
else
echo "Failed to upload log file."
exit 1
fi
## Invalidate API Auth Token
curl -sk --header "Authorization: Bearer $apiAuthToken" "$jamfProURL/api/v1/auth/invalidate-token" -X POST
## Cleanup
rm /private/tmp/"$fileName"
exit 0