Skip to content

Using the API

pythoninthegrass edited this page Feb 18, 2022 · 1 revision

Using the API

The API script interacts with Jamf using the get, post, put, and delete commands in combination with the API resources. To see all of your resources, go to the following URL on your server. https://example.com:8443/api

Python Interpreter

The python-jamf supported API's can be accessed with the Python interactive interpreter. The Python interpreter can be invoked by typing the command "python3" without any parameter followed by the "return" key at the shell prompt:

python3

Import Modules

Python code in one module gains access to the code in another module by the process of importing it. For this example, we will import pprint to output data and jamf to access the supported API's.

from pprint import pprint
import jamf
api = jamf.API()

Getting Data

The API get method downloads the associated data from the Jamf Pro server. If you store it in a variable, it does not update itself. If you make changes on the server, you’ll need to run the API to get updated data.

Get any information from your Jamf Pro server using the classic API endpoints. This includes nested dictionaries.

pprint(api.get('accounts'))
pprint(api.get('buildings'))
pprint(api.get('categories'))
pprint(api.get('computergroups'))
pprint(api.get('computers'))
pprint(api.get('departments'))
pprint(api.get('licensedsoftware'))
pprint(api.get('networksegments'))
pprint(api.get('osxconfigurationprofiles'))
pprint(api.get('packages'))
pprint(api.get('patches'))
pprint(api.get('policies'))
pprint(api.get('scripts'))

All Categories

Get all categories and work with the nested dictionaries

categories = api.get('categories')['categories']['category']
category_names = [x['name'] for x in categories]
print(f"first category: {category_names[0]}")
pprint(category_names)

Computer Management Information

This example demonstrates using an id in the get request:

computers = api.get('computers')['computers']['computer']
pprint(computers[0])
pprint(api.get(f"computermanagement/id/{computers[0]['id']}"))
pprint(api.get(f"computermanagement/id/{computers[0]['id']}/subset/general"))

Computer Groups with Filtering

Getting computer groups and filtering using list comprehension filtering.

computergroups = api.get('computergroups')['computer_groups']['computer_group']
smartcomputergroups = [i for i in computergroups if i['is_smart'] == 'true']
pprint(smartcomputergroups)
staticcomputergroups = [i for i in computergroups if i['is_smart'] != 'true']
pprint(staticcomputergroups)
computergroupids = [i['id'] for i in computergroups]
pprint(computergroupids)

Posting Data

Creating Static Computer Group

When creating a new static computer group, the id in the url ("1") is ignored and the next available id is used. The name in the url ("ignored") is also ignored and the name in the data ("realname") is what is actually used with the static computer group.

import json
api.post("computergroups/id/1",json.loads( '{"computer_group": {"name": "test", "is_smart": "false", "site": {"id": "-1", "name": "None"}, "criteria": {"size": "0"}, "computers": {"size": "0"}}}' ))
api.post("computergroups/name/ignored",json.loads( '{"computer_group": {"name": "realname", "is_smart": "false", "site": {"id": "-1", "name": "None"}, "criteria": {"size": "0"}, "computers": {"size": "0"}}}' ))

Updating Data

Change Computer Group Realname

This changes the group "realname" created above to "new name".

import json
api.put("computergroups/name/realname",json.loads( '{"computer_group": {"name": "new name", "is_smart": "false", "site": {"id": "-1", "name": "None"}, "criteria": {"size": "0"}, "computers": {"size": "0"}}}' ))
computergroups = api.get('computergroups')['computer_groups']['computer_group']
newgroup = [i for i in computergroups if i['name'] == 'new name']

And this is how to change the computer group name using the id.

api.put(f"computergroups/id/{newgroup[0]['id']}",json.loads( '{"computer_group": {"name": "newer name", "is_smart": "false", "site": {"id": "-1", "name": "None"}, "criteria": {"size": "0"}, "computers": {"size": "0"}}}' ))

Deleting Data

The following example deletes the two groups we just created above:

api.delete("computergroups/name/test")
api.delete(f"computergroups/id/{newgroup[0]['id']}")

Updating Policies En Masse

This is where the real power of python-jamf comes in.

Update Polices with Custom Triggers

The following example searches all policies for the custom trigger "update_later" and replaces it with "update_now".

#!/usr/bin/env python3

import jamf

api = jamf.API()
all_policies = api.get('policies')['policies']['policy']
for policy_hook in all_policies:
    policy = api.get(f"policies/id/{policy_hook['id']}")
    name = policy['policy']['general']['name']
    custom_trigger = policy['policy']['general']['trigger_other']
    print(f"Working on {name}")
    if (custom_trigger == "update_later"):
        policy['policy']['general']['trigger_other'] = "update_now"
        api.put(f"policies/id/{policy_hook['id']}", policy)
        print(f"Changed custom trigger from {custom_trigger} to update_now")

Update Polices with Custom Triggers via File

The next example prints out the code you'd need to enter into a python3 interpreter to set the custom_triggers. Save the output of this script to a file, then edit the file with the custom triggers you want for each item. Delete the items you don't want to change.

#!/usr/bin/env python3

import jamf

api = jamf.API()
all_policies = api.get('policies')['policies']['policy']

print("""#!/usr/bin/env python3

import jamf

api = jamf.API()
""")

for policy_hook in all_policies:
    policy = api.get(f"policies/id/{policy_hook['id']}")
    custom_trigger = policy['policy']['general']['trigger_other']
    print(f"print(f\"Working on {policy['policy']['general']['name']}\")\n"
          f"policy = api.get(\"policies/id/{policy_hook['id']}\")\n"
          f"policy['policy']['general']['trigger_other'] = "
          f"\"{policy['policy']['general']['trigger_other']}\"\n"
          f"api.put(\"policies/id/{policy_hook['id']}\", policy)\n\n")

Create Custom Triggers Script

Save the script named "custom_triggers_1.py" with the following commands:

./custom_triggers_1.py > custom_triggers_2.py
chmod 755 custom_triggers_2.py

Edit Custom Triggers Script

Then edit "custom_triggers_2.py" with the custom triggers you want (and remove what you don't want to modify).

Then run "custom_triggers_2.py" script to make modifications.

Categories

Output All Categories

Here is an example of how to output all the categories from your Jamf Pro server:

from jamf.category import Categories
allcategories = Categories()
allcategories.names()
allcategories.ids()
allcategories.categoryWithName("Utilities")
allcategories.categoryWithId(141)

for item in allcategories:
    repr(item)

category = Categories().find("Utilities")
repr(category)
category = Categories().find(141)
repr(category)

Clone this wiki locally