Posted on 11-07-2017 06:17 AM
I can see my managed preferences being targeted to the computers in their management tab but I can't find the preferences themselves anymore.
Solved! Go to Solution.
Posted on 11-07-2017 02:09 PM
Jamf support sent me a message as to how I could access what I need to so I can remove them.
Posted on 11-08-2017 04:26 AM
You can remove managed preferences using the API;
First go to your API page and use the GET /managedpreferenceprofiles button to list all your managed preferences. If you want to delete one of the preferences make a note of the ID and use the following command to remove this managed preference
for example: if you want to delete ID number 1
curl -k -u API_USERNAME:API_PASSWORD https://yourjamfserver.jamfcloud.com/JSSResource/managedpreferenceprofiles/id/1 -X Delete
Posted on 11-07-2017 06:37 AM
Hello @Asnyder
http://docs.jamf.com/10.0.0/jamf-pro/release-notes/Deprecations_and_Removals.html
Managed Preferences—Support for managed preferences has been removed. It is recommended that you use macOS configuration profiles to define settings and restrictions for computers and users.
Apple has been deprecating MCX (Managed Preferences) for some time now.
Posted on 11-07-2017 06:41 AM
@david.thornton I understand the removal of it, but I can still see it being scoped to devices (I scope by department). I don't have any way to remove the scoping unless it's just a bug and it isn't actually scoping to machines anymore. So if I add devices I'm unsure if the preferences will still scope to any new devices or not.
Posted on 11-07-2017 07:05 AM
Also be aware that config profiles are not 100% reliable. As an example make a com.apple.finder.plist that unselects the Show Icon Preview checkbox.
Placing it in the User Template will work 100% of the time in unselecting the Show Icon Preview, however if you use the exact same plist and convert it to a config profile the Show Icon Preview checkbox is selected everytime.
Not good for Apple to recommend (i.e., force) config files if they are not 100% reliable.
Posted on 11-07-2017 07:53 AM
@Cornoir I use scripts for a lot of things but was hoping to move towards config profiles for simplicity and ease of use.
Posted on 11-07-2017 02:09 PM
Jamf support sent me a message as to how I could access what I need to so I can remove them.
Posted on 11-08-2017 03:02 AM
That's great, but we have to ask on a case by case basis? Will contact them, Thanks
Posted on 11-08-2017 04:26 AM
You can remove managed preferences using the API;
First go to your API page and use the GET /managedpreferenceprofiles button to list all your managed preferences. If you want to delete one of the preferences make a note of the ID and use the following command to remove this managed preference
for example: if you want to delete ID number 1
curl -k -u API_USERNAME:API_PASSWORD https://yourjamfserver.jamfcloud.com/JSSResource/managedpreferenceprofiles/id/1 -X Delete
Posted on 11-08-2017 11:45 AM
@macbofh I didn't even think about using the api. Good call.
Posted on 11-16-2017 03:30 PM
Be careful to get the correct URL, I tried it @macbofh's way, and didn't get the address for our hosted JAMF Pro correct, make sure JSSResource is at the topmost level of the URL you are using to access your MDM instance.
Posted on 12-05-2017 11:44 AM
FYI - MCX is a persistent thing and just deleting or un-scopping them them via the GUI or the API will not remove the settings from the computers that have installed them.
The only way to reverse settings applied via MCX is to modify the MCX payload and apply the opposite (set True to False or 1 to 0, etc) or change the "Level" from its existing setting; e.g. "User Level at Every Login" (often), "User Level at Next Login Only" (once), "User Level Enforced" (always), "Computer Level Enforced" (always w/ state_metadata saying System Level Enforced) to "Make this Preference Unmanaged" (unset).
Often, once, and always at the keys that would be shown via the API that would need to be changed to unset and the the computers in scope would need to apply those settings either via startup/login/logout management framework scripts or running 'jamf mcx' or 'jamf mcx -username $username' depending on if the settings are computer level or user level respectively.
Also, dont follow old instructions floating around for deleting MCX locally where it has you delete "/Library/Managed Preferences/" as that is SIP protected in 10.13 and prior to that, deleting the folder would wipe out Configuration Profile settings as thats where Config Profiles store the plists since its built off of MCX.
Posted on 12-11-2017 07:43 AM
Here is a script that a coworker made that will modify all MCX payloads in your JSS via the API and turn all the enforced settings of Often, Once, and Always to Unset. Just deleting the MCX settings from the JSS will leave your computers with all the previous MCX settings and doesnt solve the problem.
Once this is done you will still have to have computers download those changes by running 'jamf mcx' and 'jamf mcx -username $username' for system and user level settings respectively. You may already have your management framework startup and login scripts set to enforce MCX so these commands would be ran at after a restart and login.
Save it as a .py and give it a go.
#!/usr/bin/python
# -*- coding: utf-8 -*-
####################################################################################################
#
# Copyright (c) 2017, JAMF Software, LLC. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the JAMF Software, LLC nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY JAMF SOFTWARE, LLC "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL JAMF SOFTWARE, LLC BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
####################################################################################################
#
# SUPPORT FOR THIS PROGRAM
#
# This program is distributed "as is" by JAMF Software, LLC.
#
####################################################################################################
#
# DESCRIPTION
# This script was designed to update all managed preference profiles, setting their
# enforcement level to "unmanaged"
#
####################################################################################################
#
# HISTORY
#
# Version: 1.0
#
# - Created by Sam Fortuna on Dec. 6, 2017
#
#####################################################################################################
#
# DEFINE VARIABLES & READ IN PARAMETERS
#
#####################################################################################################
#
# HARDCODED VALUES SET HERE
#
jss_host = "" #Example: 127.0.0.1 if run on server
jss_port = 8443
jss_path = "" #Example: "jss" for a JSS at https://www.company.com:8443/jss
jss_username = ""
jss_password = ""
##DONT EDIT BELOW THIS LINE
import sys
import json
import httplib
import base64
import urllib2
import string
##Computer Object Definition
class MCX:
id = -1
##Check variable
def verifyVariable(name, value):
if value == "":
print "Error: Please specify a value for variable "" + name + """
sys.exit(1)
## the main function.
def main():
verifyVariable("jss_host",jss_host)
verifyVariable("jss_port",jss_port)
verifyVariable("jss_username",jss_username)
verifyVariable("jss_password",jss_password)
mcx=grabMCXIDs()
updateMCX(mcx)
##Grab and parse the MCX and return them in an array.
def grabMCXIDs():
mcx=[];
## parse the list
for MCXListJSON in (getMCXListFromJSS()["managed_preference_profiles"]):
m = MCX()
m.id = MCXListJSON.get("id")
mcx.append(m)
print "Found " + str(len(mcx)) + " MCX Profiles."
return mcx
##Create a header for the request
def getAuthHeader(u,p):
# Compute base64 representation of the authentication token.
token = base64.b64encode('%s:%s' % (u,p))
return "Basic %s" % token
##Download a list of all MCX from the JSS API
def getMCXListFromJSS():
print "Getting MCX list from the JSS..."
headers = {"Authorization":getAuthHeader(jss_username,jss_password),"Accept":"application/json"}
try:
conn = httplib.HTTPSConnection(jss_host,jss_port)
conn.request("GET",jss_path + "/JSSResource/managedpreferenceprofiles",None,headers)
data = conn.getresponse().read()
conn.close()
jsonData = json.loads(data)
return jsonData
except httplib.HTTPException as inst:
print "Exception: %s" % inst
sys.exit(1)
except ValueError as inst:
print "Exception decoding JSON: %s" % inst
sys.exit(1)
##Loop to submit the updates for all MCX profiles, and track progress
def updateMCX(mcx):
##Parse through each device and submit the command to update inventory
for index, profile in enumerate(mcx):
percent = "%.2f" % (float(index) / float(len(mcx)) * 100)
print str(percent) + "% Complete"
submitDataToJSS(profile)
print "100.00% Complete"
##Get data for individual MCX Profile
def submitDataToJSS(Profile):
headers = {"Authorization":getAuthHeader(jss_username,jss_password),"Accept":"application/xml"}
try:
print "Setting MCX Profile ID %s to unmanaged" % Profile.id
MCXdata = None
conn = httplib.HTTPSConnection(jss_host,jss_port)
conn.request("GET",jss_path + "/JSSResource/managedpreferenceprofiles/id/" + str(Profile.id),None,headers)
MCXdata = conn.getresponse().read()
conn.close()
MCXdata = string.replace(MCXdata,"<string>always</string>","<string>unset</string>")
MCXdata = string.replace(MCXdata,"<string>often</string>","<string>unset</string>")
MCXdata = string.replace(MCXdata,"<string>once</string>","<string>unset</string>")
##print "Data: %s" % MCXdata
conn.request("PUT",jss_path + "/JSSResource/managedpreferenceprofiles/id/" + str(Profile.id),None,headers)
url = "https://" + str(jss_host) + ":" + str(jss_port) + str(jss_path) + "/JSSResource/managedpreferenceprofiles/id/" + str(Profile.id)
opener = urllib2.build_opener(urllib2.HTTPHandler)
request = urllib2.Request(url,MCXdata)
request.add_header("Authorization", getAuthHeader(jss_username,jss_password))
request.add_header('Content-Type', 'application/xml')
request.get_method = lambda: 'PUT'
opener.open(request)
except httplib.HTTPException as inst:
print " Exception: %s" % inst
except ValueError as inst:
print " Exception submitting PUT XML: %s" % inst
except urllib2.HTTPError as inst:
print " Exception submitting PUT XML: %s" % inst
except:
print " Unknown error submitting PUT XML."
## Code starts executing here. Just call main.
main()
Posted on 07-11-2018 08:03 AM
I fixed a type on the command, but it's not really doing what I had hoped. It might help someone get to where they need to...
oitajg070822:2018-04-23-managed preferences gersteina1$ ./fixup.py
Getting MCX list from the JSS...
Exception decoding JSON: No JSON object could be decoded
I was able to just play with the curl command and eventually stumbled on using:
curl -k -u USERNAME:'PASSWORD' https://JSS_URL/JSSResource/managedpreferenceprofiles/id/ID_NUM_TO_DELETE -H 'MCXdata = <string>unset</string>'
But if I can save someone else some time....
Posted on 07-27-2018 11:13 AM
I was wrong - my curl command had no effect. The python script isn't working either.
I'm a little lost in the API - if I wanted to change an existing MCX so I can undo it and then delete it, what's the best way to go about it?
Posted on 07-30-2018 05:19 AM
@gersteina1 - what do you have set for jss_host, jss_port, and jss_path?
Should be something like the following unless you have a multi-context environment.
jss_host = "your.jamf.server" #Example: 127.0.0.1 if run on server
jss_port = 8443 # default port if locally hosted, 443 is default for jamfcloud hosted
jss_path = "https://your.jamf.server:8443" # no trailing forward slash
Posted on 07-30-2018 06:36 AM
@leslie I had "https://" in the jss_host, updated that, and tried to re-run - and got this:
Getting MCX list from the JSS...
Found 27 MCX Profiles.
0.00% Complete
Setting MCX Profile ID 23 to unmanaged
Unknown error submitting PUT XML.
3.70% Complete
Setting MCX Profile ID 26 to unmanaged
Unknown error submitting PUT XML.
7.41% Complete
Setting MCX Profile ID 24 to unmanaged
Unknown error submitting PUT XML.
11.11% Complete
...
Setting MCX Profile ID 27 to unmanaged
Unknown error submitting PUT XML.
100.00% Complet
On the other hand, I had some great success with CocoaRestClient, so I'm going to wrap things up with that - and hopefully write it up so others can take advantage of my learning process.
Posted on 03-22-2019 11:59 AM
Just wanted to share, not sure if it was the difference in versioning or what but macbofh's command was throwing an error for me. I was able to delete the managed preference successfully by changing it to:
curl -XDELETE -u username:password https://yourinstance.jamfcloud.com/JSSResource/managedpreferenceprofiles/id/1 -H "accept: application/xml"
Posted on 02-15-2023 04:48 PM
Thank you for this, worked like a charm to delete some legacy managed preferences I noticed were still getting pushed to computers. It's strange how the legacy API GUI allows you to do do all managedpreferenceprofiles commands except delete.