Unable to set a Recovery Lock Command

brentac
New Contributor II

I am attempting to set (or more accurately clear) recovery lock on an M1 Macbook Air using bash. I work for a school district but we are using Jamf Pro

We have had an issue where several hundred of our fleet have been (seemingly) randomly getting set into Recovery Lock. Some after initial log in. Others after our end users have had the device for a few hours or days. While the larger issue of what's triggering it is being investigated, I was trying to help speed up the process of getting these devices back into our users hands and clear the recovery lock code (and then set another one) so they could get back in.

We have a little under 10K M1 MacBook Airs and I was able to obtain the management ID (as detailed here) for the devices I want to do this too. I am new to scripting but was able to work my way through obtaining a bearer token and parsing the different pages to find the device in question (using jq to pull the relevant management ID).

I've looked at every sample script I could find related to Recovery Lock but all of them are ending up with various errors. Sometimes it's a 401 (which I've even gotten when trying with an account with full admin access, though ultimately I'd like to use a single purpose account for this). Other times I've gotten a 415 and it's said something along the lines of the curl command wasn't formatted properly, though I was using the same one from the website (as far as I know).

I am 100% ready to believe it's operator error. Like I said I'm new to scripting. Outside Shortcuts programming in general is not something I have experience with. I've actually tried in shortcuts but am getting the same results. Shortcuts is how I initially figured out the management ID before moving that to bash as well.

Here is my latest attempts at what I have been sending. Any advise would be greatly appreciated.

 

curl --location --request POST 'https://myDomain.jamfcloud.com/api/preview/mdm/commands' \
--header 'Authorization: Bearer $bearerToken' \
--header 'Content-Type: application/json' \
--data-raw '{
"clientData": [
{
"managementId": "'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'",
"clientType": "COMPUTER"
}
],
"commandData": {
"commandType": "SET_RECOVERY_LOCK",
"newPassword": "NewPassword",
}
}'

 

 

16 REPLIES 16

jtrant
Valued Contributor

Are you able to manually issue the MDM command using the same account and the API landing page?

 

https://myDomain.jamfcloud.com/api/doc

 

If so, that would rule out a permission issue. I ask because there is a specific permission needed for this, which is
"Send Set Recovery Lock Command" under the "Jamf Pro Server Actions" section. 

brentac
New Contributor II

I did the "Try it out" under /preview/mdm/commands with an account with full admin permissions and got these back:

 

Response Body
{
  "httpStatus": 500,
  "errors": [
    {
      "code": "SYSTEM_EXCEPTION",
      "description": "Unable to perform MDM operation",
      "id": "0",
      "field": null
    }
  ]
}
Response headers
 cache-control: no-cache, no-store, must-revalidate 
 content-type: application/json 
 date: Wed, 12 Oct 2022 14:07:21 GMT 
 expires: 0 
 server: Jamf Cloud Node 
 strict-transport-security: max-age=31536000; includeSubdomains;, max-age=31536000 ; includeSubDomains 
 x-frame-options: DENY 
 x-xss-protection: 1; mode=block 

 
When I did /v1/mdm/commands with the same account it worked to return info about the device in question.

brentac
New Contributor II

Ok scratch that other response. I had not realized a field was editable for me. I copied the code from the recovery lock documentation page and got this response 

 

{
  "httpStatus": 400,
  "errors": [
    {
      "code": "INVALID_FIELD",
      "description": "JSON parse error: Unexpected character (''' (code 39)): expected a valid value (JSON String, Number, Array, Object or token 'null', 'true' or 'false'); nested exception is com.fasterxml.jackson.core.JsonParseException: Unexpected character (''' (code 39)): expected a valid value (JSON String, Number, Array, Object or token 'null', 'true' or 'false')",
      "id": "0",
      "field": null
    }
  ]
}

jtrant
Valued Contributor

What are you trying to set the Recovery Lock password to? It's numeric only.

brentac
New Contributor II

Well that's interesting.  I didn't know it was numeric only (I should have thought of that possibility though since when I've looked at them they were all numbers.) I tried with my admin account and got a 401 still however (I tried an empty string to remove it as well as a numeric one.)

jtrant
Valued Contributor

401 is unauthorized. Request a new bearer token from the top of the page to ensure you have a valid session. I think they expire after 30 minutes.

brentac
New Contributor II

When I did that one I had just requested it via script (and that token worked to retrieve the management IDs in the same script).

jtrant
Valued Contributor

Interesting, and the account you're using has the "Send Set Recovery Lock Command" permission, and 'Update' permissions for Computers?

brentac
New Contributor II

Correct. While I intend to use a specific account with just the required permissions for this, to make sure I had the syntax down (again, new) I am using an account with full admin permissions. I made a point of check those specific elements as well.

jtrant
Valued Contributor

I'm really not sure at this point. I'd probably reach out to Jamf Support on this. Sorry I can't help more!

taochunhua
New Contributor II

Hello, can I ask how you solved the problem in the end, I also encountered the same problem, if you can tell me, thank you very much.😉

brentac
New Contributor II

Guess that will be my next step. I really appreciate you trying. Thank you.

taochunhua
New Contributor II

Hello, can I ask how you solved the problem in the end, I also encountered the same problem, if you can tell me, thank you very much.

brentac
New Contributor II

This is the working code we have. Slightly adapted from some code we found on GitHub but forgive me I can't find it now to give you a proper link. This is set to remove the password. I have found the password can be alphanumeric . 

 

pdata=$(jq --null-input --arg mgmtid "$ID" \
    '{
    "clientData": [
        {
            "managementId": $mgmtid,
            "clientType": "COMPUTER"
        }
    ],
    "commandData": {
        "commandType": "SET_RECOVERY_LOCK",
        "newPassword": "",
    }
    }')


# Send the command to change the recovery lock password. 

    /usr/bin/curl --location --request POST "$jamfURL/api/preview/mdm/commands" \
    --header "Authorization: Bearer $bearerToken" \
    --header "Content-Type: application/json" \
    --header "accept: application/json" \
    --silent \
    --data-raw "$pdata"

  

taochunhua
New Contributor II

ok.l'll test this code,very thanks for your code 😊

taochunhua
New Contributor II

thanks