Skip to main content
Blog

How to convert Classic API scripts to use bearer token authentication


Did this topic help you find an answer to your question?
Show first post

36 replies

Forum|alt.badge.img+9
  • Contributor
  • 11 replies
  • March 19, 2024

I can't thank you enough! Excellent article, very detailed and extremely helpful.


MacJunior
Forum|alt.badge.img+9
  • Valued Contributor
  • 129 replies
  • April 4, 2024

How do I use encoded credentials with bearer authentication?


howie_isaacks
Forum|alt.badge.img+23
  • Esteemed Contributor
  • 773 replies
  • April 10, 2024

This was very helpful. Reading this and trying out all of the steps helped me learn how to use the API in scripts. Today, I created a new script that uses the API to assign Macs to sites. This has been a big issue for us since we have several Jamf admins who can only access their assigned site. We had a lot of Macs assigned to the wrong site or not assigned to any. I was able to automate the assignments using the script.


Forum|alt.badge.img+13
  • Valued Contributor
  • 277 replies
  • May 1, 2024

@talkingmoose 

I'm looking at trying to do the same thing but for a powershellscript, have you had any success doing that?

 

the intent is to populate our DHCP with approved access policies for mdm bound Mac addresses, so that we can curb user wifi enrolment of non bound devices, which are also generating multiple IP reservations in our DHCP, due to the changing Mac addresses, where the device causing it is unmanaged.


Forum|alt.badge.img+7
  • Contributor
  • 31 replies
  • November 7, 2024

Hi all,

I have a shell script that will take all app IDs I have listed and add them to a category ID I have listed. I just can't seem to incorporate this into @talkingmoose method of using bearer token.

Can anyone point me in the right direction?

 

 

#!/bin/sh TARGET=(29 58 64 65 87 88 133 157 158 169 190 205 236 267 271 278 279 284 290 315 318 337 343 371 379 381 389 395 406 411 415 434 444 449 479 489 512 513 535 563 567 572 574 576 579 590 591 595 597 598 599 605 630 642 654 657 660 680 688 694 738 740 751 752) CATEGORY=24 cat $TARGET | while read APP; do curl -sk -u @username:@password -H "Content-Type: text/xml" -d "<?xml version="1.0" encoding="ISO-8859-1"?><mobile_device_application><general><category><id>$CATEGORY</id></category></general></mobile_device_application>" https://$jamfProURL/JSSResource/mobiledeviceapplications/id/$APP -X PUT done

 

 


Forum|alt.badge.img+7
  • Contributor
  • 31 replies
  • November 7, 2024

so far I got 

#!/bin/zsh # server and credential information jamfProURL=https://www.myjamfurl.com:8443/ username="username" password="password" renewToken() { # renew auth token authToken=$( /usr/bin/curl \\ --header "Accept: application/json" \\ --header "Authorization: Bearer $token" \\ --request POST \\ --silent \\ --url "$jamfProURL/api/v1/auth/keep-alive" ) # parse auth token token=$( /usr/bin/plutil \\ -extract token raw - <<< "$authToken" ) tokenExpiration=$( /usr/bin/plutil \\ -extract expires raw - <<< "$authToken" ) localTokenExpirationEpoch=$( TZ=GMT /bin/date -j \\ -f "%Y-%m-%dT%T" "$tokenExpiration" \\ +"%s" 2> /dev/null ) # update the renewal time for another 25 minutes renewalTime=$(( $localTokenExpirationEpoch - 300 )) } # request auth token authToken=$( /usr/bin/curl \\ --request POST \\ --silent \\ --url "$jamfProURL/api/v1/auth/token" \\ --user "$username:$password" ) echo "$authToken" # parse auth token token=$( /usr/bin/plutil \\ -extract token raw - <<< "$authToken" ) tokenExpiration=$( /usr/bin/plutil \\ -extract expires raw - <<< "$authToken" ) localTokenExpirationEpoch=$( TZ=GMT /bin/date -j \\ -f "%Y-%m-%dT%T" "$tokenExpiration" \\ +"%s" 2> /dev/null ) echo Token: "$token" echo Expiration: "$tokenExpiration" echo Expiration epoch: "$localTokenExpirationEpoch" # subtract five minutes (300 seconds) from localTokenExpirationEpoch renewalTime=$(( $localTokenExpirationEpoch - 300 )) while IFS= read aDevice do now=$( /bin/date +"%s" ) if [[ "$renewalTime" -lt "$now" ]]; then renewToken fi # change app categorys TARGET=(29 58 64 65 87 88 133 157 158 169 190 205 236 267 271 278 279 284 290 315 318 337 343 371 379 381 389 395 406 411 415 434 444 449 479 489 512 513 535 563 567 572 574 576 579 590 591 595 597 598 599 605 630 642 654 657 660 680 688 694 738 740 751 752) CATEGORY=24 APP="<mobile_device_application><general><category><id>$CATEGORY</id></category></general></mobile_device_application>" $appcategory=$( /usr/bin/curl \\ --header "Accept: text/xml" \\ --request PUT \\ --silent \\ --url "$jamfProURL/JSSResource/mobiledeviceapplications/id/$APP" \\ --header "Authorization: Bearer $token" ) done <<< "$appcategory" # expire auth token /usr/bin/curl \\ --header "Authorization: Bearer $token" \\ --request POST \\ --silent \\ --url "$jamfProURL/api/v1/auth/invalidate-token" # verify auth token is valid checkToken=$( /usr/bin/curl \\ --header "Authorization: Bearer $token" \\ --silent \\ --url "$jamfProURL/api/v1/auth" \\ --write-out "%{http_code}" ) tokenStatus=${checkToken: -3} echo Token status: "$tokenStatus"

