ruby-jss 4.2.4 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGES.md +28 -0
- data/lib/jamf/api/classic/api_objects/computer.rb +20 -0
- data/lib/jamf/api/classic/api_objects/mdm.rb +439 -247
- data/lib/jamf/api/classic/api_objects/mdm_classic.rb +1416 -0
- data/lib/jamf/api/classic/api_objects/mobile_device.rb +20 -0
- data/lib/jamf/version.rb +1 -1
- data/lib/jamf/zeitwerk_config.rb +1 -0
- metadata +26 -5
|
@@ -2,94 +2,101 @@
|
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the terms set forth in the LICENSE.txt file available at
|
|
4
4
|
# at the root of this project.
|
|
5
|
-
|
|
6
|
-
###
|
|
5
|
+
#
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
module Jamf
|
|
7
|
+
# frozen_string_literal: true
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
#####################################
|
|
9
|
+
module Jamf
|
|
13
10
|
|
|
14
|
-
# This module
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
# Objects mixing in this module MUST:
|
|
18
|
-
#
|
|
19
|
-
# - Define the constant MDM_COMMAND_TARGET - One of:
|
|
20
|
-
# :computers, :computergroups, :mobiledevices, :mobiledevicegroups
|
|
21
|
-
#
|
|
22
|
-
#
|
|
11
|
+
# This module should be mixed in to Jamf::Computer and Jamf::MobileDevice
|
|
12
|
+
# ang Jamf::ComputerGroup and Jamf::MobileDeviceGroup.
|
|
23
13
|
#
|
|
14
|
+
# Those must define the following constants:
|
|
15
|
+
# - MDM_COMMAND_TARGET - one of :computers, :computergroups, :mobiledevices, :mobiledevicegroups
|
|
24
16
|
#
|
|
25
17
|
module MDM
|
|
26
18
|
|
|
19
|
+
# when this module is included, also extend our Class Methods
|
|
20
|
+
def self.included(includer)
|
|
21
|
+
Jamf.load_msg "--> #{includer} is including #{self}"
|
|
22
|
+
includer.extend(ClassMethods)
|
|
23
|
+
end
|
|
24
|
+
|
|
27
25
|
# Constants
|
|
28
26
|
#####################################
|
|
29
27
|
|
|
28
|
+
# TODO: clean up unused constants left over from classic API implementation
|
|
29
|
+
|
|
30
|
+
# JPAPI Resources
|
|
31
|
+
|
|
32
|
+
MDM_COMMAND_RSRC = 'v2/mdm/commands'
|
|
33
|
+
BLANK_PUSH_RSRC = 'v2/mdm/blank-push'
|
|
34
|
+
|
|
35
|
+
# computers are unmanaged via v1/computer-inventory/{id}/remove-mdm-profile
|
|
36
|
+
COMPUTER_INV_RSRC = 'v1/computer-inventory'
|
|
37
|
+
UNMANAGE_COMPUTER_RSRC = 'remove-mdm-profile'
|
|
38
|
+
|
|
39
|
+
# Devices are unmanaged via v2/mobile-devices/{id}/unmanage
|
|
40
|
+
MOBILE_DEVICE_RSRC = 'v2/mobile-devices'
|
|
41
|
+
UNMANAGE_MOBILE_DEVICE_RSRC = 'unmanage'
|
|
42
|
+
|
|
30
43
|
#### target types
|
|
31
44
|
|
|
32
45
|
# These targets are computers
|
|
33
46
|
COMPUTER_TARGETS = %i[computers computergroups].freeze
|
|
34
47
|
|
|
35
|
-
# The API resource for sending computer commands
|
|
36
|
-
COMPUTER_RSRC = 'computercommands'.freeze
|
|
37
|
-
|
|
38
48
|
# These targets are mobile devices
|
|
39
49
|
DEVICE_TARGETS = %i[mobiledevices mobiledevicegroups].freeze
|
|
40
50
|
|
|
41
|
-
# the API resource for sending device commands
|
|
42
|
-
DEVICE_RSRC = 'mobiledevicecommands'.freeze
|
|
43
|
-
|
|
44
51
|
# These targets are groups, and need their member ids expanded for sending commands
|
|
45
52
|
GROUP_TARGETS = %i[computergroups mobiledevicegroups].freeze
|
|
46
53
|
|
|
47
54
|
#### The commands
|
|
48
55
|
|
|
49
56
|
# Both computers & devices
|
|
57
|
+
BLANK_PUSH = 'BlankPush'
|
|
58
|
+
DEVICE_LOCK = 'DEVICE_LOCK'
|
|
59
|
+
ERASE_DEVICE = 'ERASE_DEVICE'
|
|
60
|
+
UNMANGE_DEVICE = 'UnmanageDevice'
|
|
50
61
|
|
|
51
|
-
BLANK_PUSH = 'BlankPush'.freeze
|
|
52
|
-
DEVICE_LOCK = 'DeviceLock'.freeze
|
|
53
|
-
ERASE_DEVICE = 'EraseDevice'.freeze
|
|
54
|
-
UNMANGE_DEVICE = 'UnmanageDevice'.freeze
|
|
55
62
|
# UPDATE_OS = 'UpdateOS'.freeze
|
|
56
63
|
|
|
57
64
|
# computers only
|
|
58
65
|
|
|
59
|
-
DELETE_USER = '
|
|
60
|
-
UNLOCK_USER_ACCOUNT = '
|
|
61
|
-
ENABLE_REMOTE_DESKTOP = '
|
|
62
|
-
DISABLE_REMOTE_DESKTOP = '
|
|
66
|
+
DELETE_USER = 'DELETE_USER'
|
|
67
|
+
UNLOCK_USER_ACCOUNT = 'UNLOCK_USER_ACCOUNT'
|
|
68
|
+
ENABLE_REMOTE_DESKTOP = 'ENABLE_REMOTE_DESKTOP'
|
|
69
|
+
DISABLE_REMOTE_DESKTOP = 'DISABLE_REMOTE_DESKTOP'
|
|
63
70
|
|
|
64
71
|
# devices
|
|
65
72
|
|
|
66
|
-
SETTINGS = '
|
|
67
|
-
CLEAR_PASSCODE = '
|
|
68
|
-
UPDATE_INVENTORY = 'UpdateInventory'
|
|
69
|
-
CLEAR_RESTRICTIONS_PASSWORD = '
|
|
70
|
-
ENABLE_DATA_ROAMING = '
|
|
71
|
-
DISABLE_DATA_ROAMING = '
|
|
72
|
-
ENABLE_VOICE_ROAMING = '
|
|
73
|
-
DISABLE_VOICE_ROAMING = '
|
|
73
|
+
SETTINGS = 'SETTINGS'
|
|
74
|
+
CLEAR_PASSCODE = 'CLEAR_PASSCODE'
|
|
75
|
+
UPDATE_INVENTORY = 'UpdateInventory'
|
|
76
|
+
CLEAR_RESTRICTIONS_PASSWORD = 'CLEAR_RESTRICTIONS_PASSWORD'
|
|
77
|
+
ENABLE_DATA_ROAMING = 'ENABLE_DATA_ROAMING'
|
|
78
|
+
DISABLE_DATA_ROAMING = 'DISABLE_DATA_ROAMING'
|
|
79
|
+
ENABLE_VOICE_ROAMING = 'ENABLE_VOICE_ROAMING'
|
|
80
|
+
DISABLE_VOICE_ROAMING = 'DISABLE_VOICE_ROAMING'
|
|
74
81
|
|
|
75
82
|
# shared ipads only
|
|
76
83
|
|
|
77
|
-
PASSCODE_LOCK_GRACE_PERIOD = '
|
|
84
|
+
PASSCODE_LOCK_GRACE_PERIOD = 'passcodeLockGracePeriod'
|
|
78
85
|
|
|
79
86
|
# supervised devices
|
|
80
87
|
|
|
81
|
-
WALLPAPER = 'Wallpaper'
|
|
82
|
-
DEVICE_NAME = 'DeviceName'
|
|
83
|
-
|
|
84
|
-
RESTART_DEVICE = '
|
|
85
|
-
ENABLE_LOST_MODE = '
|
|
86
|
-
DISABLE_LOST_MODE = '
|
|
87
|
-
DEVICE_LOCATION = 'DeviceLocation'
|
|
88
|
-
PLAY_LOST_MODE_SOUND = '
|
|
89
|
-
ENABLE_APP_ANALYTICS = '
|
|
90
|
-
DISABLE_APP_ANALYTICS = '
|
|
91
|
-
ENABLE_DIAGNOSTIC_SUBMISSION = '
|
|
92
|
-
DISABLE_DIAGNOSTIC_SUBMISSION = '
|
|
88
|
+
WALLPAPER = 'Wallpaper'
|
|
89
|
+
DEVICE_NAME = 'DeviceName'
|
|
90
|
+
SHUT_DOWN_DEVICE = 'SHUT_DOWN_DEVICE'
|
|
91
|
+
RESTART_DEVICE = 'RESTART_DEVICE'
|
|
92
|
+
ENABLE_LOST_MODE = 'ENABLE_LOST_MODE'
|
|
93
|
+
DISABLE_LOST_MODE = 'DISABLE_LOST_MODE'
|
|
94
|
+
DEVICE_LOCATION = 'DeviceLocation'
|
|
95
|
+
PLAY_LOST_MODE_SOUND = 'PLAY_LOST_MODE_SOUND'
|
|
96
|
+
ENABLE_APP_ANALYTICS = 'ENABLE_APP_ANALYTICS'
|
|
97
|
+
DISABLE_APP_ANALYTICS = 'DISABLE_APP_ANALYTICS'
|
|
98
|
+
ENABLE_DIAGNOSTIC_SUBMISSION = 'ENABLE_DIAGNOSTIC_SUBMISSION'
|
|
99
|
+
DISABLE_DIAGNOSTIC_SUBMISSION = 'DISABLE_DIAGNOSTIC_SUBMISSION'
|
|
93
100
|
|
|
94
101
|
#### Groupings of commands
|
|
95
102
|
|
|
@@ -125,7 +132,7 @@ module Jamf
|
|
|
125
132
|
SUPERVISED_DEVICE_COMMANDS = [
|
|
126
133
|
WALLPAPER,
|
|
127
134
|
DEVICE_NAME,
|
|
128
|
-
|
|
135
|
+
SHUT_DOWN_DEVICE,
|
|
129
136
|
RESTART_DEVICE,
|
|
130
137
|
CLEAR_RESTRICTIONS_PASSWORD,
|
|
131
138
|
ENABLE_LOST_MODE,
|
|
@@ -201,10 +208,10 @@ module Jamf
|
|
|
201
208
|
|
|
202
209
|
passcode_lock_grace_period: PASSCODE_LOCK_GRACE_PERIOD,
|
|
203
210
|
|
|
204
|
-
shut_down_device:
|
|
205
|
-
shutdown_device:
|
|
206
|
-
shut_down:
|
|
207
|
-
shutdown:
|
|
211
|
+
shut_down_device: SHUT_DOWN_DEVICE,
|
|
212
|
+
shutdown_device: SHUT_DOWN_DEVICE,
|
|
213
|
+
shut_down: SHUT_DOWN_DEVICE,
|
|
214
|
+
shutdown: SHUT_DOWN_DEVICE,
|
|
208
215
|
|
|
209
216
|
restart_device: RESTART_DEVICE,
|
|
210
217
|
restart: RESTART_DEVICE,
|
|
@@ -241,13 +248,13 @@ module Jamf
|
|
|
241
248
|
### Status
|
|
242
249
|
|
|
243
250
|
# the status to flush for 'pending'
|
|
244
|
-
PENDING_STATUS = 'Pending'
|
|
251
|
+
PENDING_STATUS = 'Pending'
|
|
245
252
|
|
|
246
253
|
# the status to flush for 'failed'
|
|
247
|
-
FAILED_STATUS = 'Failed'
|
|
254
|
+
FAILED_STATUS = 'Failed'
|
|
248
255
|
|
|
249
256
|
# the status to flush for both pending and failed
|
|
250
|
-
PENDINGFAILED_STATUS = 'Pending+Failed'
|
|
257
|
+
PENDINGFAILED_STATUS = 'Pending+Failed'
|
|
251
258
|
|
|
252
259
|
FLUSHABLE_STATUSES = {
|
|
253
260
|
pending: PENDING_STATUS,
|
|
@@ -255,22 +262,22 @@ module Jamf
|
|
|
255
262
|
pending_failed: PENDINGFAILED_STATUS
|
|
256
263
|
}.freeze
|
|
257
264
|
|
|
258
|
-
BLANK_PUSH_RESULT = 'Command sent'
|
|
265
|
+
BLANK_PUSH_RESULT = 'Command sent'
|
|
259
266
|
|
|
260
267
|
# xml elements
|
|
261
268
|
|
|
262
|
-
GENERAL_ELEMENT = 'general'
|
|
263
|
-
COMMAND_ELEMENT = 'command'
|
|
264
|
-
TARGET_ID_ELEMENT = 'id'
|
|
269
|
+
GENERAL_ELEMENT = 'general'
|
|
270
|
+
COMMAND_ELEMENT = 'command'
|
|
271
|
+
TARGET_ID_ELEMENT = 'id'
|
|
265
272
|
|
|
266
|
-
COMPUTER_COMMAND_ELEMENT = 'computer_command'
|
|
267
|
-
COMPUTER_ID_ELEMENT = 'computer_id'
|
|
268
|
-
COMPUTER_COMMAND_UDID_ELEMENT = 'command_uuid'
|
|
273
|
+
COMPUTER_COMMAND_ELEMENT = 'computer_command'
|
|
274
|
+
COMPUTER_ID_ELEMENT = 'computer_id'
|
|
275
|
+
COMPUTER_COMMAND_UDID_ELEMENT = 'command_uuid'
|
|
269
276
|
|
|
270
|
-
DEVICE_COMMAND_ELEMENT = 'mobile_device_command'
|
|
271
|
-
DEVICE_LIST_ELEMENT = 'mobile_devices'
|
|
272
|
-
DEVICE_ID_ELEMENT = 'id'
|
|
273
|
-
DEVICE_COMMAND_STATUS_ELEMENT = 'status'
|
|
277
|
+
DEVICE_COMMAND_ELEMENT = 'mobile_device_command'
|
|
278
|
+
DEVICE_LIST_ELEMENT = 'mobile_devices'
|
|
279
|
+
DEVICE_ID_ELEMENT = 'id'
|
|
280
|
+
DEVICE_COMMAND_STATUS_ELEMENT = 'status'
|
|
274
281
|
|
|
275
282
|
# Mixin Class Methods
|
|
276
283
|
###########################
|
|
@@ -282,13 +289,18 @@ module Jamf
|
|
|
282
289
|
#
|
|
283
290
|
module ClassMethods
|
|
284
291
|
|
|
292
|
+
# when this module is included, also extend our Class Methods
|
|
293
|
+
def self.extended(extender)
|
|
294
|
+
Jamf.load_msg "--> #{extender} is extending #{self}"
|
|
295
|
+
end
|
|
296
|
+
|
|
285
297
|
# Send an MDM command to one or more targets without instantiating them.
|
|
286
298
|
#
|
|
287
|
-
# This general class method, and all the specific ones that
|
|
299
|
+
# This general class method, and all the specific ones that call it, have
|
|
288
300
|
# matching instance methods. Use the class method when you don't have, or
|
|
289
301
|
# don't want to retrieve, instances of all the targets.
|
|
290
302
|
#
|
|
291
|
-
# If you do have an instance
|
|
303
|
+
# If you do have an instance of a target, call the matching instance method
|
|
292
304
|
# to send commands to that specific target.
|
|
293
305
|
#
|
|
294
306
|
# @example send a blank push to mobiledevice id 12 without instantiating:
|
|
@@ -332,119 +344,57 @@ module Jamf
|
|
|
332
344
|
# always 'Command sent' (an error will be raised if there are problems
|
|
333
345
|
# sending)
|
|
334
346
|
#
|
|
335
|
-
def send_mdm_command(targets,
|
|
347
|
+
def send_mdm_command(targets, command_data, api: nil, cnx: Jamf.cnx)
|
|
336
348
|
cnx = api if api
|
|
337
349
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
rsrc = "#{send_command_rsrc}/command/#{command}"
|
|
341
|
-
|
|
342
|
-
targets = raw_targets_to_ids targets, cnx: cnx
|
|
350
|
+
targets = raw_targets_to_mgmt_ids(targets, cnx: cnx)
|
|
351
|
+
targets.map! { |mid| { managementId: mid } }
|
|
343
352
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
REXML::Document.new(cmd_xml).write STDOUT, 2
|
|
349
|
-
puts "\n\nTo rsrc: #{rsrc}"
|
|
350
|
-
end
|
|
351
|
-
|
|
352
|
-
result = cnx.c_post rsrc, cmd_xml
|
|
353
|
-
|
|
354
|
-
if command == BLANK_PUSH
|
|
355
|
-
hash = {}
|
|
356
|
-
targets.each { |t| hash[t] = BLANK_PUSH_RESULT }
|
|
357
|
-
elsif COMPUTER_TARGETS.include? self::MDM_COMMAND_TARGET
|
|
358
|
-
hash = process_computer_xml_result(result)
|
|
359
|
-
elsif DEVICE_TARGETS.include? self::MDM_COMMAND_TARGET
|
|
360
|
-
hash = process_mobiledevice_xml_result(result)
|
|
361
|
-
end
|
|
362
|
-
|
|
363
|
-
hash
|
|
364
|
-
end
|
|
365
|
-
|
|
366
|
-
# Convert the result of senting a computer MDM command into
|
|
367
|
-
# the appropriate hash
|
|
368
|
-
#
|
|
369
|
-
# @param result [String] The raw XML from POSTing a computer command
|
|
370
|
-
#
|
|
371
|
-
# @return (see #send_mdm_command)
|
|
372
|
-
#
|
|
373
|
-
def process_computer_xml_result(result)
|
|
374
|
-
hash = {}
|
|
375
|
-
REXML::Document.new(result).elements[COMPUTER_COMMAND_ELEMENT].each_element do |cmd|
|
|
376
|
-
compid = cmd.elements[COMPUTER_ID_ELEMENT].text.to_i
|
|
377
|
-
udid = cmd.elements[COMPUTER_COMMAND_UDID_ELEMENT].text
|
|
378
|
-
hash[compid] = udid
|
|
379
|
-
end
|
|
380
|
-
hash
|
|
381
|
-
end
|
|
353
|
+
data = {
|
|
354
|
+
clientData: targets,
|
|
355
|
+
commandData: command_data
|
|
356
|
+
}
|
|
382
357
|
|
|
383
|
-
|
|
384
|
-
# the appropriate hash
|
|
385
|
-
#
|
|
386
|
-
# @param result [String] The raw XML from POSTing a device command
|
|
387
|
-
#
|
|
388
|
-
# @return (see #send_mdm_command)
|
|
389
|
-
#
|
|
390
|
-
def process_mobiledevice_xml_result(result)
|
|
391
|
-
hash = {}
|
|
392
|
-
mds = REXML::Document.new(result).elements[DEVICE_COMMAND_ELEMENT].elements[DEVICE_LIST_ELEMENT]
|
|
393
|
-
mds.each_element do |md|
|
|
394
|
-
id = md.elements[DEVICE_ID_ELEMENT].text.to_i
|
|
395
|
-
status = md.elements[DEVICE_COMMAND_STATUS_ELEMENT].text
|
|
396
|
-
hash[id] = status
|
|
397
|
-
end
|
|
398
|
-
hash
|
|
399
|
-
end
|
|
358
|
+
puts "Sending data:\n#{data}" if JSS.devmode?
|
|
400
359
|
|
|
401
|
-
|
|
402
|
-
#
|
|
403
|
-
# @return [String] The API rsrc.
|
|
404
|
-
#
|
|
405
|
-
def send_command_rsrc
|
|
406
|
-
case self::MDM_COMMAND_TARGET
|
|
407
|
-
when *COMPUTER_TARGETS
|
|
408
|
-
COMPUTER_RSRC
|
|
409
|
-
when *DEVICE_TARGETS
|
|
410
|
-
DEVICE_RSRC
|
|
411
|
-
else
|
|
412
|
-
raise Jamf::InvalidDataError, "Unknown MDM command target: #{self::MDM_COMMAND_TARGET}"
|
|
413
|
-
end
|
|
360
|
+
cnx.jp_post MDM_COMMAND_RSRC, data
|
|
414
361
|
end
|
|
415
362
|
|
|
416
363
|
# Convert the targets provided for sending a command into
|
|
417
|
-
# the final list of
|
|
364
|
+
# the final list of computer or mobile device management ids
|
|
418
365
|
#
|
|
419
366
|
# @param targets[String,Integer,Array] See {#send_mdm_command}
|
|
420
367
|
#
|
|
421
368
|
# @param expand_groups[Boolean] Should groups be expanded into member ids?
|
|
369
|
+
# DEPRECATED: this is now automatic based on the class type.
|
|
370
|
+
#
|
|
371
|
+
# @param unmanaged_ok[Boolean] Are unmanaged targets allowed?
|
|
372
|
+
#
|
|
373
|
+
# @param jamf_ids[Boolean] return Jamf ids instead of management ids
|
|
422
374
|
#
|
|
423
375
|
# @param cnx [Jamf::Connection] an API connection to use.
|
|
424
376
|
#
|
|
425
|
-
# @return [Array<Integer>] The ids of the target devices for a command
|
|
377
|
+
# @return [Array<String,Integer>] The ids of the target devices for a command
|
|
426
378
|
#
|
|
427
|
-
def
|
|
379
|
+
def raw_targets_to_mgmt_ids(targets, expand_groups: true, unmanaged_ok: false, jamf_ids: false, api: nil, cnx: Jamf.cnx)
|
|
428
380
|
cnx = api if api
|
|
429
|
-
|
|
430
381
|
targets = targets.is_a?(Array) ? targets : [targets]
|
|
431
382
|
|
|
432
383
|
# flush caches before checking ids and managment
|
|
433
384
|
cnx.flushcache self::RSRC_LIST_KEY
|
|
434
385
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
id = valid_id md, cnx: cnx
|
|
438
|
-
raise Jamf::NoSuchItemError, "No #{self} matches identifier: #{md}" unless id
|
|
386
|
+
target_ids = []
|
|
387
|
+
this_is_a_group_class = GROUP_TARGETS.include?(self::MDM_COMMAND_TARGET)
|
|
439
388
|
|
|
440
|
-
|
|
441
|
-
|
|
389
|
+
targets.each do |ident|
|
|
390
|
+
id = valid_id ident, cnx: cnx
|
|
391
|
+
raise Jamf::NoSuchItemError, "No #{self} matches identifier: #{ident}" unless id
|
|
442
392
|
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
393
|
+
if this_is_a_group_class
|
|
394
|
+
target_ids += fetch(id: id).member_ids
|
|
395
|
+
else
|
|
396
|
+
target_ids << id
|
|
397
|
+
end
|
|
448
398
|
end
|
|
449
399
|
|
|
450
400
|
# make sure all of them are managed, or else the API will raise a 400
|
|
@@ -452,17 +402,74 @@ module Jamf
|
|
|
452
402
|
# Some actions, like flushing MDM commands (see .flush_mdm_commands)
|
|
453
403
|
# are OK on unmanaged machines, so they will specify 'unmanaged_ok'
|
|
454
404
|
unless unmanaged_ok
|
|
405
|
+
# get all managed ids in an array
|
|
455
406
|
all_mgd = map_all_ids_to(:managed, cnx: cnx).select { |_id, mgd| mgd }.keys
|
|
456
407
|
|
|
457
|
-
|
|
408
|
+
target_ids.each do |target_id|
|
|
458
409
|
raise Jamf::UnmanagedError, "#{self} with id #{target_id} is not managed. Cannot send command." unless all_mgd.include? target_id
|
|
459
410
|
end
|
|
460
|
-
end #
|
|
411
|
+
end # unless
|
|
461
412
|
|
|
462
|
-
|
|
413
|
+
# return the jamf ids if requested
|
|
414
|
+
return target_ids if jamf_ids
|
|
415
|
+
|
|
416
|
+
# return the management id for each target
|
|
417
|
+
target_ids.map { |t| management_id t, cnx: cnx }
|
|
463
418
|
end
|
|
464
419
|
|
|
465
|
-
#
|
|
420
|
+
# Convert the result of senting a computer MDM command into
|
|
421
|
+
# the appropriate hash
|
|
422
|
+
#
|
|
423
|
+
# @param result [String] The raw XML from POSTing a computer command
|
|
424
|
+
#
|
|
425
|
+
# @return (see #send_mdm_command)
|
|
426
|
+
#
|
|
427
|
+
# def process_computer_xml_result(result)
|
|
428
|
+
# hash = {}
|
|
429
|
+
# REXML::Document.new(result).elements[COMPUTER_COMMAND_ELEMENT].each_element do |cmd|
|
|
430
|
+
# compid = cmd.elements[COMPUTER_ID_ELEMENT].text.to_i
|
|
431
|
+
# udid = cmd.elements[COMPUTER_COMMAND_UDID_ELEMENT].text
|
|
432
|
+
# hash[compid] = udid
|
|
433
|
+
# end
|
|
434
|
+
# hash
|
|
435
|
+
# end
|
|
436
|
+
|
|
437
|
+
# Convert the result of senting a device MDM command into
|
|
438
|
+
# the appropriate hash
|
|
439
|
+
#
|
|
440
|
+
# @param result [String] The raw XML from POSTing a device command
|
|
441
|
+
#
|
|
442
|
+
# @return (see #send_mdm_command)
|
|
443
|
+
#
|
|
444
|
+
# def process_mobiledevice_xml_result(result)
|
|
445
|
+
# hash = {}
|
|
446
|
+
# mds = REXML::Document.new(result).elements[DEVICE_COMMAND_ELEMENT].elements[DEVICE_LIST_ELEMENT]
|
|
447
|
+
# mds.each_element do |md|
|
|
448
|
+
# id = md.elements[DEVICE_ID_ELEMENT].text.to_i
|
|
449
|
+
# status = md.elements[DEVICE_COMMAND_STATUS_ELEMENT].text
|
|
450
|
+
# hash[id] = status
|
|
451
|
+
# end
|
|
452
|
+
# hash
|
|
453
|
+
# end
|
|
454
|
+
|
|
455
|
+
# The API rsrc for sending MDM commands to this kind of target
|
|
456
|
+
#
|
|
457
|
+
# @return [String] The API rsrc.
|
|
458
|
+
#
|
|
459
|
+
# def send_command_rsrc
|
|
460
|
+
# case self::MDM_COMMAND_TARGET
|
|
461
|
+
# when *COMPUTER_TARGETS
|
|
462
|
+
# COMPUTER_RSRC
|
|
463
|
+
# when *DEVICE_TARGETS
|
|
464
|
+
# DEVICE_RSRC
|
|
465
|
+
# else
|
|
466
|
+
# raise Jamf::InvalidDataError, "Unknown MDM command target: #{self::MDM_COMMAND_TARGET}"
|
|
467
|
+
# end
|
|
468
|
+
# end
|
|
469
|
+
|
|
470
|
+
# Generate the XML to send to the Classic API, sending the MDM command to the targets
|
|
471
|
+
#
|
|
472
|
+
# DEPRECATED: Will be removed when 'wallpaper' is migrated to JPAPI
|
|
466
473
|
#
|
|
467
474
|
# @param command [Symbol] the command to be sent, a key from COMMANDS
|
|
468
475
|
#
|
|
@@ -525,6 +532,7 @@ module Jamf
|
|
|
525
532
|
return command if COMPUTER_COMMANDS.include? command
|
|
526
533
|
|
|
527
534
|
raise Jamf::UnsupportedError, "'#{command}' cannot be sent to computers or computer groups"
|
|
535
|
+
|
|
528
536
|
when *DEVICE_TARGETS
|
|
529
537
|
return command if DEVICE_COMMANDS.include? command
|
|
530
538
|
|
|
@@ -547,12 +555,14 @@ module Jamf
|
|
|
547
555
|
#
|
|
548
556
|
# @param cnx [Jamf::Connection] the API thru which to send the command
|
|
549
557
|
#
|
|
550
|
-
# @return
|
|
558
|
+
# @return [Hash{Symbol=>Array<String>}] The array contains mgmt ids of targets that failed
|
|
551
559
|
#
|
|
552
560
|
def blank_push(targets, api: nil, cnx: Jamf.cnx)
|
|
553
561
|
cnx = api if api
|
|
562
|
+
targets = raw_targets_to_mgmt_ids targets, cnx: cnx
|
|
554
563
|
|
|
555
|
-
|
|
564
|
+
data = { clientManagementIds: targets }
|
|
565
|
+
cnx.jp_post BLANK_PUSH_RSRC, data
|
|
556
566
|
end
|
|
557
567
|
alias send_blank_push blank_push
|
|
558
568
|
alias noop blank_push
|
|
@@ -561,27 +571,27 @@ module Jamf
|
|
|
561
571
|
#
|
|
562
572
|
# @param targets[String,Integer,Array<String,Integer>] @see .send_mdm_command
|
|
563
573
|
#
|
|
564
|
-
# @param passcode[String] a six-char passcode
|
|
574
|
+
# @param passcode[String] a six-char passcode
|
|
565
575
|
#
|
|
566
|
-
# @param message[String] An optional message to display
|
|
576
|
+
# @param message[String] An optional message to display
|
|
577
|
+
#
|
|
578
|
+
# @param phoneNumber[String] An optional phoneNumber to display
|
|
567
579
|
#
|
|
568
580
|
# @param cnx [Jamf::Connection] the API thru which to send the command
|
|
569
581
|
#
|
|
570
582
|
# @return (see .send_mdm_command)
|
|
571
583
|
#
|
|
572
|
-
def device_lock(targets, passcode:
|
|
584
|
+
def device_lock(targets, passcode: nil, message: nil, phoneNumber: nil, api: nil, cnx: Jamf.cnx)
|
|
573
585
|
cnx = api if api
|
|
574
586
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
587
|
+
cmd_data = {
|
|
588
|
+
commandType: DEVICE_LOCK
|
|
589
|
+
}
|
|
590
|
+
cmd_data[:message] = message if message
|
|
591
|
+
cmd_data[:phoneNumber] = phoneNumber if phoneNumber
|
|
592
|
+
cmd_data[:pin] = passcode unless passcode.pix_empty?
|
|
578
593
|
|
|
579
|
-
|
|
580
|
-
when *DEVICE_TARGETS
|
|
581
|
-
opts = {}
|
|
582
|
-
opts[:lock_message] = message if message
|
|
583
|
-
end # case
|
|
584
|
-
send_mdm_command targets, :device_lock, opts: opts, cnx: cnx
|
|
594
|
+
send_mdm_command(targets, cmd_data, cnx: cnx)
|
|
585
595
|
end
|
|
586
596
|
alias lock_device device_lock
|
|
587
597
|
alias lock device_lock
|
|
@@ -590,27 +600,42 @@ module Jamf
|
|
|
590
600
|
#
|
|
591
601
|
# @param targets[String,Integer,Array<String,Integer>] @see .send_mdm_command
|
|
592
602
|
#
|
|
593
|
-
# @param passcode[String] a six-char
|
|
603
|
+
# @param passcode[String] a six-char pin for FindMy
|
|
594
604
|
#
|
|
595
605
|
# @param preserve_data_plan[Boolean] Should the data plan of the mobile device be preserved?
|
|
596
606
|
#
|
|
607
|
+
# @param obliterationBehavior[String] 'Default', 'DoNotObliterate', 'ObliterateWithWarning' or 'Always'
|
|
608
|
+
#
|
|
609
|
+
# @param returnToService[Hash] Options for Return to Service. Keys are :enabled, :mdmProfileData, :wifiProfileData, boostrapToken. The last 3 are Base64 encoded strings. See Jamf and Apple docs for details. Default is { enabled: false }
|
|
610
|
+
#
|
|
597
611
|
# @param cnx [Jamf::Connection] the API thru which to send the command
|
|
598
612
|
#
|
|
599
613
|
# @return (see .send_mdm_command)
|
|
600
614
|
#
|
|
601
|
-
def erase_device(
|
|
615
|
+
def erase_device(
|
|
616
|
+
targets,
|
|
617
|
+
passcode: nil,
|
|
618
|
+
preserve_data_plan: false,
|
|
619
|
+
disallow_proximity_setup: false,
|
|
620
|
+
obliteration_behavior: 'Default',
|
|
621
|
+
return_to_service: nil,
|
|
622
|
+
api: nil,
|
|
623
|
+
cnx: Jamf.cnx
|
|
624
|
+
)
|
|
602
625
|
cnx = api if api
|
|
626
|
+
return_to_service ||= { enabled: false }
|
|
603
627
|
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
628
|
+
cmd_data = {
|
|
629
|
+
commandType: ERASE_DEVICE,
|
|
630
|
+
preserveDataPlan: preserve_data_plan,
|
|
631
|
+
disallowProximitySetup: disallow_proximity_setup,
|
|
632
|
+
obliterationBehavior: obliteration_behavior,
|
|
633
|
+
returnToService: return_to_service
|
|
634
|
+
}
|
|
607
635
|
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
opts[:preserve_data_plan] = 'true' if preserve_data_plan
|
|
612
|
-
end # case
|
|
613
|
-
send_mdm_command targets, :erase_device, opts: opts, cnx: cnx
|
|
636
|
+
cmd_data[:pin] = passcode if passcode
|
|
637
|
+
|
|
638
|
+
send_mdm_command(targets, cmd_data, cnx: cnx)
|
|
614
639
|
end
|
|
615
640
|
alias wipe erase_device
|
|
616
641
|
alias wipe_device erase_device
|
|
@@ -628,12 +653,27 @@ module Jamf
|
|
|
628
653
|
#
|
|
629
654
|
# @param cnx [Jamf::Connection] the API thru which to send the command
|
|
630
655
|
#
|
|
631
|
-
# @return
|
|
656
|
+
# @return [Array<Hash>] An array of the raw API results for each target
|
|
632
657
|
#
|
|
633
658
|
def unmanage_device(targets, api: nil, cnx: Jamf.cnx)
|
|
634
659
|
cnx = api if api
|
|
635
660
|
|
|
636
|
-
|
|
661
|
+
target_ids = raw_targets_to_mgmt_ids targets, jamf_ids: true, cnx: cnx
|
|
662
|
+
results = []
|
|
663
|
+
|
|
664
|
+
computer_targets = COMPUTER_TARGETS.include?(self::MDM_COMMAND_TARGET)
|
|
665
|
+
target_ids.each do |tid|
|
|
666
|
+
rsrc =
|
|
667
|
+
if computer_targets
|
|
668
|
+
"#{COMPUTER_INV_RSRC}/#{tid}/#{UNMANAGE_COMPUTER_RSRC}"
|
|
669
|
+
else
|
|
670
|
+
"#{MOBILE_DEVICE_RSRC}/#{tid}/#{UNMANAGE_MOBILE_DEVICE_RSRC}"
|
|
671
|
+
end
|
|
672
|
+
|
|
673
|
+
results << cnx.jp_post(rsrc)
|
|
674
|
+
end
|
|
675
|
+
|
|
676
|
+
results
|
|
637
677
|
end
|
|
638
678
|
alias remove_mdm_profile unmanage_device
|
|
639
679
|
|
|
@@ -653,7 +693,11 @@ module Jamf
|
|
|
653
693
|
def unlock_user_account(targets, user, api: nil, cnx: Jamf.cnx)
|
|
654
694
|
cnx = api if api
|
|
655
695
|
|
|
656
|
-
|
|
696
|
+
data = {
|
|
697
|
+
commandType: UNLOCK_USER_ACCOUNT,
|
|
698
|
+
userName: user
|
|
699
|
+
}
|
|
700
|
+
send_mdm_command targets, data, cnx: cnx
|
|
657
701
|
end
|
|
658
702
|
|
|
659
703
|
# Send a delete_user command to one or more targets
|
|
@@ -661,15 +705,23 @@ module Jamf
|
|
|
661
705
|
# @param targets[String,Integer,Array<String,Integer>] @see .send_mdm_command
|
|
662
706
|
#
|
|
663
707
|
# @param user[String] the username of the acct to delete
|
|
708
|
+
# @param force[Boolean] should the user be deleted even if logged in
|
|
709
|
+
# @param all[Boolean] should all users be deleted
|
|
664
710
|
#
|
|
665
711
|
# @param cnx [Jamf::Connection] the API thru which to send the command
|
|
666
712
|
#
|
|
667
713
|
# @return (see .send_mdm_command)
|
|
668
714
|
#
|
|
669
|
-
def delete_user(targets, user, api: nil, cnx: Jamf.cnx)
|
|
715
|
+
def delete_user(targets, user = nil, force: false, all: false, api: nil, cnx: Jamf.cnx)
|
|
670
716
|
cnx = api if api
|
|
671
717
|
|
|
672
|
-
|
|
718
|
+
data = {
|
|
719
|
+
commandType: DELETE_USER,
|
|
720
|
+
userName: user,
|
|
721
|
+
forceDeletion: force,
|
|
722
|
+
deleteAllUsers: all
|
|
723
|
+
}
|
|
724
|
+
send_mdm_command targets, data, cnx: cnx
|
|
673
725
|
end
|
|
674
726
|
|
|
675
727
|
# Send an enable_remote_desktop command to one or more targets
|
|
@@ -683,7 +735,10 @@ module Jamf
|
|
|
683
735
|
def enable_remote_desktop(targets, api: nil, cnx: Jamf.cnx)
|
|
684
736
|
cnx = api if api
|
|
685
737
|
|
|
686
|
-
|
|
738
|
+
data = {
|
|
739
|
+
commandType: ENABLE_REMOTE_DESKTOP
|
|
740
|
+
}
|
|
741
|
+
send_mdm_command targets, data, cnx: cnx
|
|
687
742
|
end
|
|
688
743
|
|
|
689
744
|
# Send a disable_remote_desktop command to one or more targets
|
|
@@ -697,12 +752,18 @@ module Jamf
|
|
|
697
752
|
def disable_remote_desktop(targets, api: nil, cnx: Jamf.cnx)
|
|
698
753
|
cnx = api if api
|
|
699
754
|
|
|
700
|
-
|
|
755
|
+
data = {
|
|
756
|
+
commandType: DISABLE_REMOTE_DESKTOP
|
|
757
|
+
}
|
|
758
|
+
send_mdm_command targets, data, cnx: cnx
|
|
701
759
|
end
|
|
702
760
|
|
|
703
761
|
# Commands for mobile devices only
|
|
704
762
|
################################
|
|
705
763
|
|
|
764
|
+
# DEPRECATED: The Jamf Pro API no longer uses MDM commands to update inventory.
|
|
765
|
+
# It uses DDM.
|
|
766
|
+
#
|
|
706
767
|
# Send an update_inventory command to one or more targets
|
|
707
768
|
#
|
|
708
769
|
# @param targets[String,Integer,Array<String,Integer>] @see .send_mdm_command
|
|
@@ -711,10 +772,8 @@ module Jamf
|
|
|
711
772
|
#
|
|
712
773
|
# @return (see .send_mdm_command)
|
|
713
774
|
#
|
|
714
|
-
def update_inventory(
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
send_mdm_command targets, :update_inventory, cnx: cnx
|
|
775
|
+
def update_inventory(_targets, api: nil, cnx: Jamf.cnx)
|
|
776
|
+
raise Jamf::UnsupportedError, 'The Jamf Pro no longer uses an MDM command to update MobileDevice inventory.'
|
|
718
777
|
end
|
|
719
778
|
alias recon update_inventory
|
|
720
779
|
|
|
@@ -722,14 +781,20 @@ module Jamf
|
|
|
722
781
|
#
|
|
723
782
|
# @param targets[String,Integer,Array<String,Integer>] @see .send_mdm_command
|
|
724
783
|
#
|
|
784
|
+
# @param unlock_token[String] The unlock token from Jamf Pro
|
|
785
|
+
#
|
|
725
786
|
# @param cnx [Jamf::Connection] the API thru which to send the command
|
|
726
787
|
#
|
|
727
788
|
# @return (see .send_mdm_command)
|
|
728
789
|
#
|
|
729
|
-
def clear_passcode(targets, api: nil, cnx: Jamf.cnx)
|
|
790
|
+
def clear_passcode(targets, unlock_token:, api: nil, cnx: Jamf.cnx)
|
|
730
791
|
cnx = api if api
|
|
731
792
|
|
|
732
|
-
|
|
793
|
+
data = {
|
|
794
|
+
commandType: CLEAR_PASSCODE,
|
|
795
|
+
unlockToken: unlock_token
|
|
796
|
+
}
|
|
797
|
+
send_mdm_command targets, data, cnx: cnx
|
|
733
798
|
end
|
|
734
799
|
|
|
735
800
|
# Send an clear_restrictions_password command to one or more targets
|
|
@@ -743,7 +808,10 @@ module Jamf
|
|
|
743
808
|
def clear_restrictions_password(targets, api: nil, cnx: Jamf.cnx)
|
|
744
809
|
cnx = api if api
|
|
745
810
|
|
|
746
|
-
|
|
811
|
+
data = {
|
|
812
|
+
commandType: CLEAR_RESTRICTIONS_PASSWORD
|
|
813
|
+
}
|
|
814
|
+
send_mdm_command targets, data, cnx: cnx
|
|
747
815
|
end
|
|
748
816
|
|
|
749
817
|
# Send an enable_data_roaming command to one or more targets
|
|
@@ -757,7 +825,11 @@ module Jamf
|
|
|
757
825
|
def enable_data_roaming(targets, api: nil, cnx: Jamf.cnx)
|
|
758
826
|
cnx = api if api
|
|
759
827
|
|
|
760
|
-
|
|
828
|
+
data = {
|
|
829
|
+
commandType: SETTINGS,
|
|
830
|
+
dataRoaming: ENABLE_DATA_ROAMING
|
|
831
|
+
}
|
|
832
|
+
send_mdm_command targets, data, cnx: cnx
|
|
761
833
|
end
|
|
762
834
|
|
|
763
835
|
# Send andisable_data_roaming command to one or more targets
|
|
@@ -771,7 +843,11 @@ module Jamf
|
|
|
771
843
|
def disable_data_roaming(targets, api: nil, cnx: Jamf.cnx)
|
|
772
844
|
cnx = api if api
|
|
773
845
|
|
|
774
|
-
|
|
846
|
+
data = {
|
|
847
|
+
commandType: SETTINGS,
|
|
848
|
+
dataRoaming: DISABLE_DATA_ROAMING
|
|
849
|
+
}
|
|
850
|
+
send_mdm_command targets, data, cnx: cnx
|
|
775
851
|
end
|
|
776
852
|
|
|
777
853
|
# Send an enable_voice_roaming command to one or more targets
|
|
@@ -785,7 +861,11 @@ module Jamf
|
|
|
785
861
|
def enable_voice_roaming(targets, api: nil, cnx: Jamf.cnx)
|
|
786
862
|
cnx = api if api
|
|
787
863
|
|
|
788
|
-
|
|
864
|
+
data = {
|
|
865
|
+
commandType: SETTINGS,
|
|
866
|
+
voiceRoaming: ENABLE_VOICE_ROAMING
|
|
867
|
+
}
|
|
868
|
+
send_mdm_command targets, data, cnx: cnx
|
|
789
869
|
end
|
|
790
870
|
|
|
791
871
|
# Send a disable_voice_roaming command to one or more targets
|
|
@@ -799,7 +879,11 @@ module Jamf
|
|
|
799
879
|
def disable_voice_roaming(targets, api: nil, cnx: Jamf.cnx)
|
|
800
880
|
cnx = api if api
|
|
801
881
|
|
|
802
|
-
|
|
882
|
+
data = {
|
|
883
|
+
commandType: SETTINGS,
|
|
884
|
+
voiceRoaming: DISABLE_VOICE_ROAMING
|
|
885
|
+
}
|
|
886
|
+
send_mdm_command targets, data, cnx: cnx
|
|
803
887
|
end
|
|
804
888
|
|
|
805
889
|
# Commands for supervized mobile devices only
|
|
@@ -818,11 +902,17 @@ module Jamf
|
|
|
818
902
|
def device_name(targets, name, api: nil, cnx: Jamf.cnx)
|
|
819
903
|
cnx = api if api
|
|
820
904
|
|
|
821
|
-
|
|
905
|
+
data = {
|
|
906
|
+
commandType: SETTINGS,
|
|
907
|
+
deviceName: name
|
|
908
|
+
}
|
|
909
|
+
send_mdm_command targets, data, cnx: cnx
|
|
822
910
|
end
|
|
823
911
|
alias set_name device_name
|
|
824
912
|
alias set_device_name device_name
|
|
825
913
|
|
|
914
|
+
# TODO: Update/migrate this when the wallpaper MDM command is migrated to JPAPI
|
|
915
|
+
#
|
|
826
916
|
# Send a wallpaper command to one or more targets
|
|
827
917
|
#
|
|
828
918
|
# @param targets[String,Integer,Array<String,Integer>] @see .send_mdm_command
|
|
@@ -860,7 +950,27 @@ module Jamf
|
|
|
860
950
|
raise ArgumentError, 'Either wallpaper_id: or wallpaper_content must be provided'
|
|
861
951
|
end
|
|
862
952
|
|
|
863
|
-
|
|
953
|
+
targets = raw_targets_to_mgmt_ids targets, jamf_ids: true, cnx: cnx
|
|
954
|
+
cmd_xml = mdm_command_xml(:Wallpaper, opts, targets)
|
|
955
|
+
rsrc = 'mobiledevicecommands/command/Wallpaper'
|
|
956
|
+
|
|
957
|
+
if JSS.devmode?
|
|
958
|
+
puts "Sending XML:\n"
|
|
959
|
+
REXML::Document.new(cmd_xml).write STDOUT, 2
|
|
960
|
+
puts "\n\nTo rsrc: #{rsrc}"
|
|
961
|
+
end
|
|
962
|
+
|
|
963
|
+
xml_resp = cnx.c_post rsrc, cmd_xml
|
|
964
|
+
|
|
965
|
+
hash = {}
|
|
966
|
+
mds = REXML::Document.new(xml_resp).elements[DEVICE_COMMAND_ELEMENT].elements[DEVICE_LIST_ELEMENT]
|
|
967
|
+
mds.each_element do |md|
|
|
968
|
+
id = md.elements[DEVICE_ID_ELEMENT].text.to_i
|
|
969
|
+
status = md.elements[DEVICE_COMMAND_STATUS_ELEMENT].text
|
|
970
|
+
hash[id] = status
|
|
971
|
+
end
|
|
972
|
+
|
|
973
|
+
hash
|
|
864
974
|
end
|
|
865
975
|
alias set_wallpaper wallpaper
|
|
866
976
|
|
|
@@ -877,7 +987,11 @@ module Jamf
|
|
|
877
987
|
def passcode_lock_grace_period(targets, secs, api: nil, cnx: Jamf.cnx)
|
|
878
988
|
cnx = api if api
|
|
879
989
|
|
|
880
|
-
|
|
990
|
+
data = {
|
|
991
|
+
commandType: SETTINGS,
|
|
992
|
+
passcodeLockGracePeriod: secs
|
|
993
|
+
}
|
|
994
|
+
send_mdm_command targets, data, cnx: cnx
|
|
881
995
|
end
|
|
882
996
|
|
|
883
997
|
# Send a shut_down_device command to one or more targets
|
|
@@ -891,7 +1005,10 @@ module Jamf
|
|
|
891
1005
|
def shut_down_device(targets, api: nil, cnx: Jamf.cnx)
|
|
892
1006
|
cnx = api if api
|
|
893
1007
|
|
|
894
|
-
|
|
1008
|
+
data = {
|
|
1009
|
+
commandType: SHUT_DOWN_DEVICE
|
|
1010
|
+
}
|
|
1011
|
+
send_mdm_command targets, data, cnx: cnx
|
|
895
1012
|
end
|
|
896
1013
|
alias shutdown_device shut_down_device
|
|
897
1014
|
alias shut_down shut_down_device
|
|
@@ -899,16 +1016,33 @@ module Jamf
|
|
|
899
1016
|
|
|
900
1017
|
# Send a restart_device command to one or more targets
|
|
901
1018
|
#
|
|
1019
|
+
# @param rebuild_kernel_cache[Boolean] Rebuild the kernel cache on restart. Default is false
|
|
1020
|
+
#
|
|
1021
|
+
# @param kext_paths[Array<String>] An array of kext paths to rebuild the cache for. Default is nil
|
|
1022
|
+
#
|
|
1023
|
+
# @param notify_user[Boolean] Notify the user of the restart. Default is true
|
|
1024
|
+
#
|
|
902
1025
|
# @param targets[String,Integer,Array<String,Integer>] @see .send_mdm_command
|
|
903
1026
|
#
|
|
904
1027
|
# @param cnx [Jamf::Connection] the API thru which to send the command
|
|
905
1028
|
#
|
|
906
1029
|
# @return (see .send_mdm_command)
|
|
907
1030
|
#
|
|
908
|
-
def restart_device(targets, api: nil, cnx: Jamf.cnx)
|
|
1031
|
+
def restart_device(targets, rebuild_kernel_cache: false, kext_paths: nil, notify_user: true, api: nil, cnx: Jamf.cnx)
|
|
909
1032
|
cnx = api if api
|
|
910
1033
|
|
|
911
|
-
|
|
1034
|
+
data = {
|
|
1035
|
+
commandType: RESTART_DEVICE,
|
|
1036
|
+
rebuildKernelCache: rebuild_kernel_cache,
|
|
1037
|
+
notifyUser: notify_user
|
|
1038
|
+
}
|
|
1039
|
+
if kext_paths
|
|
1040
|
+
raise ArgumentError, 'kext_paths must be an Array of Strings' unless kext_paths.is_a?(Array) && kext_paths.all? { |kp| kp.is_a? String }
|
|
1041
|
+
|
|
1042
|
+
data[:kextPaths] = kext_paths
|
|
1043
|
+
end
|
|
1044
|
+
|
|
1045
|
+
send_mdm_command targets, data, cnx: cnx
|
|
912
1046
|
end
|
|
913
1047
|
alias restart restart_device
|
|
914
1048
|
|
|
@@ -923,7 +1057,11 @@ module Jamf
|
|
|
923
1057
|
def enable_app_analytics(targets, api: nil, cnx: Jamf.cnx)
|
|
924
1058
|
cnx = api if api
|
|
925
1059
|
|
|
926
|
-
|
|
1060
|
+
data = {
|
|
1061
|
+
commandType: SETTINGS,
|
|
1062
|
+
appAnalytics: ENABLE_APP_ANALYTICS
|
|
1063
|
+
}
|
|
1064
|
+
send_mdm_command targets, data, cnx: cnx
|
|
927
1065
|
end
|
|
928
1066
|
|
|
929
1067
|
# Send a disable_app_analytics command to one or more targets
|
|
@@ -937,7 +1075,11 @@ module Jamf
|
|
|
937
1075
|
def disable_app_analytics(targets, api: nil, cnx: Jamf.cnx)
|
|
938
1076
|
cnx = api if api
|
|
939
1077
|
|
|
940
|
-
|
|
1078
|
+
data = {
|
|
1079
|
+
commandType: SETTINGS,
|
|
1080
|
+
appAnalytics: DISABLE_APP_ANALYTICS
|
|
1081
|
+
}
|
|
1082
|
+
send_mdm_command targets, data, cnx: cnx
|
|
941
1083
|
end
|
|
942
1084
|
|
|
943
1085
|
# Send an enable_diagnostic_submission command to one or more targets
|
|
@@ -951,7 +1093,11 @@ module Jamf
|
|
|
951
1093
|
def enable_diagnostic_submission(targets, api: nil, cnx: Jamf.cnx)
|
|
952
1094
|
cnx = api if api
|
|
953
1095
|
|
|
954
|
-
|
|
1096
|
+
data = {
|
|
1097
|
+
commandType: SETTINGS,
|
|
1098
|
+
diagnosticSubmission: ENABLE_DIAGNOSTIC_SUBMISSION
|
|
1099
|
+
}
|
|
1100
|
+
send_mdm_command targets, data, cnx: cnx
|
|
955
1101
|
end
|
|
956
1102
|
|
|
957
1103
|
# Send a disable_diagnostic_submission command to one or more targets
|
|
@@ -965,7 +1111,11 @@ module Jamf
|
|
|
965
1111
|
def disable_diagnostic_submission(targets, api: nil, cnx: Jamf.cnx)
|
|
966
1112
|
cnx = api if api
|
|
967
1113
|
|
|
968
|
-
|
|
1114
|
+
data = {
|
|
1115
|
+
commandType: SETTINGS,
|
|
1116
|
+
diagnosticSubmission: DISABLE_DIAGNOSTIC_SUBMISSION
|
|
1117
|
+
}
|
|
1118
|
+
send_mdm_command targets, data, cnx: cnx
|
|
969
1119
|
end
|
|
970
1120
|
|
|
971
1121
|
# Send a enable_lost_mode command to one or more targets
|
|
@@ -980,9 +1130,9 @@ module Jamf
|
|
|
980
1130
|
#
|
|
981
1131
|
# @param footnote[String] Optional footnote to display on the lock screen
|
|
982
1132
|
#
|
|
983
|
-
# @param play_sound[Boolean] Play a sound when entering lost mode
|
|
1133
|
+
# @param play_sound[Boolean] Play a sound when entering lost mode.
|
|
984
1134
|
#
|
|
985
|
-
# @param enforce_lost_mode[Boolean] Re-enable lost mode when re-enrolled after wipe.
|
|
1135
|
+
# @param enforce_lost_mode[Boolean] Re-enable lost mode when re-enrolled after wipe. DEPRECATED: ignored by Jamf Pro API
|
|
986
1136
|
#
|
|
987
1137
|
# @param cnx [Jamf::Connection] the API thru which to send the command
|
|
988
1138
|
#
|
|
@@ -1000,15 +1150,18 @@ module Jamf
|
|
|
1000
1150
|
)
|
|
1001
1151
|
cnx = api if api
|
|
1002
1152
|
|
|
1003
|
-
|
|
1153
|
+
data = {
|
|
1154
|
+
commandType: ENABLE_LOST_MODE
|
|
1155
|
+
}
|
|
1156
|
+
data[:lostModeMessage] = message if message
|
|
1157
|
+
data[:lostModePhone] = phone if phone
|
|
1158
|
+
data[:lostModeFootnote] = footnote if footnote
|
|
1004
1159
|
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
opts[:lost_mode_phone] = phone if phone
|
|
1008
|
-
opts[:lost_mode_footnote] = footnote if footnote
|
|
1009
|
-
opts[:lost_mode_with_sound] = 'true' if play_sound
|
|
1160
|
+
result = send_mdm_command targets, data, cnx: cnx
|
|
1161
|
+
return result unless play_sound
|
|
1010
1162
|
|
|
1011
|
-
|
|
1163
|
+
sound_result = play_lost_mode_sound targets, cnx: cnx
|
|
1164
|
+
{ enable_lost_mode: result, play_lost_mode_sound: sound_result }
|
|
1012
1165
|
end
|
|
1013
1166
|
|
|
1014
1167
|
# Send a play_lost_mode_sound command to one or more targets
|
|
@@ -1022,7 +1175,10 @@ module Jamf
|
|
|
1022
1175
|
def play_lost_mode_sound(targets, api: nil, cnx: Jamf.cnx)
|
|
1023
1176
|
cnx = api if api
|
|
1024
1177
|
|
|
1025
|
-
|
|
1178
|
+
data = {
|
|
1179
|
+
commandType: PLAY_LOST_MODE_SOUND
|
|
1180
|
+
}
|
|
1181
|
+
send_mdm_command targets, data, cnx: cnx
|
|
1026
1182
|
end
|
|
1027
1183
|
|
|
1028
1184
|
# Send a disable_lost_mode command to one or more targets
|
|
@@ -1036,7 +1192,10 @@ module Jamf
|
|
|
1036
1192
|
def disable_lost_mode(targets, api: nil, cnx: Jamf.cnx)
|
|
1037
1193
|
cnx = api if api
|
|
1038
1194
|
|
|
1039
|
-
|
|
1195
|
+
data = {
|
|
1196
|
+
commandType: DISABLE_LOST_MODE
|
|
1197
|
+
}
|
|
1198
|
+
send_mdm_command targets, data, cnx: cnx
|
|
1040
1199
|
end
|
|
1041
1200
|
|
|
1042
1201
|
# Flushing Commands
|
|
@@ -1057,16 +1216,16 @@ module Jamf
|
|
|
1057
1216
|
#
|
|
1058
1217
|
# @return [void]
|
|
1059
1218
|
#
|
|
1060
|
-
def flush_mdm_commands(targets, status
|
|
1219
|
+
def flush_mdm_commands(targets, status:, api: nil, cnx: Jamf.cnx)
|
|
1061
1220
|
cnx = api if api
|
|
1062
1221
|
|
|
1063
1222
|
raise Jamf::InvalidDataError, "Status must be one of :#{FLUSHABLE_STATUSES.keys.join ', :'}" unless FLUSHABLE_STATUSES.keys.include? status
|
|
1064
1223
|
|
|
1065
1224
|
status = FLUSHABLE_STATUSES[status]
|
|
1066
1225
|
|
|
1067
|
-
# TODO: add 'unmanaged_ok:' param to
|
|
1226
|
+
# TODO: add 'unmanaged_ok:' param to raw_targets_to_mgmt_ids method, so that we can
|
|
1068
1227
|
# use this to flush commands for unmanaged machines.
|
|
1069
|
-
target_ids =
|
|
1228
|
+
target_ids = raw_targets_to_mgmt_ids targets, cnx: cnx, jamf_ids: true, unmanaged_ok: true
|
|
1070
1229
|
|
|
1071
1230
|
command_flush_rsrc = "commandflush/#{self::MDM_COMMAND_TARGET}/id"
|
|
1072
1231
|
|
|
@@ -1108,11 +1267,23 @@ module Jamf
|
|
|
1108
1267
|
#
|
|
1109
1268
|
# @param passcode_or_message[String] a six-char passcode, required for computers & computergroups
|
|
1110
1269
|
# Or an optional message to display on mobiledevices & mobiledevicegroups
|
|
1270
|
+
# @param passcode[String] a six-char passcode
|
|
1271
|
+
#
|
|
1272
|
+
# @param message[String] An optional message to display
|
|
1273
|
+
#
|
|
1111
1274
|
#
|
|
1112
1275
|
# @return (see .send_mdm_command)
|
|
1113
1276
|
#
|
|
1114
|
-
def device_lock(passcode_or_message = '')
|
|
1115
|
-
|
|
1277
|
+
def device_lock(passcode_or_message = '', passcode: nil, message: nil, phoneNumber: nil)
|
|
1278
|
+
# backward compatibility: if only one arg given, decide if it's a passcode or message
|
|
1279
|
+
# explicit args override that
|
|
1280
|
+
if passcode_or_message.length == 6
|
|
1281
|
+
passcode ||= passcode_or_message
|
|
1282
|
+
elsif passcode_or_message.length > 0
|
|
1283
|
+
message ||= passcode_or_message
|
|
1284
|
+
end
|
|
1285
|
+
|
|
1286
|
+
self.class.device_lock @id, passcode: passcode, message: message, phoneNumber: phoneNumber, cnx: @cnx
|
|
1116
1287
|
end
|
|
1117
1288
|
alias lock device_lock
|
|
1118
1289
|
alias lock_device device_lock
|
|
@@ -1121,10 +1292,30 @@ module Jamf
|
|
|
1121
1292
|
#
|
|
1122
1293
|
# @param passcode[String] a six-char passcode, required for computers & computergroups
|
|
1123
1294
|
#
|
|
1295
|
+
# @param preserve_data_plan[Boolean] Should the data plan of the mobile device be preserved?
|
|
1296
|
+
#
|
|
1297
|
+
# @param obliterationBehavior[String] 'Default', 'DoNotObliterate', 'ObliterateWithWarning' or 'Always'
|
|
1298
|
+
#
|
|
1299
|
+
# @param returnToService[Hash] Options for Return to Service. Keys are :enabled, :mdmProfileData, :wifiProfileData, boostrapToken. The last 3 are Base64 encoded strings. See Jamf and Apple docs for details. Default is { enabled: false }
|
|
1300
|
+
#
|
|
1124
1301
|
# @return (see .send_mdm_command)
|
|
1125
1302
|
#
|
|
1126
|
-
def erase_device(
|
|
1127
|
-
|
|
1303
|
+
def erase_device(
|
|
1304
|
+
passcode: nil,
|
|
1305
|
+
preserve_data_plan: false,
|
|
1306
|
+
disallow_proximity_setup: false,
|
|
1307
|
+
obliteration_behavior: 'Default',
|
|
1308
|
+
return_to_service: nil
|
|
1309
|
+
)
|
|
1310
|
+
self.class.erase_device(
|
|
1311
|
+
@id,
|
|
1312
|
+
passcode: passcode,
|
|
1313
|
+
preserve_data_plan: preserve_data_plan,
|
|
1314
|
+
disallow_proximity_setup: disallow_proximity_setup,
|
|
1315
|
+
obliteration_behavior: obliteration_behavior,
|
|
1316
|
+
return_to_service: return_to_service,
|
|
1317
|
+
cnx: @cnx
|
|
1318
|
+
)
|
|
1128
1319
|
end
|
|
1129
1320
|
alias wipe_device erase_device
|
|
1130
1321
|
alias wipe_computer erase_device
|
|
@@ -1161,11 +1352,12 @@ module Jamf
|
|
|
1161
1352
|
# Send a delete_user command to this computer or group
|
|
1162
1353
|
#
|
|
1163
1354
|
# @param user[String] the username of the acct to delete
|
|
1164
|
-
#
|
|
1355
|
+
# @param force[Boolean] should the user be deleted even if logged in
|
|
1356
|
+
# @param all[Boolean] should all users be deleted #
|
|
1165
1357
|
# @return (see .send_mdm_command)
|
|
1166
1358
|
#
|
|
1167
|
-
def delete_user(user)
|
|
1168
|
-
self.class.delete_user @id, user, cnx: @cnx
|
|
1359
|
+
def delete_user(user, force: false, all: false)
|
|
1360
|
+
self.class.delete_user @id, user, force: force, all: all, cnx: @cnx
|
|
1169
1361
|
end
|
|
1170
1362
|
|
|
1171
1363
|
# Send an enable_remote_desktop command to this computer or group
|
|
@@ -1200,10 +1392,10 @@ module Jamf
|
|
|
1200
1392
|
|
|
1201
1393
|
# Send an clear_passcode command to this object
|
|
1202
1394
|
#
|
|
1395
|
+
# @param unlock_token[String] The unlock token from Jamf Pro
|
|
1203
1396
|
# @return (see .send_mdm_command)
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
self.class.clear_passcode @id, cnx: @cnx
|
|
1397
|
+
def clear_passcode(unlock_token:)
|
|
1398
|
+
self.class.clear_passcode @id, unlock_token: unlock_token, cnx: @cnx
|
|
1207
1399
|
end
|
|
1208
1400
|
|
|
1209
1401
|
# Send an clear_restrictions_password command to this object
|
|
@@ -1259,11 +1451,10 @@ module Jamf
|
|
|
1259
1451
|
#
|
|
1260
1452
|
# @return (see .send_mdm_command)
|
|
1261
1453
|
#
|
|
1262
|
-
def
|
|
1454
|
+
def set_device_name(name)
|
|
1263
1455
|
self.class.device_name @id, name, cnx: @cnx
|
|
1264
1456
|
end
|
|
1265
|
-
alias set_name
|
|
1266
|
-
alias set_device_name device_name
|
|
1457
|
+
alias set_name set_device_name
|
|
1267
1458
|
|
|
1268
1459
|
# Send a wallpaper command to this object
|
|
1269
1460
|
#
|
|
@@ -1378,7 +1569,8 @@ module Jamf
|
|
|
1378
1569
|
phone: phone,
|
|
1379
1570
|
footnote: footnote,
|
|
1380
1571
|
play_sound: play_sound,
|
|
1381
|
-
enforce_lost_mode: enforce_lost_mode,
|
|
1572
|
+
enforce_lost_mode: enforce_lost_mode,
|
|
1573
|
+
cnx: @cnx
|
|
1382
1574
|
)
|
|
1383
1575
|
end
|
|
1384
1576
|
|
|
@@ -1411,6 +1603,6 @@ module Jamf
|
|
|
1411
1603
|
self.class.flush_mdm_commands @id, status: status, cnx: @cnx
|
|
1412
1604
|
end
|
|
1413
1605
|
|
|
1414
|
-
end # module
|
|
1606
|
+
end # module MacOSRedeployMgmtFramework
|
|
1415
1607
|
|
|
1416
|
-
end # module
|
|
1608
|
+
end # module Jamf
|