I'm wondering if there is a way to bring up a GUI (jamfhelper, cocoadialog, etc) to give a device an already created EA. As mentioned, the EA is created, I just need a way for a technician who is setting up the computer to assign it to the right EA so that it drops into scope for some policies to run based on the EA. The EA I created has the following characteristics: Data Type: String, Input Type: Pop-Up Menu . I then have a few items in the dropdown to choose. I'm hoping to be able to assign one of those dropdown items directly from the computer.
You need to be careful about passing credentials into scripts as it's not a safe practice
So I have a suggestion that might work and something we use here during the build process. When the ADE process starts it brings up DepNotify and asks the user for certain information (computer name, user assigned to, location, and persona). What I did was I had the script default write those values to a plist file.
So you can create a GUI to get the data and send it to the plist file. Then you can use a EA that uses a script to read the information from the plist file.
But I do think that giving techs access do to do it themselves might be faster.
Does anyone have this same script or something similar which is using basic authentication changed over to token authentication?
For starters I have, the following ground work to get the token but I'm not sure how to use the token to authenticate to the API so I can run scripts similar to the ones shared on this thread.
#!/bin/bash
username="username_here"
password="password_here"
URL="https://someplace.jamfcloud.com"
# created base64-encoded credentials
encodedCredentials=$( printf "$username:$password" | /usr/bin/iconv -t ISO-8859-1 | /usr/bin/base64 -i - )
# echo encodedCredentials: "$encodedCredentials"
# generate an auth token
authToken=$( /usr/bin/curl "$URL/api/v1/auth/token" \\
--silent \\
--request POST \\
--header "Authorization: Basic $encodedCredentials" )
# echo authToken: "$authToken"
# parse authToken for token, omit expiration
if [[ $(/usr/bin/sw_vers -productVersion | awk -F . '{print $1}') -lt 12 ]]; then
token=$(/usr/bin/awk -F \\" 'NR==2{print $4}' <<< "$authToken" | /usr/bin/xargs)
else
token=$(/usr/bin/plutil -extract token raw -o - - <<< "$authToken")
fi
Does anyone have this same script or something similar which is using basic authentication changed over to token authentication?
For starters I have, the following ground work to get the token but I'm not sure how to use the token to authenticate to the API so I can run scripts similar to the ones shared on this thread.
#!/bin/bash
username="username_here"
password="password_here"
URL="https://someplace.jamfcloud.com"
# created base64-encoded credentials
encodedCredentials=$( printf "$username:$password" | /usr/bin/iconv -t ISO-8859-1 | /usr/bin/base64 -i - )
# echo encodedCredentials: "$encodedCredentials"
# generate an auth token
authToken=$( /usr/bin/curl "$URL/api/v1/auth/token" \\
--silent \\
--request POST \\
--header "Authorization: Basic $encodedCredentials" )
# echo authToken: "$authToken"
# parse authToken for token, omit expiration
if [[ $(/usr/bin/sw_vers -productVersion | awk -F . '{print $1}') -lt 12 ]]; then
token=$(/usr/bin/awk -F \\" 'NR==2{print $4}' <<< "$authToken" | /usr/bin/xargs)
else
token=$(/usr/bin/plutil -extract token raw -o - - <<< "$authToken")
fi
This is a template I work from, it might need some tweaking at the command part on the bottom, but the token stuff should work.
#!/bin/sh
# Set some variables
username=$4
password=$5
jssURL="https://company.jamfcloud.com"
# Get the token
authBasic=$(echo '$username:$password\\c' | base64) # "\\c" is required to get the right format
authToken=$(curl -sk "$jssURL/api/v1/auth/token" -H "Accept: application/json" -H "Authorization: Basic $authBasic" -X POST --connect-timeout 10)
curlRes=$?
# Check the token result
if [[ $curlRes -gt 0 ]]
then
echo "CURL return code: $curlRes"
exit 1
fi
# We got a token, lets parse the data for the token itself
read -r -d '' JXA <<EOF
function run() {
var tokenInfo = JSON.parse(\\`$authToken\\`);
return tokenInfo.token;
}
EOF
OAuthToken=$( osascript -l 'JavaScript' <<< "${JXA}" )
read -r -d '' JXA <<EOF
function run() {
var tokenInfo = JSON.parse(\\`$authToken\\`);
return tokenInfo.expires;
}
EOF
# Set a variable with the expiration if your script will be running a while and you need to refer back
OAuthExpires=$( osascript -l 'JavaScript' <<< "${JXA}" )
# Run a Classic API call with bearer token auth
serialNum=$(ioreg -l | grep IOPlatformSerialNumber | awk '{print $4}' | cut -d "\\"" -f 2)
cloudCompID=$(curl -sk "$jssURL/JSSResource/computers/serialnumber/$serialNum" -H "Content-Type: application/xml" -H "Accept: application/xml" -H "Authorization: Bearer $OAuthToken" -X GET --connect-timeout 10 | xmllint --xpath "/computer/general/id/text()" - )
echo "Current machine computer ID: $cloudCompID"
# Run an Jamf Pro API call with bearer token auth
computersJSON=$(curl -Ls -X GET "$jssURL/api/v1/computers-inventory?section=&page=0&page-size=100&sort=id%3Aasc" -H "Accept: application/json" -H "Authorization: Bearer $OAuthToken")
echo "Computers: $computersJSON"
This is a template I work from, it might need some tweaking at the command part on the bottom, but the token stuff should work.
#!/bin/sh
# Set some variables
username=$4
password=$5
jssURL="https://company.jamfcloud.com"
# Get the token
authBasic=$(echo '$username:$password\\c' | base64) # "\\c" is required to get the right format
authToken=$(curl -sk "$jssURL/api/v1/auth/token" -H "Accept: application/json" -H "Authorization: Basic $authBasic" -X POST --connect-timeout 10)
curlRes=$?
# Check the token result
if [[ $curlRes -gt 0 ]]
then
echo "CURL return code: $curlRes"
exit 1
fi
# We got a token, lets parse the data for the token itself
read -r -d '' JXA <<EOF
function run() {
var tokenInfo = JSON.parse(\\`$authToken\\`);
return tokenInfo.token;
}
EOF
OAuthToken=$( osascript -l 'JavaScript' <<< "${JXA}" )
read -r -d '' JXA <<EOF
function run() {
var tokenInfo = JSON.parse(\\`$authToken\\`);
return tokenInfo.expires;
}
EOF
# Set a variable with the expiration if your script will be running a while and you need to refer back
OAuthExpires=$( osascript -l 'JavaScript' <<< "${JXA}" )
# Run a Classic API call with bearer token auth
serialNum=$(ioreg -l | grep IOPlatformSerialNumber | awk '{print $4}' | cut -d "\\"" -f 2)
cloudCompID=$(curl -sk "$jssURL/JSSResource/computers/serialnumber/$serialNum" -H "Content-Type: application/xml" -H "Accept: application/xml" -H "Authorization: Bearer $OAuthToken" -X GET --connect-timeout 10 | xmllint --xpath "/computer/general/id/text()" - )
echo "Current machine computer ID: $cloudCompID"
# Run an Jamf Pro API call with bearer token auth
computersJSON=$(curl -Ls -X GET "$jssURL/api/v1/computers-inventory?section=&page=0&page-size=100&sort=id%3Aasc" -H "Accept: application/json" -H "Authorization: Bearer $OAuthToken")
echo "Computers: $computersJSON"
Here is a the original script shared in this thread (thanks @mm2270 ) converted to token authentication, however I'm getting a permissions error message at one part.
#!/bin/bash
username="username_here"
password="password_here"
URL=$(/usr/bin/defaults read /Library/Preferences/com.jamfsoftware.jamf.plist jss_url | sed 's|/$||')
EA_ID="$6"
# Make sure xpath changes won't bother us!
xpath() {
# the xpath tool changes in Big Sur
if [[ $(sw_vers -buildVersion) > "20A" ]]; then
/usr/bin/xpath -e "$@"
else
/usr/bin/xpath "$@"
fi
}
########################################
## This section is getting the token ##
########################################
# created base64-encoded credentials
encodedCredentials=$( printf "$username:$password" | /usr/bin/iconv -t ISO-8859-1 | /usr/bin/base64 -i - )
# generate an auth token (This is not the sanitized version)
authToken=$( /usr/bin/curl "$URL/api/v1/auth/token" \\
--silent \\
--request POST \\
--header "Authorization: Basic $encodedCredentials" )
# parse authToken for token, omit expiration (this is the sanitized version)
if [[ $(/usr/bin/sw_vers -productVersion | awk -F . '{print $1}') -lt 12 ]]; then
token=$(/usr/bin/awk -F \\" 'NR==2{print $4}' <<< "$authToken" | /usr/bin/xargs)
else
token=$(/usr/bin/plutil -extract token raw -o - - <<< "$authToken")
fi
########################################################################
######## This is the start of the Computer Role API Commands ###########
########################################################################
if [ -z "$username" ] || [ -z "$password" ] || [ -z "$EA_ID" ]; then
echo "One of the required script parameters was not filled in. Please check the policy script parameters and try again."
exit 1
fi
# Computer's UUID/UDID string
UDID=$(ioreg -rd1 -c IOPlatformExpertDevice | awk -F'"' '/IOPlatformUUID/{print $4}')
## The logged in user and their UID
LOGGED_IN_USER=$(stat -f%Su /dev/console)
LOGGED_IN_UID=$(id -u "$LOGGED_IN_USER")
## API call to obtain the Extension Attribute and store in file
curl -sk "$URL/JSSResource/computerextensionattributes/id/$EA_ID" -H "Content-Type: application/xml" -H "Accept: application/xml" -H "Authorization: Bearer $token" -X GET --connect-timeout 10 | xmllint --format - > /tmp/${EA_ID}.xml
## Get the EA display name
EA_NAME=$(xpath '/computer_extension_attribute/name/text()' < /tmp/${EA_ID}.xml)
## API call to obtain a list of drop down values from the Extension Attribute
VALUES_ALL=$(xpath '/computer_extension_attribute/input_type/popup_choices' < /tmp/${EA_ID}.xml 2>/dev/null | xmllint --format - | awk -F'>|<' '/<choice>/{print $3}')
if [ ! -z "$VALUES_ALL" ]; then
## Values were obtained for the EA. Prompt user to make a selection from a list
SELECTION=$(/bin/launchctl asuser "$LOGGED_IN_UID" sudo -iu "$LOGGED_IN_USER" /usr/bin/osascript << EOD
tell application "System Events"
activate
set Values to do shell script "echo \\"$VALUES_ALL\\""
set ValuesList to paragraphs of Values
choose from list ValuesList with prompt "Choose the appropriate computer role:"
end tell
EOD)
else
echo "No values obtained in the API"
exit 1
fi
function updateEAValue ()
{
## Create an xml file containing the EA settings
cat << EOF > /tmp/EA_${EA_ID}.xml
<computer>
<extension_attributes>
<extension_attribute>
<id>${EA_ID}</id>
<name>${EA_NAME}</name>
<type>String</type>
<value>${SELECTION}</value>
</extension_attribute>
</extension_attributes>
</computer>
EOF
## Update the current computer's server record with the updated EA value
curl -sk "$URL/JSSResource/computers/udid/${UDID}" -H "Content-Type: application/xml" -H "Accept: application/xml" -H "Authorization: Bearer $token" -X PUT --connect-timeout 10 | "/tmp/${EA_ID}.xml" -X PUT
if [ $? == 0 ]; then
echo "Extension Attribute value updated successfully"
/usr/local/bin/jamf displayMessage -message "Computer role updated successfully"
rm /tmp/EA_${EA_ID}.xml; rm /tmp/${EA_ID}.xml
exit 0
else
echo "Error when attempting to update the Extension Attribute value"
/usr/local/bin/jamf displayMessage -message "Error when attempting to update the Extension Attribute value"
rm /tmp/EA_${EA_ID}.xml; rm /tmp/${EA_ID}.xml
exit 1
fi
}
if [ "$SELECTION" != "false" ]; then
updateEAValue
else
echo "User canceled from selection. Nothing to do"
exit 0
fi
The part that I'm not able to get past for this API call to write the EA to the computer record is at this point:
curl -sk "$URL/JSSResource/computers/udid/${UDID}" -H "Content-Type: application/xml" -H "Accept: application/xml" -H "Authorization: Bearer $token" -X PUT --connect-timeout 10 | "/tmp/${EA_ID}.xml" -X PUT
I suspect it has something to do with the syntax- possibly the method that I'm using (PUT vs GET vs POST) to update the record or something not correct in the command. The exact error message I'm getting is: /tmp/6.xml: Permission denied.
Any guidance would be appreciated!
Here is a the original script shared in this thread (thanks @mm2270 ) converted to token authentication, however I'm getting a permissions error message at one part.
#!/bin/bash
username="username_here"
password="password_here"
URL=$(/usr/bin/defaults read /Library/Preferences/com.jamfsoftware.jamf.plist jss_url | sed 's|/$||')
EA_ID="$6"
# Make sure xpath changes won't bother us!
xpath() {
# the xpath tool changes in Big Sur
if [[ $(sw_vers -buildVersion) > "20A" ]]; then
/usr/bin/xpath -e "$@"
else
/usr/bin/xpath "$@"
fi
}
########################################
## This section is getting the token ##
########################################
# created base64-encoded credentials
encodedCredentials=$( printf "$username:$password" | /usr/bin/iconv -t ISO-8859-1 | /usr/bin/base64 -i - )
# generate an auth token (This is not the sanitized version)
authToken=$( /usr/bin/curl "$URL/api/v1/auth/token" \\
--silent \\
--request POST \\
--header "Authorization: Basic $encodedCredentials" )
# parse authToken for token, omit expiration (this is the sanitized version)
if [[ $(/usr/bin/sw_vers -productVersion | awk -F . '{print $1}') -lt 12 ]]; then
token=$(/usr/bin/awk -F \\" 'NR==2{print $4}' <<< "$authToken" | /usr/bin/xargs)
else
token=$(/usr/bin/plutil -extract token raw -o - - <<< "$authToken")
fi
########################################################################
######## This is the start of the Computer Role API Commands ###########
########################################################################
if [ -z "$username" ] || [ -z "$password" ] || [ -z "$EA_ID" ]; then
echo "One of the required script parameters was not filled in. Please check the policy script parameters and try again."
exit 1
fi
# Computer's UUID/UDID string
UDID=$(ioreg -rd1 -c IOPlatformExpertDevice | awk -F'"' '/IOPlatformUUID/{print $4}')
## The logged in user and their UID
LOGGED_IN_USER=$(stat -f%Su /dev/console)
LOGGED_IN_UID=$(id -u "$LOGGED_IN_USER")
## API call to obtain the Extension Attribute and store in file
curl -sk "$URL/JSSResource/computerextensionattributes/id/$EA_ID" -H "Content-Type: application/xml" -H "Accept: application/xml" -H "Authorization: Bearer $token" -X GET --connect-timeout 10 | xmllint --format - > /tmp/${EA_ID}.xml
## Get the EA display name
EA_NAME=$(xpath '/computer_extension_attribute/name/text()' < /tmp/${EA_ID}.xml)
## API call to obtain a list of drop down values from the Extension Attribute
VALUES_ALL=$(xpath '/computer_extension_attribute/input_type/popup_choices' < /tmp/${EA_ID}.xml 2>/dev/null | xmllint --format - | awk -F'>|<' '/<choice>/{print $3}')
if [ ! -z "$VALUES_ALL" ]; then
## Values were obtained for the EA. Prompt user to make a selection from a list
SELECTION=$(/bin/launchctl asuser "$LOGGED_IN_UID" sudo -iu "$LOGGED_IN_USER" /usr/bin/osascript << EOD
tell application "System Events"
activate
set Values to do shell script "echo \\"$VALUES_ALL\\""
set ValuesList to paragraphs of Values
choose from list ValuesList with prompt "Choose the appropriate computer role:"
end tell
EOD)
else
echo "No values obtained in the API"
exit 1
fi
function updateEAValue ()
{
## Create an xml file containing the EA settings
cat << EOF > /tmp/EA_${EA_ID}.xml
<computer>
<extension_attributes>
<extension_attribute>
<id>${EA_ID}</id>
<name>${EA_NAME}</name>
<type>String</type>
<value>${SELECTION}</value>
</extension_attribute>
</extension_attributes>
</computer>
EOF
## Update the current computer's server record with the updated EA value
curl -sk "$URL/JSSResource/computers/udid/${UDID}" -H "Content-Type: application/xml" -H "Accept: application/xml" -H "Authorization: Bearer $token" -X PUT --connect-timeout 10 | "/tmp/${EA_ID}.xml" -X PUT
if [ $? == 0 ]; then
echo "Extension Attribute value updated successfully"
/usr/local/bin/jamf displayMessage -message "Computer role updated successfully"
rm /tmp/EA_${EA_ID}.xml; rm /tmp/${EA_ID}.xml
exit 0
else
echo "Error when attempting to update the Extension Attribute value"
/usr/local/bin/jamf displayMessage -message "Error when attempting to update the Extension Attribute value"
rm /tmp/EA_${EA_ID}.xml; rm /tmp/${EA_ID}.xml
exit 1
fi
}
if [ "$SELECTION" != "false" ]; then
updateEAValue
else
echo "User canceled from selection. Nothing to do"
exit 0
fi
The part that I'm not able to get past for this API call to write the EA to the computer record is at this point:
curl -sk "$URL/JSSResource/computers/udid/${UDID}" -H "Content-Type: application/xml" -H "Accept: application/xml" -H "Authorization: Bearer $token" -X PUT --connect-timeout 10 | "/tmp/${EA_ID}.xml" -X PUT
I suspect it has something to do with the syntax- possibly the method that I'm using (PUT vs GET vs POST) to update the record or something not correct in the command. The exact error message I'm getting is: /tmp/6.xml: Permission denied.
Any guidance would be appreciated!
Ironically, I was looking at that script myself today trying to update my old auth scripts. I got that same error, I suspect there might be another xml file in tmp with that name (since it's just a number). I updated my code to "/tmp/$Jamf_EA_{EA_ID}.xml" in a few spots and it seems to be working now (although I'm getting a HTTP 401 return code trying to get the token). Slow progress is still progress, right?
Edit:
My credentials were setup like this:
encodedCredentials=$(echo "$APIUSER:$APIPASS\\c" | base64)
This worked fine when I ran the script locally, but failed when running through my Self Service policy. When I swapped in the `printf` command above, I got the prompt below and clicking that worked.
Ironically, I was looking at that script myself today trying to update my old auth scripts. I got that same error, I suspect there might be another xml file in tmp with that name (since it's just a number). I updated my code to "/tmp/$Jamf_EA_{EA_ID}.xml" in a few spots and it seems to be working now (although I'm getting a HTTP 401 return code trying to get the token). Slow progress is still progress, right?
Edit:
My credentials were setup like this:
encodedCredentials=$(echo "$APIUSER:$APIPASS\\c" | base64)
This worked fine when I ran the script locally, but failed when running through my Self Service policy. When I swapped in the `printf` command above, I got the prompt below and clicking that worked.
@PhillyPhoto , did you ever get this to work?
Reply
Enter your E-mail address. We'll send you an e-mail with instructions to reset your password.