-
Notifications
You must be signed in to change notification settings - Fork 30
JNUC2019 Intro and Overview
Jamf Pro's Classic API provides RESTful, programmatic access to much of what's available in the Jamf Pro web interface, in either JSON or XML format.
While the API's existence is a boon for automating lots of Jamf Pro-related tasks, using it via bash scripts can be unwieldy, hard to grasp, and difficult to troubleshoot and maintain.
Take, for example, the task of changing the assigned user for all computers in a smart group
bash
GROUP_NAME='myGroupName'
NEW_COMPUTER_USER='jbleaux'
NEW_COMPUTER_USER_REAL_NAME='Jeaux Bleaux'
API_USER="api_username"
read -p "API pw for $API_USER: " API_PW
API_URL_BASE="https://jss.server:8443/JSSResource"
raw_group_xml=`curl -H 'Accept: application/xml' -sk -u "${API_USER}:${API_PW}" -X GET "${API_URL_BASE}/computergroups/name/${GROUP_NAME}"`
member_count=`echo "$raw_group_xml" | xmllint --xpath 'count(/computer_group/computers/computer)' -`
for (( i=1; i <= $member_count; i++ )); do
computer_id=`echo "$raw_group_xml" | xmllint --xpath "/computer_group/computers/computer[$i]/id/text()" -`
change_xml="<computer><location><username>$NEW_COMPUTER_USER</username><realname>$NEW_COMPUTER_USER_REAL_NAME</realname></location></computer>"
curl -H 'Content-Type: application/xml' -u "${API_USER}:${API_PW}" -X PUT "${API_URL_BASE}/computers/id/${computer_id}" -d "$change_xml"
done
ruby using ruby-jss
require 'ruby-jss'
GROUP_NAME = 'myGroupName'
NEW_COMPUTER_USER = 'jbleaux'
NEW_COMPUTER_USER_REAL_NAME = 'Jeaux Bleaux'
JSS.api.connect server: 'jss.server', user: 'api_username', pw: :prompt
computer_group = JSS::ComputerGroup.fetch name: GROUP_NAME
computer_group.member_ids.each do |comp_id|
computer = JSS::Computer.fetch id: comp_id
computer.username = NEW_COMPUTER_USER
computer.real_name = NEW_COMPUTER_USER_REAL_NAME
computer.save
end
Which one would your mother understand more easily?
Not only your mother, which one will you understand more easily in 2 years, when you need to make some changes to the script or adapt it for some other purpose? Or your co-workers who need to work with it while you're on vacation trekking in the Himalayas?
When using ruby-jss, you don't have to worry about the details of the connection headers, insecure use of the password on a command-line, parsing or formatting XML or JSON - All of that is handled 'under the hood' for you. You can focus on the objects in your JSS - the computers, devices, groups, policies, packages, profiles, and so on. Your code will reflect them and their attributes at a conceptual level, increasing the writability, readability, and maintainability of your code.
Ruby's syntax may be a bit different from bash, but it isn't hard to learn, especially when you have API tasks to automate.
Not only will it be easier to write programs to automate repeated tasks, you can also use ruby-jss with Interactive Ruby, a.k.a. irb
to act as a sort of 'shell' to your Jamf Pro server, allowing you to easily perform on-off tasks using the Classic API
Today we're going to do just that.
We'll use irb
and ruby-jss to connect to a Jamf Pro server and do things in realtime.
The things we do in irb are directly translatable to writing programs to run as needed. Just like bash code can be run live in a shell, or executed from a file, so can ruby be run live in irb, or exectuted from a file; the code is the same in both situations.
Here's what we'll cover:
- installing ruby-jss and launching irb
- ruby basics
- collections: Arrays & Hashes
- iterators
- ruby-jss basics
- connecting to the API
- listing objects
- fetching objects
- changing and updating objects
- deleting objects
- real-life examples
- updating extension attribute values
- disabling all policies RIGHT NOW!!
- ...
- security considerations
- QuickLook at the documentation, and how to read it.
More advanced stuff we won't cover in the lab, but should be mentioned:
- Client-side coding
- Scoping
- Group and Search criteria
- Multiple simultaneous API connections