Script to remove Management through API

GabeShack
Valued Contributor III

@mm2270 I seem to recall you building some great API scripts previously...hoping you can help me figure out what is wrong here...
Im trying to run a script that calls the remove mdm profile button api and had found this... however its giving me an error when I run it even if I try in one line typing the variables directly in:

#!/bin/bash
## account with computer create and read (JSS Objects), Send Computer Unmanage Command (JSS Actions)
uname="$4"
pwd="$5"

if [ "$6" != "" ];then
    server="$6"
else
    ## get current Jamf server
    server=$(defaults read /Library/Preferences/com.jamfsoftware.jamf.plist jss_url)
fi

## ensure the server URL ends with a /
strLen=$((${#server}-1))
lastChar="${server:$strLen:1}"
if [ ! "$lastChar" = "/" ];then
    server="${server}/"
fi

## get unique identifier for machine
udid=$(system_profiler SPHardwareDataType | awk '/UUID/ { print $3; }')

## get computer ID from Jamf server
compId=$(/usr/bin/curl -sku ${uname}:${pwd} ${server}JSSResource/computers/udid/${udid}/subset/general -H "Accept: application/xml" | /usr/bin/xpath "//computer/general/id/text()" )

## send unmanage command to machine
curl -X POST -sku ${uname}:${pwd} ${server}JSSResource/computercommands/command/UnmanageDevice/id/${compId}

The error I keep getting is :

Script result: 
mismatched tag at line 10, column 2, byte 404:
<p>You can get technical details <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2">here</a>.<br>
    Please continue your visit at our <a href="/">home page</a>.
</p>
=^
</body>
</html>
 at /System/Library/Perl/Extras/5.18/darwin-thread-multi-2level/XML/Parser.pm line 187.
<html>
<head>
    <title>Status page</title>
</head>
<body style="font-family: sans-serif;">
<p style="font-size: 1.2em;font-weight: bold;margin: 1em 0px;">Unauthorized</p>
<p>The request requires user authentication</p>
<p>You can get technical details <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2">here</a>.<br>
    Please continue your visit at our <a href="/">home page</a>.
</p>
</body>
</html>

Any Ideas?
Gabe Shackney
Princeton Public Schools

Gabe Shackney
Princeton Public Schools
2 ACCEPTED SOLUTIONS

Tribruin
Valued Contributor II

So, it looks like the first curl command is not returning the expected XML data and xpath is breaking. You could try trimming the pipe to xpath off the curl command and then echo the output and see what result you are getting.

Isn't troubleshooting script fun?

FYI - I apologize if this basic, but I want to make sure you edited out your username, password, and url before posted the script result. All three items are blank, just want to double check and make sure we are not overlooking anything.

View solution in original post

GabeShack
Valued Contributor III

Can I just say how stupid I am at this point. I knew it was simple.

Up until this migration to the jamf cloud we had not used the feature for the scripts being built into the server. Like a fool I was editing in the Variable descriptions, not the actual variables. Im really sorry to waste everyones valuable time on this. Hopefully I can get you all gift cards for beer or something when this is all done.

Once I fixed my stupidity everything now works as it should.

Gabe Shackney
Princeton Public Schools

Gabe Shackney
Princeton Public Schools

View solution in original post

18 REPLIES 18

Tribruin
Valued Contributor II

At first glance, it looks like your API user account does not have the correct privileges set. The first error is from xpath. It is failing to find the fully XML path it is looking for. The second error is a shown in the response request requires user authentication. Check your privileges in Jamf for the API users. You will need Jamf Server Pro Objects -> Computers -> Read to retrieve the computer record and (I think) Jamf Pro Server Actions -> Send Computer Unmanage Command

GabeShack
Valued Contributor III

@RBlount Thanks for the response!
Funny thing is im using my user account as a test right now just to get this working which has full access.

Gabe Shackney
Princeton Public Schools

Gabe Shackney
Princeton Public Schools

GabeShack
Valued Contributor III

I think there is something wrong with the uuid command or the computer id command, because when I input the last line and just fill in the variables it works as expected.

Gabe Shackney
Princeton Public Schools

Gabe Shackney
Princeton Public Schools

GabeShack
Valued Contributor III

Ok Update,
I hashed out all the extra code so it was just the variables and the call lines... so now it looks like:

#!/bin/bash
uname="$4"
pwd="$5"
#if [ "$6" != "" ];then
server="$6"
#else
## get current Jamf server
#server=$(defaults read /Library/Preferences/com.jamfsoftware.jamf.plist jss_url)
#fi

## ensure the server URL ends with a /
#strLen=$((${#server}-1))
#lastChar="${server:$strLen:1}"
#if [ ! "$lastChar" = "/" ];then
#    server="${server}/"
#fi

## get unique identifier for machine
udid=$(system_profiler SPHardwareDataType | awk '/UUID/ { print $3; }')

## get computer ID from Jamf server
compId=$(/usr/bin/curl -sku ${uname}:${pwd} ${server}JSSResource/computers/udid/${udid}/subset/general -H "Accept: application/xml" | /usr/bin/xpath "//computer/general/id/text()" )

## send unmanage command to machine
curl -X POST -sku ${uname}:${pwd} ${server}JSSResource/computercommands/command/UnmanageDevice/id/${compId}

And the new error message is:

Script exit code: 6
Script result: 
no element found at line 1, column 0, byte 0:

Error running script: return code was 6.

Gabe Shackney
Princeton Public Schools

Gabe Shackney
Princeton Public Schools

leslie
Contributor II
Contributor II

I'd try running commands manually, hard code some values to try and determine where the problem lies.
Validate you get a valid response when querying for the udid. You can do this a couple different ways (both should yield the same result):

system_profiler SPHardwareDataType | awk '/UUID/ { print $3; }'
ioreg -rd1 -c IOPlatformExpertDevice | awk '/UUID/ { print $3 }' | sed -e 's/"//g'

Then do the curl (hard code variables):

/usr/bin/curl -sku "jamfUser:somePassword" https://your.jamf.server/JSSResource/computers/udid/hardCodedUdid/subset/general -H "Accept: application/xml"

Verify the result returns a computer record (XML format) containing the Jamf ID for the machine.

tlarkin
Honored Contributor

Not sure if this helps but I just do an advanced search to unmanage clients after they hae not checked in after n days unless you have to use the API for this workflow

Tribruin
Valued Contributor II

How are you trying to run the script? Locally or through a policy? If you haven't tried, run the policy directly on the computer from terminal and see if runs properly.

Also, +1 to hard coding your username, password, and url for testing purposes. A couple of other tips for troubleshooting scripts:

Add a set -x right after your shebang line to see each command as it runs. You can see the commands exactly as they are being run. Add an echo command after each variable assignment and confirm the result is what you expect. For example, add echo $udid to the line after getting the $udid variable and check the output when you are running the script.

GabeShack
Valued Contributor III

@leslie Thanks for this. So when I run each line it seems to work as expected since each command is returning what its supposed to (I understand that the NODE message for the device ID is ignored and only the final result of the command is inputted correct?)

@RBlount Im running the command as a policy trigger in terminal. If I run each command in terminal it is working normally. If I hard code all the values in the last line, it works as expected. Let me try adding the echos and the set -x and play a bit more.

@tlarkin This is a command I need to shift a few hundred computers to our new cloud hosted JSS that are enrolled with a non-removable MDM profile. This command runs as part of Leslie's Jamf Re-Enroller during the process of getting these machines migrated. But I appreciate the response.

Thanks all, I'll keep chugging away,

Gabe Shackney
Princeton Public Schools

Gabe Shackney
Princeton Public Schools

GabeShack
Valued Contributor III

This almost looks like a DNS issue from my homes internet since it looks to be failing on the device ID piece but almost like the page is unreachable so it pops a Verizon Fios unreachable message...

Script result:  uname=
pwd=
server=
system_profiler SPHardwareDataType
awk '/UUID/ { print $3; }'
udid=64C66C61-CE1E-5CD4-8D27-EA565555270B
echo 64C66C61-CE1E-5CD4-8D27-EA565555270B
64C66C61-CE1E-5CD4-8D27-EA565555270B
/usr/bin/curl -sku : JSSResource/computers/udid/64C66C61-CE1E-5CD4-8D27-EA565555270B/subset/general -H 'Accept: application/xml'
+ /usr/bin/xpath '//computer/general/id/text()'

not well-formed (invalid token) at line 1, column 269, byte 269:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html><head><meta http-equiv="refresh" content="0;url=https://searchassist.verizon.com/main?ParticipantID=euekiz39ksg8nwp7iqj2fp5wzfwi5q76&FailedURI=http%3A%2F%2FJSSResource%2Fcomputers%2Fudid%2F64C66C61-CE1E-5CD4-8D27-EA565555270B%2Fsubset%2Fgeneral&FailureMode=1&Implementation=&AddInType=4&Version=pywr1.0&ClientLocation=us"/><script type="text/javascript">url="https://searchassist.verizon.com/main?ParticipantID=euekiz39ksg8nwp7iqj2fp5wzfwi5q76&FailedURI=http%3A%2F%2FJSSResource%2Fcomputers%2Fudid%2F64C66C61-CE1E-5CD4-8D27-EA565555270B%2Fsubset%2Fgeneral&FailureMode=1&Implementation=&AddInType=4&Version=pywr1.0&ClientLocation=us";if(top.location!=location){var w=window,d=document,e=d.documentElement,b=d.body,x=w.innerWidth||e.clientWidth||b.clientWidth,y=w.innerHeight||e.clientHeight||b.clientHeight;url+="&w="x"&h="y;}window.location.replace(url);</script></head><body></body></html>
============================================================================================================================================================================================================================================================================^ at /System/Library/Perl/Extras/5.18/darwin-thread-multi-2level/XML/Parser.pm line 187.
compId=
+ echo

  • curl -X POST -sku : JSSResource/computercommands/command/UnmanageDevice/id/ Error running script: return code was 52.
Gabe Shackney
Princeton Public Schools

GabeShack
Valued Contributor III

So fixed that part by switching to Fios's non assisted DNS servers, so I'm back to the same error which is from the device ID lookup which again works when I plug in all the variables and run it directly.

Running script apiMDM_remove.sh...
Script exit code: 6
Script result: + uname=
+ pwd=
+ server=
++ system_profiler SPHardwareDataType
++ awk '/UUID/ { print $3; }'
+ udid=64C66C61-CE1E-5CD4-8D27-EA565555270B
+ echo 64C66C61-CE1E-5CD4-8D27-EA565555270B
64C66C61-CE1E-5CD4-8D27-EA565555270B
++ /usr/bin/curl -sku : JSSResource/computers/udid/64C66C61-CE1E-5CD4-8D27-EA565555270B/subset/general -H 'Accept: application/xml'
++ /usr/bin/xpath '//computer/general/id/text()'

no element found at line 1, column 0, byte 0:

Error running script: return code was 6.
Gabe Shackney
Princeton Public Schools

Tribruin
Valued Contributor II

So, it looks like the first curl command is not returning the expected XML data and xpath is breaking. You could try trimming the pipe to xpath off the curl command and then echo the output and see what result you are getting.

Isn't troubleshooting script fun?

FYI - I apologize if this basic, but I want to make sure you edited out your username, password, and url before posted the script result. All three items are blank, just want to double check and make sure we are not overlooking anything.

GabeShack
Valued Contributor III

No I do appreciate the basic checks. Im going on very little sleep and trying to roll out a migration to the jamf cloud all while setting up for a new district one-to-one....so my brain is working on peanuts.

I left the script running with the variables plugged into it on the server side and this is what it returns ...so is that just indicating that the variables aren't being passed from the jamf server properly perhaps? (I really am thinking this is something very simple that im overlooking so this wouldn't surprise me).

Gabe Shackney
Princeton Public Schools

Gabe Shackney
Princeton Public Schools

GabeShack
Valued Contributor III

Can I just say how stupid I am at this point. I knew it was simple.

Up until this migration to the jamf cloud we had not used the feature for the scripts being built into the server. Like a fool I was editing in the Variable descriptions, not the actual variables. Im really sorry to waste everyones valuable time on this. Hopefully I can get you all gift cards for beer or something when this is all done.

Once I fixed my stupidity everything now works as it should.

Gabe Shackney
Princeton Public Schools

Gabe Shackney
Princeton Public Schools

Tribruin
Valued Contributor II

Glad you found the issue. We have all been there. Despite the frustration I feel when troubleshooting, the feeling you get when you find the error is so refreshing.

Good luck with your project.

ooshnoo
Valued Contributor

Jamf includes a script with their Re-Enroller app that removes the MDM profile. Wished I saw this thread sooner...could have saved you some time.

GabeShack
Valued Contributor III

@ooshnoo thanks. This is actually lifted from @leslie s script from the JAMF ReEnroller. I think I tend to just make things more complicated. This mistake would have done the same thing though since I wasn’t smart enough to put the variables where they belonged.

Gabe Shackney
Princeton Public Schools

Gabe Shackney
Princeton Public Schools

sk25
Contributor
Guys, When I execute the above script, getting the message: 

curl: (23) Failed writing body. Kindly advice.

#! /bin/sh

## account with computer create and read (JSS Objects), Send Computer Unmanage Command (JSS Actions)

username="XX"

password="XX"

server="XX"

 

## if [ "$6" != "" ];then

##    server="$6"

## else

    ## get current Jamf server

   ## server=$(defaults read /Library/Preferences/com.jamfsoftware.jamf.plist jss_url)

## fi

 

## ensure the server URL ends with a /

## strLen=$((${#server}-1))

## lastChar="${server:$strLen:1}"

## if [ ! "$lastChar" = "/" ];then

##    server="${server}/"

## fi

 

## get unique identifier for machine

udid=$( system_profiler SPHardwareDataType | awk '/UUID/ { print $3; }' )

 

echo udid=$udid

 

## get computer ID from Jamf server

compId=$( /usr/bin/curl \

--user "$username:$password" \

--request GET \

--url "$server/JSSResource/computers/udid/${udid}/subset/general" \

--header "Accept: application/xml" \

|/usr/bin/xpath '/computer/general/id/text()' 2> /dev/null )

echo compid=$compId

## send unmanage command to machine
/usr/bin/curl \
--request POST \
--user "$username:$password" \
--url "$server/JSSResource/computercommands/command/UnmanageDevice/id/${compId}"

 

leslie
Contributor II
Contributor II

Likely an issue with xpath.  See the following:

https://scriptingosx.com/2020/10/dealing-with-xpath-changes-in-big-sur/