yet I'm getting a 

Token: <stdin>: Could not extract value, error: No value at that key path or invalid key path: token

Expiration: <stdin>: Could not extract value, error: No value at that key path or invalid key path: expires

Expiration epoch:

Untitled.sh: line 78: =: command not found

Token status: 000
error.


Forum|alt.badge.img+13
  • Valued Contributor
  • 277 replies
  • November 7, 2024

@HenryOzsoy 

I am going to be inclined to say its the put command.

How I am reading it is:

$appcategory=$( /usr/bin/curl \\

--header "Accept: text/xml" \\

--request PUT \\

--silent \\

--url "$jamfProURL/JSSResource/mobiledeviceapplications/id/<mobile_device_application><general><category><id>$CATEGORY</id></category></general></mobile_device_application>"

 

I think firstly you want:

--url "$jamfProURL/JSSResource/mobiledeviceapplications/id/$TARGET”

not

--url "$jamfProURL/JSSResource/mobiledeviceapplications/id/$APP”


This is some example code that uses PUT that will insert a variable into the Purchasing_Contact field of a device.

so I think your xml section needs to be similar...

I will try and re-write your section there in the way I think it should be written in a follow up post... But I would advise to test it against a single Target first.

echo "<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?> <xsl:stylesheet version=\\"1.0\\" xmlns:xsl=\\"http://www.w3.org/1999/XSL/Transform\\"> <xsl:output method=\\"text\\"/> <xsl:template match=\\"/\\"> <xsl:value-of select=\\"id\\"/> </xsl:template> </xsl:stylesheet>" > /private/var/tmp/stylesheet.xslt curl -s -k \\ -H "Authorization: Bearer $jamfProApiToken" \\ -H "Content-type: application/xml" \\ -X PUT \\ -d "<computer><purchasing><purchasing_contact>$updatedmdmdeviceName</purchasing_contact></purchasing></computer>" \\ "${jamfProURL}/JSSResource/computers/id/$computerID" echo "name change applied $updatedmdmdeviceName"

 


Forum|alt.badge.img+7
  • Contributor
  • 31 replies
  • November 7, 2024

Thanks, @Malcolm . To follow up on your comment, I modified the script. I'm not getting any errors now, yet no change has occurred in the app category post-script.

#!/bin/sh # server and credential information jamfProURL=https://www.myjamfurl.com:8443 username="username" password="password" renewToken() { # renew auth token authToken=$( /usr/bin/curl \\ --header "Accept: application/json" \\ --header "Authorization: Bearer $token" \\ --request POST \\ --silent \\ --url "$jamfProURL/api/v1/auth/keep-alive" ) # parse auth token token=$( /usr/bin/plutil \\ -extract token raw - <<< "$authToken" ) tokenExpiration=$( /usr/bin/plutil \\ -extract expires raw - <<< "$authToken" ) localTokenExpirationEpoch=$( TZ=GMT /bin/date -j \\ -f "%Y-%m-%dT%T" "$tokenExpiration" \\ +"%s" 2> /dev/null ) # update the renewal time for another 25 minutes renewalTime=$(( $localTokenExpirationEpoch - 300 )) } # request auth token authToken=$( /usr/bin/curl \\ --request POST \\ --silent \\ --url "$jamfProURL/api/v1/auth/token" \\ --user "$username:$password" ) echo "$authToken" # parse auth token token=$( /usr/bin/plutil \\ -extract token raw - <<< "$authToken" ) tokenExpiration=$( /usr/bin/plutil \\ -extract expires raw - <<< "$authToken" ) localTokenExpirationEpoch=$( TZ=GMT /bin/date -j \\ -f "%Y-%m-%dT%T" "$tokenExpiration" \\ +"%s" 2> /dev/null ) echo Token: "$token" echo Expiration: "$tokenExpiration" echo Expiration epoch: "$localTokenExpirationEpoch" # subtract five minutes (300 seconds) from localTokenExpirationEpoch renewalTime=$(( $localTokenExpirationEpoch - 300 )) while IFS= read aDevice do now=$( /bin/date +"%s" ) if [[ "$renewalTime" -lt "$now" ]]; then renewToken fi # change app categorys TARGET=29 CATEGORY=24 appcategory=$( /usr/bin/curl \\ --header "Accept: text/xml" \\ --request PUT \\ --silent \\ --url "$jamfProURL/JSSResource/mobiledeviceapplications/id/$TARGET/<mobile_device_application><general><category><id>$CATEGORY</id><name>Applications</name></category></general><mobile_device_application>" \\ --header "Authorization: Bearer $token" ) done <<< "$changeappcategorys" echo "$appcategory" # expire auth token /usr/bin/curl \\ --header "Authorization: Bearer $token" \\ --request POST \\ --silent \\ --url "$jamfProURL/api/v1/auth/invalidate-token" # verify auth token is valid checkToken=$( /usr/bin/curl \\ --header "Authorization: Bearer $token" \\ --silent \\ --url "$jamfProURL/api/v1/auth" \\ --write-out "%{http_code}" ) tokenStatus=${checkToken: -3} echo Token status: "$tokenStatus"

Forum|alt.badge.img+13
  • Valued Contributor
  • 277 replies
  • November 7, 2024

@HenryOzsoy 

try this:

 

echo "<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?> <xsl:stylesheet version=\\"1.0\\" xmlns:xsl=\\"http://www.w3.org/1999/XSL/Transform\\"> <xsl:output method=\\"text\\"/> <xsl:template match=\\"/\\"> <xsl:value-of select=\\"id\\"/> </xsl:template> </xsl:stylesheet>" > /private/var/tmp/stylesheet.xslt curl -s -k \\ -H "Authorization: Bearer $token" \\ -H "Content-type: application/xml" \\ -X PUT \\ -d "<mobile_device_application><general><category><id>$CATEGORY</id></category></general></mobile_device_application>" \\ "${jamfProURL}/JSSResource/mobiledeviceapplications/id/$TARGET" echo "Category change Category $CATEGORY to application $TARGET"

 

 

But I would suggest trying this first against just one of your targets:

 

echo "<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?> <xsl:stylesheet version=\\"1.0\\" xmlns:xsl=\\"http://www.w3.org/1999/XSL/Transform\\"> <xsl:output method=\\"text\\"/> <xsl:template match=\\"/\\"> <xsl:value-of select=\\"id\\"/> </xsl:template> </xsl:stylesheet>" > /private/var/tmp/stylesheet.xslt curl -s -k \\ -H "Authorization: Bearer $token" \\ -H "Content-type: application/xml" \\ -X PUT \\ -d "<mobile_device_application><general><category><id>24</id></category></general></mobile_device_application>" \\ "${jamfProURL}/JSSResource/mobiledeviceapplications/id/29" echo "Category change category 24 on app 29"

 

 


Forum|alt.badge.img+7
  • Contributor
  • 31 replies
  • November 8, 2024

Thanks, @Malcolm works great.


Forum|alt.badge.img+13
  • Valued Contributor
  • 277 replies
  • November 8, 2024

@HenryOzsoy 

Happy to have helped, it took me a long time to work out the put command the right way, I had an old script for forcing old assets to unmanaged a Jamf employee helped me with because I wanted to retain the information of the previously managed devices, such as the activation lock and FileVault key.

I later ended up needing to do it for a different purpose, and had to dissect their code to work it out.

I use it to auto name devices, using assigned users and prefix information I append to the device, set via a prestage enrolment group, the trouble I had was I had a lot of devices, in presages where the data wasn;t accurate as moving a device from one prestage to another would leave the old prestage information on the device record, so I had to query the presages for the device id, then collect the correct prestage prefix info I would store in the prestage purchasing section of the prestage info, then I would update that data back to the device record, and then use that data with the assigned user to name the device.

I then later on used it to also bind devices that were shared devices, by using a purchasing field for the string AD, which then in the same naming script, would also domain bind the device.


Reply


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings