I'm trying to send a command for a group of computers to unmanage them via the JSS API. Using Python, I think I've got it all built out, just I'm not sure if I'm passing the correct XML for the JSS to process the command. Could someone take a look and let me know if this is correct?
I'm using this API command, where you could replace "myjssURL" with yours:
The thing I'm most unclear on is exactly what to pass in for the postXML. It says the one parameter is the id.
jss_api_base_url='https://myjssURL/JSSResource' comp_id = '1234' reqStr = jss_api_base_url + '/computercommands/command/UnmanageDevice/id/' + comp_id postXML = "<id>" + comp_id + "</id>" request = urllib2.Request(reqStr) request.add_header('Authorization', 'Basic ' + base64.b64encode(username + ':' + password)) # POST request.add_header('Content-Type', 'text/xml') request.get_method = lambda: 'POST' response = urllib2.urlopen(request, postXML)
I don't think that's the correct xml you have there. Usually the way it works is you'd want to pull down an existing computer record and examine the tag structure for that computer, and then build the xml file to match the structure, with the one field you want to update or use as the criteria included within it.
So looking at an existing Mac record, it looks something like this
<computer> <general> <id>1000</id> [bunch of other xml stuff here] </general> </computer>
Using that as a guide, something like this would likely be what you need to use
<computer> <general> <id>1000</id> </general> </computer>
IOW, you can't exclude the additional higher level xml tags when submitting an xml to use for this purpose. It won't be able to use it with just <id> alone.
My python script ended up being this, and it turns out I just needed to send it to the API computer object based on the computer ID.
jss_api_base_url='https://myjssURL/JSSResource' comp_id = '434' putStr = jss_api_base_url + '/computers/id/' + comp_id putXML = "<computer><general><remote_management><managed>false</managed></remote_management></general></computer>" request = urllib2.Request(putStr) request.add_header('Authorization', 'Basic ' + base64.b64encode(username + ':' + password)) # PUT request.add_header('Content-Type', 'text/xml') request.get_method = lambda: 'PUT' response = urllib2.urlopen(request, putXML)
So, if your JSS computer id is, say, 434.
The URL you'd send the request to is: https://your-jss-url/JSSResource/computers/id/434
With the following XML. And bingo, computer is unmanaged, but kept all inventory information.
<computer> <general> <remote_management> <managed>false</managed> </remote_management> </general> </computer>
@jkuo That's great, except that @brad actually had the correct answer for you. I didn't notice it, but it seems if you use the original command URL you were playing with to do an unmanage, all you should need to PUT is the URL with the correct JSS computer ID. IOW, a URL like:
1000 is the JSS' computer ID. The above, in theory, should be enough to do the unmanage, since that's the specific URL you're using as shown above.
I would try it that way since that seems vastly simpler than building the correct xml and PUT'ing it back up to the JSS.
Note that I have not tested this out, but looking at the API, it does seem like that specific address will do all the heavy lifting for you.
@mm2270 - Interesting. What would I send along with the post, a blank XML, or nothing at all?
I tried it both ways, with a blank XML, I got a 500 error, and with no XML at all, I get a successful response, but nothing changes.
Building the XML to set "managed" to false isn't too bad, and it's repeatable for me once I got the XML right (just one additional line of code compared to sending the POST to with the unmanage command.)
Nothing at all should be needed. The URL itself is supposed to be designed to do the unmanage. It really should only need the ID for the computer that you want to unmanage. If its not doing the unmanage, then maybe its not functional or something is broken. Might be worth sending a quick email to your JAMF rep so they are aware (they may already be aware, or they will have the right answer on how to use it)
There's nothing wrong with doing it with the xml file, so if that's working and the other way isn't, then just ignore me :) But I would be curious as to how to correctly use those URLs, since I don't have much experience with them myself. I might play with that and see what the deal is.
Thanks. It's probably a configuration thing or user error on my part. I'm also doing this on a sandbox, so I haven't fully configured everything on it, so perhaps I'm missing something there. For now, the PUT + XML method does what I need it to do in prod, so I'll revisit it later. If you do figure it out, do let me know, as I'm sure that'll be helpful for me in the future.
@jkuo - Mind sharing your final code? I am looking for a way to automate or streamline the process stale machines to an Unmanaged state; I do this on a weekly basis and would be a great timesaver and a great place to get into API and maybe tweak it down the line!
@benducklow - I've got the green light and am cleaning it all up and should have it ready to go early next week. Using the script, you can type:
casper unmanagecomputer 1235
where 1235 is the JSS ID of the computer. Or you can load up a csv file with a bunch of JSS computer IDs and do it en masse. I'll keep you posted, sorry for the delay!
@benducklow - It's up!
I've tried to document it well and make the setup as smooth as possible, but let me know if you run into any trouble.
It does just a handful of things at the moment: