v0.3 = Completed all desired logic and tidied up code

+ Added check to see if the app exists in the iTunes API
 + Cleaned up code
 + Finished supporting logic
This commit is contained in:
Zack T
2018-06-14 21:24:40 -07:00
parent 6a33d59881
commit c9de090fee

View File

@@ -3,9 +3,9 @@
###################################################################################################
# Script Name: jamf_verifyVPPApps.sh
# By: Zack Thompson / Created: 6/13/2018
# Version: 0.2 / Updated: 6/13/2018 / By: ZT
# Version: 0.3 / Updated: 6/14/2018 / By: ZT
#
# Description: This script is used to scope groups to VPP Apps.
# Description: Gets details on all of the VPP Apps from the JSS and checks iTunes to see if they are 32bit and exports results to a csv file
#
###################################################################################################
@@ -43,123 +43,105 @@ echo "***** verifyVPPApps process: START *****"
getHelp() {
echo "
usage: jamf_verifyVPPApps.sh [-get | -assign] [/path/to/file.txt] [-help]
usage: jamf_verifyVPPApps.sh [-run | -r] [/path/to/file.csv] [-help]
Info: Get a list of VPP Apps or assign VPP Apps to groups.
Info: Gets details on all of the VPP Apps from the JSS and checks iTunes to see if they are 32bit and exports results to a csv file.
Actions:
-get Gets all the VPP Apps from the JSS and exports them to a txt file.
Example: jamf_verifyVPPApps.sh -get output.txt
-assign Read the provide file and assigns (scopes) VPP Apps to a Group.
Example: jamf_verifyVPPApps.sh -assign input.txt
-run | -r Run the report and output to a csv file.
Example: jamf_verifyVPPApps.sh -run output.csv
-help Displays this help section.
Example: jamf_verifyVPPApps.sh -help
"
}
# Build a list of Mobile Device Apps from the JSS.
getAppInfo() {
echo "Requesting list of all App IDs..."
# GET list of App IDs from the JSS.
curlReturn="$(/usr/bin/curl "${curlJamfAPI[@]}" GET $mobileApps)"
# Check if the API call was successful or not.
curlCode=$(echo "${curlReturn}" | awk -F statusCode: '{print $2}')
if [[ $curlCode != "200" ]]; then
informBy "ERROR: API call failed with error: ${curlCode}!"
echo "***** verifyVPPApps process: FAILED *****"
exit 4
fi
curlCode=$(echo "${curlReturn}" | /usr/bin/awk -F statusCode: '{print $2}' | /usr/bin/xargs )
# Regex down to just the ID numbers
appIDs=$(echo "${curlReturn}" | sed -e 's/statusCode\:.*//g' | xmllint --format - | xpath /mobile_device_applications/mobile_device_application/id 2>/dev/null | LANG=C sed -e 's/<[^/>]*>//g' | LANG=C sed -e 's/<[^>]*>/\'$'\n/g')
appIDs=$(echo "${curlReturn}" | /usr/bin/sed -e 's/statusCode\:.*//g' | /usr/bin/xmllint --format - | /usr/bin/xpath /mobile_device_applications/mobile_device_application/id 2>/dev/null | LANG=C /usr/bin/sed -e 's/<[^/>]*>//g' | LANG=C /usr/bin/sed -e 's/<[^>]*>/\'$'\n/g')
informBy "Getting info for each App from the JSS..."
# For Each ID, get additional information.
for appID in $appIDs; do
# Get each info for each AppID
curlReturn="$(/usr/bin/curl "${curlJamfAPI[@]}" GET ${mobileAppsByID}/${appID}/subset/General)"
# Check if the API call was successful or not.
curlCode=$(echo "${curlReturn}" | awk -F statusCode: '{print $2}')
curlCode=$(echo "${curlReturn}" | /usr/bin/awk -F statusCode: '{print $2}' | /usr/bin/xargs )
checkStatusCode $curlCode $appID
# Regex down to the info we want and output to a tab delimited file
appInfo="$(printf "${curlReturn}" | sed -e 's/statusCode\:.*//g' | xmllint --format - | xpath '/mobile_device_application/general/id | /mobile_device_application/general/name | /mobile_device_application/general/site/name | /mobile_device_application/general/bundle_id | /mobile_device_application/general/itunes_store_url' 2>/dev/null | LANG=C sed -e 's/<[^/>]*>//g' | LANG=C sed -e 's/<[^>]*>/\'$'\t/g' | LANG=C sed -e 's/\'$'\t[^\t]*$//')" #>> "${outFile}"
# Regex down to the info we want.
appInfo="$(echo "${curlReturn}" | /usr/bin/sed -e 's/statusCode\:.*//g' | /usr/bin/xmllint --format - | /usr/bin/xpath '/mobile_device_application/general/id | /mobile_device_application/general/name | /mobile_device_application/general/site/name | /mobile_device_application/general/bundle_id | /mobile_device_application/general/itunes_store_url' 2>/dev/null | LANG=C /usr/bin/sed -e 's/<[^/>]*>//g' | LANG=C /usr/bin/sed -e 's/<[^>]*>/\'$'\t/g' | LANG=C /usr/bin/sed -e 's/\'$'\t[^\t]*$//')"
# Read in the App Info and assign to variables
while IFS=$'\t' read appID appName bundle_id itunes_store_url appSite; do
# Read in the file and assign to variables
while IFS=$'\t' read appID appName bundle_id itunes_store_url appSite; do
# Get the Adam ID which is needed for the iTunes API
appAdamID=$(echo "${itunes_store_url}" | /usr/bin/sed -e 's/.*\/id\(.*\)?.*/\1/')
# Get App info from iTunes
iTunesCurlReturn="$(/usr/bin/curl "${curliTunesAPI[@]}" GET ${iTunesAPI}${appAdamID})"
#printf "${#appInfo[@]}"
# Check if the API call was successful or not.
curlCode=$(echo "${iTunesCurlReturn}" | /usr/bin/awk -F statusCode: '{print $2}' | /usr/bin/xargs )
checkStatusCode $curlCode $appID "iTunes" $appAdamID
printf '%s\n' "itunes_store_url: ${itunes_store_url}"
appAdamID=$(printf "${itunes_store_url}" | sed -e 's/.*\/id\(.*\)?.*/\1/')
printf '%s\n' "AdamID: ${appAdamID}"
#
#echo "${iTunesAPI}/${appAdamID}"
iTunesCurlReturn="$(/usr/bin/curl "${curliTunesAPI[@]}" GET ${iTunesAPI}${appAdamID})"
# echo "AppID: ${appID} AdamID: ${appAdamID}"
# Check if the App still exists on iTunes
appExists=$(echo "${iTunesCurlReturn}" | /usr/bin/sed -e 's/statusCode\:.*//g' | /usr/bin/python -c "
import sys, json
# Check if the API call was successful or not.
curlCode=$(printf "${iTunesCurlReturn}" | awk -F statusCode: '{print $2}')
checkStatusCode $curlCode $appID
objects = json.load(sys.stdin)
printf '%s\t' "${appInfo}"
#32bitness=$(
printf "${iTunesCurlReturn}" | sed -e 's/statusCode\:.*//g' | python -mjson.tool | awk -F "is32bitOnly\": " '{print $2}' | xargs | sed 's/,//' #)
if not objects.get('results'):
print('No')
else:
print('Yes')")
unset appInfo
# echo "App Exists: ${appExists}"
# echo "Adding header to output file..."
# header="App ID\tApp Name\tBundle ID\tiTunes Store URL\tJamf Site\t\t32Bit"
# echo -e $header >> "${outFile}"
# Extract if the App is 32bit Only
bitness32=$(echo "${iTunesCurlReturn}" | /usr/bin/sed -e 's/statusCode\:.*//g' | /usr/bin/python -mjson.tool | /usr/bin/awk -F "is32bitOnly\": " '{print $2}' | /usr/bin/xargs | /usr/bin/sed 's/,//')
# Output to File
echo -e "${appInfo}\t${appExists}\t${bitness32}" >> "${outFile}"
done < <(printf '%s\n' "${appInfo}")
# Clear variable for next loop item
unset appInfo
done < <(/usr/bin/printf '%s\n' "${appInfo}")
done
# informBy "List has been saved to: ${outFile}"
informBy "List has been saved to: ${outFile}"
}
checkStatusCode() {
case $1 in
200 )
# Turn off success notifications
# informBy " -> Request successful"
;;
201)
# Turn off success notifications
# informBy "App ID: ${appID} -> Request to create or update object successful"
;;
400)
informBy "App ID: ${appID} -> Bad request. Verify the syntax of the request specifically the XML body."
;;
401)
informBy "App ID: ${appID} -> Authentication failed. Verify the credentials being used for the request."
;;
403)
informBy "App ID: ${appID} -> Invalid permissions. Verify the account being used has the proper permissions for the object/resource you are trying to access."
;;
404)
informBy "App ID: ${appID} -> Object/resource not found. Verify the URL path is correct."
;;
409)
informBy "App ID: ${appID} -> Conflict"
;;
500)
informBy "App ID: ${appID} -> Internal server error. Retry the request or contact Jamf support if the error is persistent."
;;
esac
if [[ $1 != "200" ]]; then
informBy "ERROR: API call failed for ${2} with error: ${1}!"
if [[ $3 == "iTunes" ]]; then
informBy "AdamID is: ${4}"
fi
fi
}
fileExists() {
if [[ ! -e "${1}" && $2 == "create" ]]; then
echo "Creating output file at location: ${1}"
/usr/bin/touch "${1}"
echo "Adding header to output file..."
header="App ID\tApp Name\tBundle ID\tiTunes Store URL\tJamf Site\tAvailable\t32Bit"
echo -e $header >> "${outFile}"
elif [[ ! -e "${1}" && $2 == "trip" ]]; then
informBy "ERROR: Unable to find the input file!"
echo "***** verifyVPPApps process: FAILED *****"
@@ -191,7 +173,7 @@ else
curlReturn="$(/usr/bin/curl $jamfPS/JSSResource/jssuser -i --silent --show-error --fail --user "${jamfAPIUser}:${jamfAPIPassword}" --write-out "statusCode:%{http_code}")"
# Check if the API call was successful or not.
curlCode=$(echo "$curlReturn" | awk -F statusCode: '{print $2}')
curlCode=$(echo "$curlReturn" | /usr/bin/awk -F statusCode: '{print $2}')
if [[ $curlCode != *"200"* ]]; then
informBy "ERROR: Invalid API credentials provided!"
echo "***** verifyVPPApps process: FAILED *****"
@@ -201,42 +183,28 @@ else
echo "API Credentials Valid -- continuing..."
fi
getAppInfo
# case $action in
# --get | -g | "Get VPP Apps" )
# if [[ -n "${switch1}" ]]; then
# outFile="${switch1}"
# # Function getApps
# getApps
# else
# outFile=$(/usr/bin/osascript -e 'tell application (path to frontmost application as text)' -e 'return POSIX path of (choose file name with prompt "Provide a file name and location to save the configuration file:")' -e 'end tell' 2>/dev/null)
# # Function fileExists
# fileExists "${outFile}" create
# # Function getApps
# getApps
# fi
# ;;
# --assign | -a | "Assign VPP Apps" )
# if [[ -n "${switch1}" ]]; then
# inputFile="${switch1}"
# # Function fileExists
# fileExists "${inputFile}" trip
# # Function assignApps
# assignApps
# else
# inputFile=$(/usr/bin/osascript -e 'tell application (path to frontmost application as text)' -e 'return POSIX path of(choose file with prompt "Select configuration file to process:" of type {"txt"})' -e 'end tell' 2>/dev/null)
# # Function fileExists
# fileExists "${inputFile}" trip
# # Function assignApps
# assignApps
# fi
# ;;
# -help | -h | * )
# # Function getHelp
# getHelp
# ;;
# esac
# Perform the request action.
case $action in
--run | -r )
if [[ -n "${switch1}" ]]; then
outFile="${switch1}"
# Function fileExists
fileExists "${outFile}" create
# Function getAppInfo
getAppInfo
else
outFile=$(/usr/bin/osascript -e 'tell application (path to frontmost application as text)' -e 'return POSIX path of (choose file name with prompt "Provide a file name and location to save the configuration file:")' -e 'end tell' 2>/dev/null)
# Function fileExists
fileExists "${outFile}" create
# Function getAppInfo
getAppInfo
fi
;;
-help | -h | * )
# Function getHelp
getHelp
;;
esac
informBy "Script successfully completed!"
echo "***** verifyVPPApps process: COMPLETE *****"