-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial release of SCL JAMF EA Collection.
- Loading branch information
Todd McDaniel
committed
Nov 24, 2017
1 parent
c178cdf
commit 8de1cd4
Showing
14 changed files
with
850 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
# SCL JAMF Pro Extension Attribute collection | ||
|
||
This repository contains a collection of scripts written to perform as extension attributes for the JAMF Pro of management tool. They have been written to suit our specific environment and may need to be modified to operate correctly in others. | ||
|
||
## Contents | ||
|
||
* [Download](#download) - get the .dmg | ||
* [Contact](#contact) | ||
* [System Requirements](#system-requirements) | ||
* [Install](#install) | ||
* [Uninstall](#uninstall) | ||
* [Purpose](#purpose) | ||
* [The Scripts](#scripts) | ||
* [Bluetooth device battery level](#bluetooth-device-battery-level) | ||
* [Disk free space reporter](#disk-free-space-reporter) | ||
* [Estimated date of manufacture](#estimated-date-of-manufacture) | ||
* [Estimated Age](#estimated-age) | ||
* [SMARTmon check](#smartmon-check) | ||
* [Time Machine Status](#time-machine-status) | ||
* [Attached Displays](#attached-displays) | ||
* [External Encrypted Disks](#external-encrypted-disks) | ||
* [Notes](#notes) | ||
* [Update History](#update-history) | ||
|
||
## Download | ||
|
||
[Download the latest installer here!](../../releases/) | ||
|
||
## Contact | ||
|
||
If you have any comments, questions, or other input, either [file an issue](../../issues) or [send us an email](mailto:[email protected]). Thanks! | ||
|
||
## System Requirements | ||
These scripts are designed to be as extension attributes within Casper's JAMF Software Server (JSS). Most of them are written in Python. | ||
|
||
* Python 2.7 (included in MacOS) | ||
|
||
## Install | ||
|
||
These scripts are designed to be copy-and-pasted into a script field in a JSS extension attribute field. | ||
|
||
## Uninstall | ||
|
||
Delete the extension attribute. | ||
|
||
## Purpose | ||
|
||
These scripts are meant to expand the capabilities of JAMF Pro utilizing the Extension Attribute mechanism. JAMF's EA documentation can be found [here](http://docs.jamf.com/10.0.0/jamf-pro/administrator-guide/Computer_Extension_Attributes.html). Using the information returned by an EA, you can build [smart groups](http://docs.jamf.com/10.0.0/jamf-pro/administrator-guide/Smart_Computer_Groups.html). Being a member of a specific smart group can cause additional actions to take place. For example, if the Bluetooth battery level is low, an email could be sent to the user remining them to change the batteries. | ||
|
||
Please feel free to use the code provided to build your own scripts. | ||
|
||
## The scripts | ||
|
||
### Bluetooth device battery level | ||
|
||
Detects keyboards, mice and trackpads. Reports if the battery for a device is less than 30%. | ||
|
||
![Bluetooth battery display](imgs/bluetooth.png) | ||
|
||
|
||
|
||
### Disk free space reporter | ||
|
||
Returns the name, free space, total space and percentage of drive used for each disk attached to a machine. | ||
|
||
![](imgs/diskspace.png) | ||
|
||
|
||
|
||
### Estimated date of manufacture | ||
|
||
Parses a machines serial number to estimate date of manufacture. Borrows heavily from [this script](https://github.com/pudquick/pyMacWarranty/blob/master/getwarranty.py). | ||
|
||
![](imgs/manufacturedate.png) | ||
|
||
|
||
|
||
### Estimated Age | ||
|
||
Similar to the Estimated date of manufacture script, but returns a simpler value. Also borrows heavily from [this script](https://github.com/pudquick/pyMacWarranty/blob/master/getwarranty.py). | ||
|
||
![](imgs/estimatedage.png) | ||
|
||
|
||
|
||
### SMARTmon check | ||
|
||
This EA was written to check all of the disks attached to the local machine. It returns a string containing a single character for each disk. The following table describes the characters and their meanings: | ||
|
||
| Symbol | Meaning | | ||
| ------- | ---------------------------------------- | | ||
| . | No errors detected on that disk. | | ||
| Numeral | An error was detected on that disk. | | ||
| ? | SMARTmon suffered an error while checking that disk. | | ||
|
||
Example reports: | ||
|
||
| Sample reports | | | ||
| -------------- | ---------------------------------------- | | ||
| . | A single disk was checked and no errors were detected. | | ||
| 0... | Four disks were checked and disk0 is returning SMART errors. | | ||
| ..? | Three disks were available and disk2 had a SMARTmon error. | | ||
|
||
Note: This EA requires that [SMARTmon tools](https://www.smartmontools.org/) is installed on each client. | ||
|
||
|
||
|
||
### Time Machine Status | ||
|
||
This EA checks if Time Machine itself is configured, whether a Time Machine volume is available, and the current capacity of the Time Machine volume. | ||
|
||
| Possible returns | Meaning | | ||
| -------------------------------- | ---------------------------------------- | | ||
| Good 10/31 Good 24% free of 713G | Time Machine is configured and working as of 10/31 and the drive has 24% of 713 GB available. | | ||
| Last Backup: 11/02 Not SCL drive | Time Machine is configured and working, but the drive being used is not standard. | | ||
| Not configured, no drive | Time Machine is not configured and no standard drive is attached. | | ||
| Not configured, drive available | Time Machine is not configured and there is a standard drive attached. | | ||
|
||
![](imgs/timemachine.png) | ||
|
||
|
||
|
||
###Attached Displays | ||
|
||
This EA returns the number and information about the displays attached to a machine. | ||
|
||
Here is the data returned for each display: | ||
* Model/Name | ||
* Primary (if set) | ||
* Built-in (if built into machine) | ||
* Retina (if capable) | ||
* Current resolution, refresh rate and maximum resolution | ||
|
||
| Possible returns | Meaning | | ||
| ---------------------------------------- | ---------------------------------------- | | ||
| 3: iMac, Primary, Built-in, Retina, 2048 x 1152 (4096 x 2304); VS248, 1920 x 1080 @ 60 Hz (1920 x 1080); ASUS VS247, 1920 x 1080 @ 60 Hz (1920 x 1080) | 3 displays attached: iMac built-in, VS248 and VS247. | | ||
| 2: iMac, Built-in, Retina, 2560 x 1440 (5120 x 2880); ASUS VH236H, Primary, 1920 x 1080 @ 60 Hz (1920 x 1080) | 2 displays attached: iMac built-in, VH236H primary display. | | ||
| 1: SHARP HDMI, Primary, 1920 x 1080 @ 60 Hz (1920 x 1080) | Single Sharp display. | | ||
|
||
|
||
###External Encrypted Disks | ||
|
||
This EA was written to [assist another JAMF user](https://www.jamf.com/jamf-nation/discussions/25854/inventory-report-external-hard-drive). It returns the number of attached hard drives, and the number of encrypted drives. | ||
|
||
|
||
|
||
## Notes | ||
|
||
|
||
|
||
## Update History | ||
|
||
| Date | Version | Notes | | ||
| ---------- | ------- | ---------------- | | ||
| 2017.11.24 | 1.0.0 | Initial release. | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
#!/usr/bin/python | ||
""" | ||
This should not be blank. | ||
""" | ||
|
||
# Copyright (c) 2017 University of Utah Student Computing Labs. ################ | ||
# All Rights Reserved. | ||
# | ||
# Permission to use, copy, modify, and distribute this software and | ||
# its documentation for any purpose and without fee is hereby granted, | ||
# provided that the above copyright notice appears in all copies and | ||
# that both that copyright notice and this permission notice appear | ||
# in supporting documentation, and that the name of The University | ||
# of Utah not be used in advertising or publicity pertaining to | ||
# distribution of the software without specific, written prior | ||
# permission. This software is supplied as is without expressed or | ||
# implied warranties of any kind. | ||
################################################################################ | ||
|
||
# attached_displays.py ######################################################### | ||
# | ||
# A Python script/Jamf Pro Extension Attribute to inventory and report on | ||
# attached displays. | ||
# | ||
# 1.0.0 2017.09.08 Initial release. tjm | ||
# | ||
################################################################################ | ||
|
||
# Notes ######################################################################## | ||
# | ||
# The output is set up to split three times. Once on ':' will give you the count | ||
# of displays and the description string. And then splitting the description | ||
# string on ':' will give you individual displays. Finally on ',' will give | ||
# features. You can also split the resolution if you need to, for height, | ||
# width, etc. | ||
# | ||
# 2: iMac, Built-in, Retina, 2560 x 1440 (5120 x 2880); ASUS VH236H, Primary, 1920 x 1080 @ 60 Hz (1920 x 1080) | ||
# ^ ^ | ||
# | 1. split on ':" | | ||
# | 2. split on ';' | ||
# Continue spliting on ',' for indiviual features | ||
# Current resolution is displayed, Maximum resolution available in parentheses | ||
# | ||
################################################################################ | ||
|
||
from __future__ import print_function | ||
import subprocess | ||
import plistlib | ||
|
||
|
||
def main(): | ||
""" | ||
This should not be blank. | ||
""" | ||
|
||
count_displays = 0 | ||
master_string = "" | ||
|
||
raw_displays = subprocess.check_output(["system_profiler", "SPDisplaysDataType", "-xml"]) | ||
plist_displays = plistlib.readPlistFromString(raw_displays) | ||
list_of_displays = plist_displays[0]['_items'] | ||
|
||
for item in list_of_displays: | ||
sublist = item['spdisplays_ndrvs'] | ||
count_displays = str(len(sublist)) | ||
|
||
for subitem in sublist: | ||
feature_list = [] | ||
|
||
try: | ||
name_string = subitem['_name'] | ||
except: | ||
name_string = "" | ||
|
||
# Build list of resolution strings | ||
try: | ||
resolution_string = subitem['_spdisplays_resolution'] | ||
except: | ||
resolution_string = "" | ||
|
||
try: | ||
resolution_string = resolution_string + " (" + subitem['_spdisplays_pixels'] + ")" | ||
except: | ||
resolution_string = resolution_string + "" | ||
|
||
# Build list of individual features | ||
try: | ||
display_type = subitem['spdisplays_display_type'] | ||
except: | ||
display_type = "" | ||
|
||
try: | ||
display_main_raw = subitem['spdisplays_main'] | ||
if 'yes' in display_main_raw: | ||
feature_list.append("Primary") | ||
except: | ||
pass | ||
|
||
if 'built' in display_type: | ||
feature_list.append("Built-in") | ||
|
||
if 'retina' in display_type: | ||
feature_list.append("Retina") | ||
|
||
if 'spdisplays_on' in subitem['spdisplays_mirror']: | ||
feature_list.append("Mirrored") | ||
|
||
if feature_list: | ||
output_string = name_string + ", " + ", ".join(feature_list) + ", " + resolution_string | ||
else: | ||
output_string = name_string + ", " + resolution_string | ||
|
||
if master_string: | ||
master_string = master_string + "; " + output_string | ||
else: | ||
master_string = output_string | ||
|
||
master_string = count_displays + ": " + master_string | ||
print("<result>" + master_string + "</result>") | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
#!/usr/bin/python | ||
|
||
# Copyright (c) 2017 University of Utah Student Computing Labs. ################ | ||
# All Rights Reserved. | ||
# | ||
# Permission to use, copy, modify, and distribute this software and | ||
# its documentation for any purpose and without fee is hereby granted, | ||
# provided that the above copyright notice appears in all copies and | ||
# that both that copyright notice and this permission notice appear | ||
# in supporting documentation, and that the name of The University | ||
# of Utah not be used in advertising or publicity pertaining to | ||
# distribution of the software without specific, written prior | ||
# permission. This software is supplied as is without expressed or | ||
# implied warranties of any kind. | ||
################################################################################ | ||
|
||
# bluetooth_device_battery.py ################################################# | ||
# | ||
# A Python script monitor and report Bluetooth device battery levels. | ||
# | ||
# 1.0.0 2016.03.xx Initial release tjm | ||
# | ||
# | ||
# | ||
################################################################################ | ||
|
||
# Notes ######################################################################## | ||
# | ||
# | ||
# | ||
# | ||
# | ||
# | ||
################################################################################ | ||
|
||
from __future__ import print_function | ||
import subprocess | ||
import re | ||
|
||
def main(): | ||
potential_devices = ["AppleBluetoothHIDKeyboard", "BNBTrackpadDevice", "BNBMouseDevice"] | ||
output_string = None | ||
|
||
bluetooth_power_state = subprocess.check_output(["defaults", "read", "/Library/Preferences/com.apple.Bluetooth.plist", "ControllerPowerState"]) | ||
|
||
# exit if bluetooth is off | ||
if "0" in bluetooth_power_state: | ||
quit() | ||
|
||
for device in potential_devices: | ||
raw_output = subprocess.check_output(["/usr/sbin/ioreg", "-r", "-c", device]) | ||
|
||
if raw_output == '': | ||
continue | ||
else: | ||
match = re.search('.*"BatteryPercent" = (.*)\n', raw_output) | ||
|
||
if int(match.group(1)) < 30: | ||
if "AppleBluetoothHIDKeyboard" in device: | ||
device_output = "BlueTooth Keyboard at " + match.group(1) + "%" | ||
elif "BNBTrackpadDevice" in device: | ||
device_output = "BlueTooth Trackpad at " + match.group(1) + "%" | ||
elif "BNBMouseDevice" in device: | ||
device_output = "BlueTooth Mouse at " + match.group(1) + "%" | ||
else: | ||
continue | ||
else: | ||
continue | ||
|
||
if output_string is None: | ||
output_string = device_output | ||
else: | ||
output_string = output_string + " " + device_output | ||
|
||
if output_string is not None: | ||
print("<result>" + output_string + "</result>") | ||
|
||
if __name__ == '__main__': | ||
main() |
Oops, something went wrong.