Posted on 10-31-2024 10:55 AM
Hi there! I'm tasked with migrating our devices from Jamf to WorkspaceONE. Working on a migration script to unmange computers automatically and have the user install an MDM profile for automated enrollment.
My issue is the JamfPro API Command to UnmanageDevice. Its just not going through. Here is the command I am using:
curl -X POST --header "Authorization: Bearer $bearer_token" "$JamfProURL/JSSResource/computercommands/command/UnmanageDevice/id/$DeviceID"
The variables are working for everything else so it can authenticate into jamf and pull the device ID using the computers serial number, but this is the main blocker. Below is the response I get:
<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;">Not Found</p>
<p>The server has not found anything matching the request URI</p>
<p>You can get technical details <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.5">here</a>.<br>
Please continue your visit at our <a href="/">home page</a>.
</p>
</body>
</html>
Solved! Go to Solution.
Posted on 11-01-2024 08:12 AM
Well I got it working showhow. Guess it was just tweaking with the variable until it starts to work.
# Get Mac serial number
serialNumber=`system_profiler SPHardwareDataType | awk '/Serial/ {print $4}'`
echo "Mac serial: $serialNumber"
# Curl to get Mac Jamf ID. Adding text()' will just return the Jamf ID without bracked info.
# determine Jamf Pro device id
deviceID=$(curl -s -H "Accept: text/xml" -H "Authorization: Bearer ${bearer_token}" ${JamfProURL}/JSSResource/computers/serialnumber/"$serialNumber" | xmllint --xpath '/computer/general/id/text()' -)
echo "Jamf ID: $deviceID"
# Remove Jamf Framework
echo "Removing Jamf Framework..."
/usr/local/bin/jamf removeFramework
# Curl to send command to remove MDM profile from the Mac
echo "Removing Jamf MDM via CURL $JamfProURL/JSSResource/computercommands/command/UnmanageDevice/id/$deviceID"
curl -v -X POST --header "Authorization: Bearer $bearer_token" "$JamfProURL/JSSResource/computercommands/command/UnmanageDevice/id/$deviceID"
exit 0
So there's the code I'm using in case someone else has a similar issue or If I run into this again.
10-31-2024 12:14 PM - edited 10-31-2024 12:41 PM
What happens if you try BlankPush instead of UnmanagedDevice? And/or if you hardcode the ID of a specific Mac?
Posted on 10-31-2024 01:33 PM
So putting the DeviceID hardcoded into the URL actually seemed to correct the issue (Device is now unmanaged)
<?xml version="1.0" encoding="UTF-8"?><computer_command><command><name>UnmanageDevice</name><command_uuid>9c5b938b-e310-4407-93a9-d13fc93d7ed9</command_uuid><computer_id>7744</computer_id></command></computer_command>%
But if that's the case, what is my bash script doing wrong to put in the deviceID it pulls, this script needs to run an any machine that's in Jamf and unenroll it.
Posted on 10-31-2024 01:37 PM
Couldn't edit my response. This is the script for pulling the ID (Hardcoded the Serial Number and commented out the other script because this is for a different machine than I'm debugging the script with)
# Get Mac serial number
#serialNumber=`system_profiler SPHardwareDataType | awk '/Serial/ {print $4}'`
serialNumber="H4HRPKVFH3"
echo "Mac serial: $serialNumber"
# Curl to get Mac Jamf ID. Adding text()' will just return the Jamf ID without bracked info.
# determine Jamf Pro device id
deviceID=$(curl -s -H "Accept: text/xml" -H "Authorization: Bearer ${bearer_token}" ${JamfProURL}/JSSResource/computers/serialnumber/"$serialNumber" | xmllint --xpath '/computer/general/id/text()' -)
echo "Jamf ID: $deviceID"
This is the output
Mac serial: H4HRPKVFH3
Jamf ID: 7744
Posted on 10-31-2024 01:52 PM
That should work. Any chance the Mac you're trying to u-manage is already un-managed?
Posted on 10-31-2024 01:53 PM
No I'm watching like a hawk next to me.
When I ran the unmanage command with the hardcoded deviceID (7744), it worked and all the profiles disappeared and jamf couldn't do anything.
I re-enrolled it fine, ran the command again with the variable $deviceID and it doesn't work
Posted on 10-31-2024 02:01 PM
Running -v with curl (should've done that before)
Its the variable. Its not passing into curl
* Host [REDACTED].jamfcloud.com:443 was resolved.
* IPv6: (none)
* IPv4: [REDACTED]
* Trying [REDACTED]:443...
* Connected to [REDACTED].jamfcloud.com ([REDACTED]) port 443
* ALPN: curl offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
* CAfile: /etc/ssl/cert.pem
* CApath: none
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-AES128-GCM-SHA256 / [blank] / UNDEF
* ALPN: server accepted h2
* Server certificate:
* subject: CN=*.jamfcloud.com
* start date: Jan 3 00:00:00 2024 GMT
* expire date: Feb 1 23:59:59 2025 GMT
* subjectAltName: host "[REDACTED].jamfcloud.com" matched cert's "*.jamfcloud.com"
* issuer: C=US; O=Amazon; CN=Amazon RSA 2048 M02
* SSL certificate verify ok.
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://[REDACTED].jamfcloud.com/JSSResource/computercommands/command/UnmanageDevice/id/
* [HTTP/2] [1] [:method: POST]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: [REDACTED].jamfcloud.com]
* [HTTP/2] [1] [:path: /JSSResource/computercommands/command/UnmanageDevice/id/]
* [HTTP/2] [1] [user-agent: curl/8.7.1]
* [HTTP/2] [1] [accept: */*]
* [HTTP/2] [1] [authorization: Bearer [REDACTED]
> POST /JSSResource/computercommands/command/UnmanageDevice/id/ HTTP/2
> Host: [REDACTED].jamfcloud.com
> User-Agent: curl/8.7.1
> Accept: */*
> Authorization: Bearer [REDACTED]
>
* Request completely sent off
< HTTP/2 404
< date: Thu, 31 Oct 2024 20:58:36 GMT
< content-type: text/html;charset=UTF-8
< content-length: 439
< x-frame-options: DENY
< x-content-type-options: nosniff
< cache-control: no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0
< content-security-policy: default-src 'self' 'unsafe-inline' 'unsafe-eval' data: blob: *.jamf.net *.jamf.build *.jamfcloud.com *.jamf.com *.jamfnebula.com *.jamfsoftware.com *.jamf.io *.inf.jamf.one *.jamfnimbus.cloud *.amazonaws.com *.mzstatic.com *.googleapis.com *.gstatic.com *.googletagmanager.com *.zoominsoftware.io *.nr-data.net *.newrelic.com *.youtube.com *.pendo.io; frame-ancestors 'self' *.jamf.net *.jamf.build *.jamfcloud.com app.pendo.io
< permissions-policy: geolocation=(), fullscreen=(self)
< referrer-policy: strict-origin-when-cross-origin
< vary: Origin
< vary: Access-Control-Request-Method
< vary: Access-Control-Request-Headers
< accept-ranges: bytes
< server: Jamf
< x-xss-protection: 0
< strict-transport-security: max-age=63072000; includeSubDomains;
< set-cookie: jpro-ingress=1323a41cff8ce6db; path=/; HttpOnly; Secure; SameSite=None
<
<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;">Not Found</p>
<p>The server has not found anything matching the request URI</p>
<p>You can get technical details <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.5">here</a>.<br>
Please continue your visit at our <a href="/">home page</a>.
</p>
</body>
</html>
* Connection #0 to host [REDACTED].jamfcloud.com left intact
Posted on 11-01-2024 08:12 AM
Well I got it working showhow. Guess it was just tweaking with the variable until it starts to work.
# Get Mac serial number
serialNumber=`system_profiler SPHardwareDataType | awk '/Serial/ {print $4}'`
echo "Mac serial: $serialNumber"
# Curl to get Mac Jamf ID. Adding text()' will just return the Jamf ID without bracked info.
# determine Jamf Pro device id
deviceID=$(curl -s -H "Accept: text/xml" -H "Authorization: Bearer ${bearer_token}" ${JamfProURL}/JSSResource/computers/serialnumber/"$serialNumber" | xmllint --xpath '/computer/general/id/text()' -)
echo "Jamf ID: $deviceID"
# Remove Jamf Framework
echo "Removing Jamf Framework..."
/usr/local/bin/jamf removeFramework
# Curl to send command to remove MDM profile from the Mac
echo "Removing Jamf MDM via CURL $JamfProURL/JSSResource/computercommands/command/UnmanageDevice/id/$deviceID"
curl -v -X POST --header "Authorization: Bearer $bearer_token" "$JamfProURL/JSSResource/computercommands/command/UnmanageDevice/id/$deviceID"
exit 0
So there's the code I'm using in case someone else has a similar issue or If I run into this again.
Posted on 11-01-2024 07:43 AM
Hi @cyberotter ,
You can try with the script below. You need to have basic auth allowed for API for this script to work else you can modify for bearer token.
https://github.com/kc9wwh/removeJamfProMDM/blob/master/removeMDM.sh
Thanks.
Posted on 11-01-2024 08:10 AM
Unfortunately, our organization has turned off Basic API usage, so that broke a lot of our old scripts. I started using Bearer tokens and got most things to work with just a couple extra steps.
# As of JamfPro V 11.5.0, Basic Token is disabled for security. We have to use the API Token above to create a bearer token.
# Retrieve Bearer Token using APIToken. This is a shortlived token.
bearer_token_response=$(curl -s --request POST \
--url "$JamfProURL/api/v1/auth/token" \
--header "Authorization: Basic $APIToken" \
--header "Accept: application/json")
#echo "Bearer Token Response: $bearer_token_response"
# Extract the Bearer token from the response
bearer_token=$(echo $bearer_token_response | awk -F'"token" : "' '{print $2}' | awk -F'"' '{print $1}')
#echo "Bearer Token: $bearer_token"