ruby-jss 4.2.4 → 5.0.0b1
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 +25 -0
- data/lib/jamf/api/classic/api_objects/computer.rb +20 -0
- data/lib/jamf/api/classic/api_objects/mdm.rb +429 -238
- 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 +28 -7
|
@@ -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,16 +344,16 @@ 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}"
|
|
350
|
+
targets = raw_targets_to_mgmt_ids(targets, cnx: cnx)
|
|
351
|
+
targets.map! { |mid| { managementId: mid } }
|
|
341
352
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
353
|
+
data = {
|
|
354
|
+
clientData: targets,
|
|
355
|
+
commandData: command_data
|
|
356
|
+
}
|
|
345
357
|
|
|
346
358
|
if JSS.devmode?
|
|
347
359
|
puts "Sending XML:\n"
|
|
@@ -349,102 +361,44 @@ module Jamf
|
|
|
349
361
|
puts "\n\nTo rsrc: #{rsrc}"
|
|
350
362
|
end
|
|
351
363
|
|
|
352
|
-
|
|
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
|
|
382
|
-
|
|
383
|
-
# Convert the result of senting a device MDM command into
|
|
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
|
|
400
|
-
|
|
401
|
-
# The API rsrc for sending MDM commands to this kind of target
|
|
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
|
|
364
|
+
cnx.jp_post MDM_COMMAND_RSRC, data
|
|
414
365
|
end
|
|
415
366
|
|
|
416
367
|
# Convert the targets provided for sending a command into
|
|
417
|
-
# the final list of
|
|
368
|
+
# the final list of computer or mobile device management ids
|
|
418
369
|
#
|
|
419
370
|
# @param targets[String,Integer,Array] See {#send_mdm_command}
|
|
420
371
|
#
|
|
421
372
|
# @param expand_groups[Boolean] Should groups be expanded into member ids?
|
|
373
|
+
# DEPRECATED: this is now automatic based on the class type.
|
|
374
|
+
#
|
|
375
|
+
# @param unmanaged_ok[Boolean] Are unmanaged targets allowed?
|
|
376
|
+
#
|
|
377
|
+
# @param jamf_ids[Boolean] return Jamf ids instead of management ids
|
|
422
378
|
#
|
|
423
379
|
# @param cnx [Jamf::Connection] an API connection to use.
|
|
424
380
|
#
|
|
425
381
|
# @return [Array<Integer>] The ids of the target devices for a command
|
|
426
382
|
#
|
|
427
|
-
def
|
|
383
|
+
def raw_targets_to_mgmt_ids(targets, expand_groups: true, unmanaged_ok: false, jamf_ids: false, api: nil, cnx: Jamf.cnx)
|
|
428
384
|
cnx = api if api
|
|
429
|
-
|
|
430
385
|
targets = targets.is_a?(Array) ? targets : [targets]
|
|
431
386
|
|
|
432
387
|
# flush caches before checking ids and managment
|
|
433
388
|
cnx.flushcache self::RSRC_LIST_KEY
|
|
434
389
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
id = valid_id md, cnx: cnx
|
|
438
|
-
raise Jamf::NoSuchItemError, "No #{self} matches identifier: #{md}" unless id
|
|
390
|
+
target_ids = []
|
|
391
|
+
this_is_a_group_class = GROUP_TARGETS.include?(self::MDM_COMMAND_TARGET)
|
|
439
392
|
|
|
440
|
-
|
|
441
|
-
|
|
393
|
+
targets.each do |ident|
|
|
394
|
+
id = valid_id ident, cnx: cnx
|
|
395
|
+
raise Jamf::NoSuchItemError, "No #{self} matches identifier: #{ident}" unless id
|
|
442
396
|
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
397
|
+
if this_is_a_group_class
|
|
398
|
+
target_ids += fetch(id: id).member_ids
|
|
399
|
+
else
|
|
400
|
+
target_ids << id
|
|
401
|
+
end
|
|
448
402
|
end
|
|
449
403
|
|
|
450
404
|
# make sure all of them are managed, or else the API will raise a 400
|
|
@@ -452,17 +406,74 @@ module Jamf
|
|
|
452
406
|
# Some actions, like flushing MDM commands (see .flush_mdm_commands)
|
|
453
407
|
# are OK on unmanaged machines, so they will specify 'unmanaged_ok'
|
|
454
408
|
unless unmanaged_ok
|
|
409
|
+
# get all managed ids in an array
|
|
455
410
|
all_mgd = map_all_ids_to(:managed, cnx: cnx).select { |_id, mgd| mgd }.keys
|
|
456
411
|
|
|
457
|
-
|
|
412
|
+
target_ids.each do |target_id|
|
|
458
413
|
raise Jamf::UnmanagedError, "#{self} with id #{target_id} is not managed. Cannot send command." unless all_mgd.include? target_id
|
|
459
414
|
end
|
|
460
|
-
end #
|
|
415
|
+
end # unless
|
|
461
416
|
|
|
462
|
-
|
|
417
|
+
# return the jamf ids if requested
|
|
418
|
+
return target_ids if jamf_ids
|
|
419
|
+
|
|
420
|
+
# return the management id for each target
|
|
421
|
+
target_ids.map { |t| management_id t, cnx: cnx }
|
|
463
422
|
end
|
|
464
423
|
|
|
465
|
-
#
|
|
424
|
+
# Convert the result of senting a computer MDM command into
|
|
425
|
+
# the appropriate hash
|
|
426
|
+
#
|
|
427
|
+
# @param result [String] The raw XML from POSTing a computer command
|
|
428
|
+
#
|
|
429
|
+
# @return (see #send_mdm_command)
|
|
430
|
+
#
|
|
431
|
+
# def process_computer_xml_result(result)
|
|
432
|
+
# hash = {}
|
|
433
|
+
# REXML::Document.new(result).elements[COMPUTER_COMMAND_ELEMENT].each_element do |cmd|
|
|
434
|
+
# compid = cmd.elements[COMPUTER_ID_ELEMENT].text.to_i
|
|
435
|
+
# udid = cmd.elements[COMPUTER_COMMAND_UDID_ELEMENT].text
|
|
436
|
+
# hash[compid] = udid
|
|
437
|
+
# end
|
|
438
|
+
# hash
|
|
439
|
+
# end
|
|
440
|
+
|
|
441
|
+
# Convert the result of senting a device MDM command into
|
|
442
|
+
# the appropriate hash
|
|
443
|
+
#
|
|
444
|
+
# @param result [String] The raw XML from POSTing a device command
|
|
445
|
+
#
|
|
446
|
+
# @return (see #send_mdm_command)
|
|
447
|
+
#
|
|
448
|
+
# def process_mobiledevice_xml_result(result)
|
|
449
|
+
# hash = {}
|
|
450
|
+
# mds = REXML::Document.new(result).elements[DEVICE_COMMAND_ELEMENT].elements[DEVICE_LIST_ELEMENT]
|
|
451
|
+
# mds.each_element do |md|
|
|
452
|
+
# id = md.elements[DEVICE_ID_ELEMENT].text.to_i
|
|
453
|
+
# status = md.elements[DEVICE_COMMAND_STATUS_ELEMENT].text
|
|
454
|
+
# hash[id] = status
|
|
455
|
+
# end
|
|
456
|
+
# hash
|
|
457
|
+
# end
|
|
458
|
+
|
|
459
|
+
# The API rsrc for sending MDM commands to this kind of target
|
|
460
|
+
#
|
|
461
|
+
# @return [String] The API rsrc.
|
|
462
|
+
#
|
|
463
|
+
# def send_command_rsrc
|
|
464
|
+
# case self::MDM_COMMAND_TARGET
|
|
465
|
+
# when *COMPUTER_TARGETS
|
|
466
|
+
# COMPUTER_RSRC
|
|
467
|
+
# when *DEVICE_TARGETS
|
|
468
|
+
# DEVICE_RSRC
|
|
469
|
+
# else
|
|
470
|
+
# raise Jamf::InvalidDataError, "Unknown MDM command target: #{self::MDM_COMMAND_TARGET}"
|
|
471
|
+
# end
|
|
472
|
+
# end
|
|
473
|
+
|
|
474
|
+
# Generate the XML to send to the Classic API, sending the MDM command to the targets
|
|
475
|
+
#
|
|
476
|
+
# DEPRECATED: Will be removed when 'wallpaper' is migrated to JPAPI
|
|
466
477
|
#
|
|
467
478
|
# @param command [Symbol] the command to be sent, a key from COMMANDS
|
|
468
479
|
#
|
|
@@ -525,6 +536,7 @@ module Jamf
|
|
|
525
536
|
return command if COMPUTER_COMMANDS.include? command
|
|
526
537
|
|
|
527
538
|
raise Jamf::UnsupportedError, "'#{command}' cannot be sent to computers or computer groups"
|
|
539
|
+
|
|
528
540
|
when *DEVICE_TARGETS
|
|
529
541
|
return command if DEVICE_COMMANDS.include? command
|
|
530
542
|
|
|
@@ -547,12 +559,14 @@ module Jamf
|
|
|
547
559
|
#
|
|
548
560
|
# @param cnx [Jamf::Connection] the API thru which to send the command
|
|
549
561
|
#
|
|
550
|
-
# @return
|
|
562
|
+
# @return [Hash{Symbol=>Array<String>}] The array contains mgmt ids of targets that failed
|
|
551
563
|
#
|
|
552
564
|
def blank_push(targets, api: nil, cnx: Jamf.cnx)
|
|
553
565
|
cnx = api if api
|
|
566
|
+
targets = raw_targets_to_mgmt_ids targets, cnx: cnx
|
|
554
567
|
|
|
555
|
-
|
|
568
|
+
data = { clientManagementIds: targets }
|
|
569
|
+
cnx.jp_post BLANK_PUSH_RSRC, data
|
|
556
570
|
end
|
|
557
571
|
alias send_blank_push blank_push
|
|
558
572
|
alias noop blank_push
|
|
@@ -561,27 +575,27 @@ module Jamf
|
|
|
561
575
|
#
|
|
562
576
|
# @param targets[String,Integer,Array<String,Integer>] @see .send_mdm_command
|
|
563
577
|
#
|
|
564
|
-
# @param passcode[String] a six-char passcode
|
|
578
|
+
# @param passcode[String] a six-char passcode
|
|
579
|
+
#
|
|
580
|
+
# @param message[String] An optional message to display
|
|
565
581
|
#
|
|
566
|
-
# @param
|
|
582
|
+
# @param phoneNumber[String] An optional phoneNumber to display
|
|
567
583
|
#
|
|
568
584
|
# @param cnx [Jamf::Connection] the API thru which to send the command
|
|
569
585
|
#
|
|
570
586
|
# @return (see .send_mdm_command)
|
|
571
587
|
#
|
|
572
|
-
def device_lock(targets, passcode:
|
|
588
|
+
def device_lock(targets, passcode: nil, message: nil, phoneNumber: nil, api: nil, cnx: Jamf.cnx)
|
|
573
589
|
cnx = api if api
|
|
574
590
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
591
|
+
cmd_data = {
|
|
592
|
+
commandType: DEVICE_LOCK
|
|
593
|
+
}
|
|
594
|
+
cmd_data[:message] = message if message
|
|
595
|
+
cmd_data[:phoneNumber] = phoneNumber if phoneNumber
|
|
596
|
+
cmd_data[:pin] = passcode if passcode
|
|
578
597
|
|
|
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
|
|
598
|
+
send_mdm_command(targets, cmd_data, cnx: cnx)
|
|
585
599
|
end
|
|
586
600
|
alias lock_device device_lock
|
|
587
601
|
alias lock device_lock
|
|
@@ -590,27 +604,42 @@ module Jamf
|
|
|
590
604
|
#
|
|
591
605
|
# @param targets[String,Integer,Array<String,Integer>] @see .send_mdm_command
|
|
592
606
|
#
|
|
593
|
-
# @param passcode[String] a six-char
|
|
607
|
+
# @param passcode[String] a six-char pin for FindMy
|
|
594
608
|
#
|
|
595
609
|
# @param preserve_data_plan[Boolean] Should the data plan of the mobile device be preserved?
|
|
596
610
|
#
|
|
611
|
+
# @param obliterationBehavior[String] 'Default', 'DoNotObliterate', 'ObliterateWithWarning' or 'Always'
|
|
612
|
+
#
|
|
613
|
+
# @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 }
|
|
614
|
+
#
|
|
597
615
|
# @param cnx [Jamf::Connection] the API thru which to send the command
|
|
598
616
|
#
|
|
599
617
|
# @return (see .send_mdm_command)
|
|
600
618
|
#
|
|
601
|
-
def erase_device(
|
|
619
|
+
def erase_device(
|
|
620
|
+
targets,
|
|
621
|
+
passcode: nil,
|
|
622
|
+
preserve_data_plan: false,
|
|
623
|
+
disallow_proximity_setup: false,
|
|
624
|
+
obliteration_behavior: 'Default',
|
|
625
|
+
return_to_service: nil,
|
|
626
|
+
api: nil,
|
|
627
|
+
cnx: Jamf.cnx
|
|
628
|
+
)
|
|
602
629
|
cnx = api if api
|
|
630
|
+
return_to_service ||= { enabled: false }
|
|
603
631
|
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
632
|
+
cmd_data = {
|
|
633
|
+
commandType: ERASE_DEVICE,
|
|
634
|
+
preserveDataPlan: preserve_data_plan,
|
|
635
|
+
disallowProximitySetup: disallow_proximity_setup,
|
|
636
|
+
obliterationBehavior: obliteration_behavior,
|
|
637
|
+
returnToService: return_to_service
|
|
638
|
+
}
|
|
607
639
|
|
|
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
|
|
640
|
+
cmd_data[:pin] = passcode if passcode
|
|
641
|
+
|
|
642
|
+
send_mdm_command(targets, cmd_data, cnx: cnx)
|
|
614
643
|
end
|
|
615
644
|
alias wipe erase_device
|
|
616
645
|
alias wipe_device erase_device
|
|
@@ -628,12 +657,27 @@ module Jamf
|
|
|
628
657
|
#
|
|
629
658
|
# @param cnx [Jamf::Connection] the API thru which to send the command
|
|
630
659
|
#
|
|
631
|
-
# @return
|
|
660
|
+
# @return [Array<Hash>] An array of the raw API results for each target
|
|
632
661
|
#
|
|
633
662
|
def unmanage_device(targets, api: nil, cnx: Jamf.cnx)
|
|
634
663
|
cnx = api if api
|
|
635
664
|
|
|
636
|
-
|
|
665
|
+
target_ids = raw_targets_to_mgmt_ids targets, jamf_ids: true, cnx: cnx
|
|
666
|
+
results = []
|
|
667
|
+
|
|
668
|
+
computer_targets = COMPUTER_TARGETS.include?(self::MDM_COMMAND_TARGET)
|
|
669
|
+
target_ids.each do |tid|
|
|
670
|
+
rsrc =
|
|
671
|
+
if computer_targets
|
|
672
|
+
"#{COMPUTER_INV_RSRC}/#{tid}/#{UNMANAGE_COMPUTER_RSRC}"
|
|
673
|
+
else
|
|
674
|
+
"#{MOBILE_DEVICE_RSRC}/#{tid}/#{UNMANAGE_MOBILE_DEVICE_RSRC}"
|
|
675
|
+
end
|
|
676
|
+
|
|
677
|
+
results << cnx.jp_post(rsrc)
|
|
678
|
+
end
|
|
679
|
+
|
|
680
|
+
results
|
|
637
681
|
end
|
|
638
682
|
alias remove_mdm_profile unmanage_device
|
|
639
683
|
|
|
@@ -653,7 +697,11 @@ module Jamf
|
|
|
653
697
|
def unlock_user_account(targets, user, api: nil, cnx: Jamf.cnx)
|
|
654
698
|
cnx = api if api
|
|
655
699
|
|
|
656
|
-
|
|
700
|
+
data = {
|
|
701
|
+
commandType: UNLOCK_USER_ACCOUNT,
|
|
702
|
+
userName: user
|
|
703
|
+
}
|
|
704
|
+
send_mdm_command targets, data, cnx: cnx
|
|
657
705
|
end
|
|
658
706
|
|
|
659
707
|
# Send a delete_user command to one or more targets
|
|
@@ -661,15 +709,23 @@ module Jamf
|
|
|
661
709
|
# @param targets[String,Integer,Array<String,Integer>] @see .send_mdm_command
|
|
662
710
|
#
|
|
663
711
|
# @param user[String] the username of the acct to delete
|
|
712
|
+
# @param force[Boolean] should the user be deleted even if logged in
|
|
713
|
+
# @param all[Boolean] should all users be deleted
|
|
664
714
|
#
|
|
665
715
|
# @param cnx [Jamf::Connection] the API thru which to send the command
|
|
666
716
|
#
|
|
667
717
|
# @return (see .send_mdm_command)
|
|
668
718
|
#
|
|
669
|
-
def delete_user(targets, user, api: nil, cnx: Jamf.cnx)
|
|
719
|
+
def delete_user(targets, user = nil, force: false, all: false, api: nil, cnx: Jamf.cnx)
|
|
670
720
|
cnx = api if api
|
|
671
721
|
|
|
672
|
-
|
|
722
|
+
data = {
|
|
723
|
+
commandType: DELETE_USER,
|
|
724
|
+
userName: user,
|
|
725
|
+
force: force,
|
|
726
|
+
all: all
|
|
727
|
+
}
|
|
728
|
+
send_mdm_command targets, data, cnx: cnx
|
|
673
729
|
end
|
|
674
730
|
|
|
675
731
|
# Send an enable_remote_desktop command to one or more targets
|
|
@@ -683,7 +739,10 @@ module Jamf
|
|
|
683
739
|
def enable_remote_desktop(targets, api: nil, cnx: Jamf.cnx)
|
|
684
740
|
cnx = api if api
|
|
685
741
|
|
|
686
|
-
|
|
742
|
+
data = {
|
|
743
|
+
commandType: ENABLE_REMOTE_DESKTOP
|
|
744
|
+
}
|
|
745
|
+
send_mdm_command targets, data, cnx: cnx
|
|
687
746
|
end
|
|
688
747
|
|
|
689
748
|
# Send a disable_remote_desktop command to one or more targets
|
|
@@ -697,12 +756,18 @@ module Jamf
|
|
|
697
756
|
def disable_remote_desktop(targets, api: nil, cnx: Jamf.cnx)
|
|
698
757
|
cnx = api if api
|
|
699
758
|
|
|
700
|
-
|
|
759
|
+
data = {
|
|
760
|
+
commandType: DISABLE_REMOTE_DESKTOP
|
|
761
|
+
}
|
|
762
|
+
send_mdm_command targets, data, cnx: cnx
|
|
701
763
|
end
|
|
702
764
|
|
|
703
765
|
# Commands for mobile devices only
|
|
704
766
|
################################
|
|
705
767
|
|
|
768
|
+
# DEPRECATED: The Jamf Pro API no longer uses MDM commands to update inventory.
|
|
769
|
+
# It uses DDM.
|
|
770
|
+
#
|
|
706
771
|
# Send an update_inventory command to one or more targets
|
|
707
772
|
#
|
|
708
773
|
# @param targets[String,Integer,Array<String,Integer>] @see .send_mdm_command
|
|
@@ -711,10 +776,8 @@ module Jamf
|
|
|
711
776
|
#
|
|
712
777
|
# @return (see .send_mdm_command)
|
|
713
778
|
#
|
|
714
|
-
def update_inventory(
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
send_mdm_command targets, :update_inventory, cnx: cnx
|
|
779
|
+
def update_inventory(_targets, api: nil, cnx: Jamf.cnx)
|
|
780
|
+
raise Jamf::UnsupportedError, 'The Jamf Pro no longer uses an MDM command to update MobileDevice inventory.'
|
|
718
781
|
end
|
|
719
782
|
alias recon update_inventory
|
|
720
783
|
|
|
@@ -722,14 +785,20 @@ module Jamf
|
|
|
722
785
|
#
|
|
723
786
|
# @param targets[String,Integer,Array<String,Integer>] @see .send_mdm_command
|
|
724
787
|
#
|
|
788
|
+
# @param unlock_token[String] The unlock token from Jamf Pro
|
|
789
|
+
#
|
|
725
790
|
# @param cnx [Jamf::Connection] the API thru which to send the command
|
|
726
791
|
#
|
|
727
792
|
# @return (see .send_mdm_command)
|
|
728
793
|
#
|
|
729
|
-
def clear_passcode(targets, api: nil, cnx: Jamf.cnx)
|
|
794
|
+
def clear_passcode(targets, unlock_token:, api: nil, cnx: Jamf.cnx)
|
|
730
795
|
cnx = api if api
|
|
731
796
|
|
|
732
|
-
|
|
797
|
+
data = {
|
|
798
|
+
commandType: CLEAR_PASSCODE,
|
|
799
|
+
unlockToken: unlock_token
|
|
800
|
+
}
|
|
801
|
+
send_mdm_command targets, data, cnx: cnx
|
|
733
802
|
end
|
|
734
803
|
|
|
735
804
|
# Send an clear_restrictions_password command to one or more targets
|
|
@@ -743,7 +812,10 @@ module Jamf
|
|
|
743
812
|
def clear_restrictions_password(targets, api: nil, cnx: Jamf.cnx)
|
|
744
813
|
cnx = api if api
|
|
745
814
|
|
|
746
|
-
|
|
815
|
+
data = {
|
|
816
|
+
commandType: CLEAR_RESTRICTIONS_PASSWORD
|
|
817
|
+
}
|
|
818
|
+
send_mdm_command targets, data, cnx: cnx
|
|
747
819
|
end
|
|
748
820
|
|
|
749
821
|
# Send an enable_data_roaming command to one or more targets
|
|
@@ -757,7 +829,11 @@ module Jamf
|
|
|
757
829
|
def enable_data_roaming(targets, api: nil, cnx: Jamf.cnx)
|
|
758
830
|
cnx = api if api
|
|
759
831
|
|
|
760
|
-
|
|
832
|
+
data = {
|
|
833
|
+
commandType: SETTINGS,
|
|
834
|
+
dataRoaming: ENABLE_DATA_ROAMING
|
|
835
|
+
}
|
|
836
|
+
send_mdm_command targets, data, cnx: cnx
|
|
761
837
|
end
|
|
762
838
|
|
|
763
839
|
# Send andisable_data_roaming command to one or more targets
|
|
@@ -771,7 +847,11 @@ module Jamf
|
|
|
771
847
|
def disable_data_roaming(targets, api: nil, cnx: Jamf.cnx)
|
|
772
848
|
cnx = api if api
|
|
773
849
|
|
|
774
|
-
|
|
850
|
+
data = {
|
|
851
|
+
commandType: SETTINGS,
|
|
852
|
+
dataRoaming: DISABLE_DATA_ROAMING
|
|
853
|
+
}
|
|
854
|
+
send_mdm_command targets, data, cnx: cnx
|
|
775
855
|
end
|
|
776
856
|
|
|
777
857
|
# Send an enable_voice_roaming command to one or more targets
|
|
@@ -785,7 +865,11 @@ module Jamf
|
|
|
785
865
|
def enable_voice_roaming(targets, api: nil, cnx: Jamf.cnx)
|
|
786
866
|
cnx = api if api
|
|
787
867
|
|
|
788
|
-
|
|
868
|
+
data = {
|
|
869
|
+
commandType: SETTINGS,
|
|
870
|
+
voiceRoaming: ENABLE_VOICE_ROAMING
|
|
871
|
+
}
|
|
872
|
+
send_mdm_command targets, data, cnx: cnx
|
|
789
873
|
end
|
|
790
874
|
|
|
791
875
|
# Send a disable_voice_roaming command to one or more targets
|
|
@@ -799,7 +883,11 @@ module Jamf
|
|
|
799
883
|
def disable_voice_roaming(targets, api: nil, cnx: Jamf.cnx)
|
|
800
884
|
cnx = api if api
|
|
801
885
|
|
|
802
|
-
|
|
886
|
+
data = {
|
|
887
|
+
commandType: SETTINGS,
|
|
888
|
+
voiceRoaming: DISABLE_VOICE_ROAMING
|
|
889
|
+
}
|
|
890
|
+
send_mdm_command targets, data, cnx: cnx
|
|
803
891
|
end
|
|
804
892
|
|
|
805
893
|
# Commands for supervized mobile devices only
|
|
@@ -818,11 +906,17 @@ module Jamf
|
|
|
818
906
|
def device_name(targets, name, api: nil, cnx: Jamf.cnx)
|
|
819
907
|
cnx = api if api
|
|
820
908
|
|
|
821
|
-
|
|
909
|
+
data = {
|
|
910
|
+
commandType: SETTINGS,
|
|
911
|
+
deviceName: name
|
|
912
|
+
}
|
|
913
|
+
send_mdm_command targets, data, cnx: cnx
|
|
822
914
|
end
|
|
823
915
|
alias set_name device_name
|
|
824
916
|
alias set_device_name device_name
|
|
825
917
|
|
|
918
|
+
# TODO: Re-enable this when the wallpaper MDM commands are migrated to JPAPI
|
|
919
|
+
#
|
|
826
920
|
# Send a wallpaper command to one or more targets
|
|
827
921
|
#
|
|
828
922
|
# @param targets[String,Integer,Array<String,Integer>] @see .send_mdm_command
|
|
@@ -860,7 +954,21 @@ module Jamf
|
|
|
860
954
|
raise ArgumentError, 'Either wallpaper_id: or wallpaper_content must be provided'
|
|
861
955
|
end
|
|
862
956
|
|
|
863
|
-
|
|
957
|
+
targets = raw_targets_to_mgmt_ids targets, jamf_ids: true, cnx: cnx
|
|
958
|
+
cmd_xml = mdm_command_xml(command, opts, targets)
|
|
959
|
+
rsrc = 'mobiledevicecommands/command/Wallpaper'
|
|
960
|
+
|
|
961
|
+
xml_resp = cnx.c_post rsrc, cmd_xml
|
|
962
|
+
|
|
963
|
+
hash = {}
|
|
964
|
+
mds = REXML::Document.new(xml_resp).elements[DEVICE_COMMAND_ELEMENT].elements[DEVICE_LIST_ELEMENT]
|
|
965
|
+
mds.each_element do |md|
|
|
966
|
+
id = md.elements[DEVICE_ID_ELEMENT].text.to_i
|
|
967
|
+
status = md.elements[DEVICE_COMMAND_STATUS_ELEMENT].text
|
|
968
|
+
hash[id] = status
|
|
969
|
+
end
|
|
970
|
+
|
|
971
|
+
hash
|
|
864
972
|
end
|
|
865
973
|
alias set_wallpaper wallpaper
|
|
866
974
|
|
|
@@ -877,7 +985,11 @@ module Jamf
|
|
|
877
985
|
def passcode_lock_grace_period(targets, secs, api: nil, cnx: Jamf.cnx)
|
|
878
986
|
cnx = api if api
|
|
879
987
|
|
|
880
|
-
|
|
988
|
+
data = {
|
|
989
|
+
commandType: SETTINGS,
|
|
990
|
+
passcodeLockGracePeriod: secs
|
|
991
|
+
}
|
|
992
|
+
send_mdm_command targets, data, cnx: cnx
|
|
881
993
|
end
|
|
882
994
|
|
|
883
995
|
# Send a shut_down_device command to one or more targets
|
|
@@ -891,7 +1003,10 @@ module Jamf
|
|
|
891
1003
|
def shut_down_device(targets, api: nil, cnx: Jamf.cnx)
|
|
892
1004
|
cnx = api if api
|
|
893
1005
|
|
|
894
|
-
|
|
1006
|
+
data = {
|
|
1007
|
+
commandType: SHUT_DOWN_DEVICE
|
|
1008
|
+
}
|
|
1009
|
+
send_mdm_command targets, data, cnx: cnx
|
|
895
1010
|
end
|
|
896
1011
|
alias shutdown_device shut_down_device
|
|
897
1012
|
alias shut_down shut_down_device
|
|
@@ -899,16 +1014,33 @@ module Jamf
|
|
|
899
1014
|
|
|
900
1015
|
# Send a restart_device command to one or more targets
|
|
901
1016
|
#
|
|
1017
|
+
# @param rebuild_kernel_cache[Boolean] Rebuild the kernel cache on restart. Default is false
|
|
1018
|
+
#
|
|
1019
|
+
# @param kext_paths[Array<String>] An array of kext paths to rebuild the cache for. Default is nil
|
|
1020
|
+
#
|
|
1021
|
+
# @param notify_user[Boolean] Notify the user of the restart. Default is true
|
|
1022
|
+
#
|
|
902
1023
|
# @param targets[String,Integer,Array<String,Integer>] @see .send_mdm_command
|
|
903
1024
|
#
|
|
904
1025
|
# @param cnx [Jamf::Connection] the API thru which to send the command
|
|
905
1026
|
#
|
|
906
1027
|
# @return (see .send_mdm_command)
|
|
907
1028
|
#
|
|
908
|
-
def restart_device(targets, api: nil, cnx: Jamf.cnx)
|
|
1029
|
+
def restart_device(targets, rebuild_kernel_cache: false, kext_paths: nil, notify_user: true, api: nil, cnx: Jamf.cnx)
|
|
909
1030
|
cnx = api if api
|
|
910
1031
|
|
|
911
|
-
|
|
1032
|
+
data = {
|
|
1033
|
+
commandType: RESTART_DEVICE,
|
|
1034
|
+
rebuildKernelCache: rebuild_kernel_cache,
|
|
1035
|
+
notifyUser: notify_user
|
|
1036
|
+
}
|
|
1037
|
+
if kext_paths
|
|
1038
|
+
raise ArgumentError, 'kext_paths must be an Array of Strings' unless kext_paths.is_a?(Array) && kext_paths.all? { |kp| kp.is_a? String }
|
|
1039
|
+
|
|
1040
|
+
data[:kextPaths] = kext_paths
|
|
1041
|
+
end
|
|
1042
|
+
|
|
1043
|
+
send_mdm_command targets, data, cnx: cnx
|
|
912
1044
|
end
|
|
913
1045
|
alias restart restart_device
|
|
914
1046
|
|
|
@@ -923,7 +1055,11 @@ module Jamf
|
|
|
923
1055
|
def enable_app_analytics(targets, api: nil, cnx: Jamf.cnx)
|
|
924
1056
|
cnx = api if api
|
|
925
1057
|
|
|
926
|
-
|
|
1058
|
+
data = {
|
|
1059
|
+
commandType: SETTINGS,
|
|
1060
|
+
appAnalytics: ENABLE_APP_ANALYTICS
|
|
1061
|
+
}
|
|
1062
|
+
send_mdm_command targets, data, cnx: cnx
|
|
927
1063
|
end
|
|
928
1064
|
|
|
929
1065
|
# Send a disable_app_analytics command to one or more targets
|
|
@@ -937,7 +1073,11 @@ module Jamf
|
|
|
937
1073
|
def disable_app_analytics(targets, api: nil, cnx: Jamf.cnx)
|
|
938
1074
|
cnx = api if api
|
|
939
1075
|
|
|
940
|
-
|
|
1076
|
+
data = {
|
|
1077
|
+
commandType: SETTINGS,
|
|
1078
|
+
appAnalytics: DISABLE_APP_ANALYTICS
|
|
1079
|
+
}
|
|
1080
|
+
send_mdm_command targets, data, cnx: cnx
|
|
941
1081
|
end
|
|
942
1082
|
|
|
943
1083
|
# Send an enable_diagnostic_submission command to one or more targets
|
|
@@ -951,7 +1091,11 @@ module Jamf
|
|
|
951
1091
|
def enable_diagnostic_submission(targets, api: nil, cnx: Jamf.cnx)
|
|
952
1092
|
cnx = api if api
|
|
953
1093
|
|
|
954
|
-
|
|
1094
|
+
data = {
|
|
1095
|
+
commandType: SETTINGS,
|
|
1096
|
+
diagnosticSubmission: ENABLE_DIAGNOSTIC_SUBMISSION
|
|
1097
|
+
}
|
|
1098
|
+
send_mdm_command targets, data, cnx: cnx
|
|
955
1099
|
end
|
|
956
1100
|
|
|
957
1101
|
# Send a disable_diagnostic_submission command to one or more targets
|
|
@@ -965,7 +1109,11 @@ module Jamf
|
|
|
965
1109
|
def disable_diagnostic_submission(targets, api: nil, cnx: Jamf.cnx)
|
|
966
1110
|
cnx = api if api
|
|
967
1111
|
|
|
968
|
-
|
|
1112
|
+
data = {
|
|
1113
|
+
commandType: SETTINGS,
|
|
1114
|
+
diagnosticSubmission: DISABLE_DIAGNOSTIC_SUBMISSION
|
|
1115
|
+
}
|
|
1116
|
+
send_mdm_command targets, data, cnx: cnx
|
|
969
1117
|
end
|
|
970
1118
|
|
|
971
1119
|
# Send a enable_lost_mode command to one or more targets
|
|
@@ -980,9 +1128,9 @@ module Jamf
|
|
|
980
1128
|
#
|
|
981
1129
|
# @param footnote[String] Optional footnote to display on the lock screen
|
|
982
1130
|
#
|
|
983
|
-
# @param play_sound[Boolean] Play a sound when entering lost mode
|
|
1131
|
+
# @param play_sound[Boolean] Play a sound when entering lost mode.
|
|
984
1132
|
#
|
|
985
|
-
# @param enforce_lost_mode[Boolean] Re-enable lost mode when re-enrolled after wipe.
|
|
1133
|
+
# @param enforce_lost_mode[Boolean] Re-enable lost mode when re-enrolled after wipe. DEPRECATED: ignored by Jamf Pro API
|
|
986
1134
|
#
|
|
987
1135
|
# @param cnx [Jamf::Connection] the API thru which to send the command
|
|
988
1136
|
#
|
|
@@ -1000,15 +1148,18 @@ module Jamf
|
|
|
1000
1148
|
)
|
|
1001
1149
|
cnx = api if api
|
|
1002
1150
|
|
|
1003
|
-
|
|
1151
|
+
data = {
|
|
1152
|
+
commandType: ENABLE_LOST_MODE
|
|
1153
|
+
}
|
|
1154
|
+
data[:lostModeMessage] = message if message
|
|
1155
|
+
data[:lostModePhone] = phone if phone
|
|
1156
|
+
data[:lostModeFootnote] = footnote if footnote
|
|
1004
1157
|
|
|
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
|
|
1158
|
+
result = send_mdm_command targets, data, cnx: cnx
|
|
1159
|
+
return result unless play_sound
|
|
1010
1160
|
|
|
1011
|
-
|
|
1161
|
+
sound_result = play_lost_mode_sound targets, cnx: cnx
|
|
1162
|
+
{ enable_lost_mode: result, play_lost_mode_sound: sound_result }
|
|
1012
1163
|
end
|
|
1013
1164
|
|
|
1014
1165
|
# Send a play_lost_mode_sound command to one or more targets
|
|
@@ -1022,7 +1173,10 @@ module Jamf
|
|
|
1022
1173
|
def play_lost_mode_sound(targets, api: nil, cnx: Jamf.cnx)
|
|
1023
1174
|
cnx = api if api
|
|
1024
1175
|
|
|
1025
|
-
|
|
1176
|
+
data = {
|
|
1177
|
+
commandType: PLAY_LOST_MODE_SOUND
|
|
1178
|
+
}
|
|
1179
|
+
send_mdm_command targets, data, cnx: cnx
|
|
1026
1180
|
end
|
|
1027
1181
|
|
|
1028
1182
|
# Send a disable_lost_mode command to one or more targets
|
|
@@ -1036,7 +1190,10 @@ module Jamf
|
|
|
1036
1190
|
def disable_lost_mode(targets, api: nil, cnx: Jamf.cnx)
|
|
1037
1191
|
cnx = api if api
|
|
1038
1192
|
|
|
1039
|
-
|
|
1193
|
+
data = {
|
|
1194
|
+
commandType: DISABLE_LOST_MODE
|
|
1195
|
+
}
|
|
1196
|
+
send_mdm_command targets, data, cnx: cnx
|
|
1040
1197
|
end
|
|
1041
1198
|
|
|
1042
1199
|
# Flushing Commands
|
|
@@ -1057,16 +1214,16 @@ module Jamf
|
|
|
1057
1214
|
#
|
|
1058
1215
|
# @return [void]
|
|
1059
1216
|
#
|
|
1060
|
-
def flush_mdm_commands(targets, status
|
|
1217
|
+
def flush_mdm_commands(targets, status:, api: nil, cnx: Jamf.cnx)
|
|
1061
1218
|
cnx = api if api
|
|
1062
1219
|
|
|
1063
1220
|
raise Jamf::InvalidDataError, "Status must be one of :#{FLUSHABLE_STATUSES.keys.join ', :'}" unless FLUSHABLE_STATUSES.keys.include? status
|
|
1064
1221
|
|
|
1065
1222
|
status = FLUSHABLE_STATUSES[status]
|
|
1066
1223
|
|
|
1067
|
-
# TODO: add 'unmanaged_ok:' param to
|
|
1224
|
+
# TODO: add 'unmanaged_ok:' param to raw_targets_to_mgmt_ids method, so that we can
|
|
1068
1225
|
# use this to flush commands for unmanaged machines.
|
|
1069
|
-
target_ids =
|
|
1226
|
+
target_ids = raw_targets_to_mgmt_ids targets, cnx: cnx, jamf_ids: true, unmanaged_ok: true
|
|
1070
1227
|
|
|
1071
1228
|
command_flush_rsrc = "commandflush/#{self::MDM_COMMAND_TARGET}/id"
|
|
1072
1229
|
|
|
@@ -1108,11 +1265,23 @@ module Jamf
|
|
|
1108
1265
|
#
|
|
1109
1266
|
# @param passcode_or_message[String] a six-char passcode, required for computers & computergroups
|
|
1110
1267
|
# Or an optional message to display on mobiledevices & mobiledevicegroups
|
|
1268
|
+
# @param passcode[String] a six-char passcode
|
|
1269
|
+
#
|
|
1270
|
+
# @param message[String] An optional message to display
|
|
1271
|
+
#
|
|
1111
1272
|
#
|
|
1112
1273
|
# @return (see .send_mdm_command)
|
|
1113
1274
|
#
|
|
1114
|
-
def device_lock(passcode_or_message = '')
|
|
1115
|
-
|
|
1275
|
+
def device_lock(passcode_or_message = '', passcode: nil, message: nil, phoneNumber: nil)
|
|
1276
|
+
# backward compatibility: if only one arg given, decide if it's a passcode or message
|
|
1277
|
+
# explicit args override that
|
|
1278
|
+
if passcode_or_message.length == 6
|
|
1279
|
+
passcode ||= passcode_or_message
|
|
1280
|
+
elsif passcode_or_message.length > 0
|
|
1281
|
+
message ||= passcode_or_message
|
|
1282
|
+
end
|
|
1283
|
+
|
|
1284
|
+
self.class.device_lock @id, passcode: passcode, message: message, phoneNumber: phoneNumber, cnx: @cnx
|
|
1116
1285
|
end
|
|
1117
1286
|
alias lock device_lock
|
|
1118
1287
|
alias lock_device device_lock
|
|
@@ -1121,10 +1290,30 @@ module Jamf
|
|
|
1121
1290
|
#
|
|
1122
1291
|
# @param passcode[String] a six-char passcode, required for computers & computergroups
|
|
1123
1292
|
#
|
|
1293
|
+
# @param preserve_data_plan[Boolean] Should the data plan of the mobile device be preserved?
|
|
1294
|
+
#
|
|
1295
|
+
# @param obliterationBehavior[String] 'Default', 'DoNotObliterate', 'ObliterateWithWarning' or 'Always'
|
|
1296
|
+
#
|
|
1297
|
+
# @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 }
|
|
1298
|
+
#
|
|
1124
1299
|
# @return (see .send_mdm_command)
|
|
1125
1300
|
#
|
|
1126
|
-
def erase_device(
|
|
1127
|
-
|
|
1301
|
+
def erase_device(
|
|
1302
|
+
passcode: nil,
|
|
1303
|
+
preserve_data_plan: false,
|
|
1304
|
+
disallow_proximity_setup: false,
|
|
1305
|
+
obliteration_behavior: 'Default',
|
|
1306
|
+
return_to_service: nil
|
|
1307
|
+
)
|
|
1308
|
+
self.class.erase_device(
|
|
1309
|
+
@id,
|
|
1310
|
+
passcode: passcode,
|
|
1311
|
+
preserve_data_plan: preserve_data_plan,
|
|
1312
|
+
disallow_proximity_setup: disallow_proximity_setup,
|
|
1313
|
+
obliteration_behavior: obliteration_behavior,
|
|
1314
|
+
return_to_service: return_to_service,
|
|
1315
|
+
cnx: @cnx
|
|
1316
|
+
)
|
|
1128
1317
|
end
|
|
1129
1318
|
alias wipe_device erase_device
|
|
1130
1319
|
alias wipe_computer erase_device
|
|
@@ -1161,11 +1350,12 @@ module Jamf
|
|
|
1161
1350
|
# Send a delete_user command to this computer or group
|
|
1162
1351
|
#
|
|
1163
1352
|
# @param user[String] the username of the acct to delete
|
|
1164
|
-
#
|
|
1353
|
+
# @param force[Boolean] should the user be deleted even if logged in
|
|
1354
|
+
# @param all[Boolean] should all users be deleted #
|
|
1165
1355
|
# @return (see .send_mdm_command)
|
|
1166
1356
|
#
|
|
1167
|
-
def delete_user(user)
|
|
1168
|
-
self.class.delete_user @id, user, cnx: @cnx
|
|
1357
|
+
def delete_user(user, force: false, all: false)
|
|
1358
|
+
self.class.delete_user @id, user, force: force, all: all, cnx: @cnx
|
|
1169
1359
|
end
|
|
1170
1360
|
|
|
1171
1361
|
# Send an enable_remote_desktop command to this computer or group
|
|
@@ -1200,10 +1390,10 @@ module Jamf
|
|
|
1200
1390
|
|
|
1201
1391
|
# Send an clear_passcode command to this object
|
|
1202
1392
|
#
|
|
1393
|
+
# @param unlock_token[String] The unlock token from Jamf Pro
|
|
1203
1394
|
# @return (see .send_mdm_command)
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
self.class.clear_passcode @id, cnx: @cnx
|
|
1395
|
+
def clear_passcode(unlock_token:)
|
|
1396
|
+
self.class.clear_passcode @id, unlock_token: unlock_token, cnx: @cnx
|
|
1207
1397
|
end
|
|
1208
1398
|
|
|
1209
1399
|
# Send an clear_restrictions_password command to this object
|
|
@@ -1378,7 +1568,8 @@ module Jamf
|
|
|
1378
1568
|
phone: phone,
|
|
1379
1569
|
footnote: footnote,
|
|
1380
1570
|
play_sound: play_sound,
|
|
1381
|
-
enforce_lost_mode: enforce_lost_mode,
|
|
1571
|
+
enforce_lost_mode: enforce_lost_mode,
|
|
1572
|
+
cnx: @cnx
|
|
1382
1573
|
)
|
|
1383
1574
|
end
|
|
1384
1575
|
|
|
@@ -1411,6 +1602,6 @@ module Jamf
|
|
|
1411
1602
|
self.class.flush_mdm_commands @id, status: status, cnx: @cnx
|
|
1412
1603
|
end
|
|
1413
1604
|
|
|
1414
|
-
end # module
|
|
1605
|
+
end # module MacOSRedeployMgmtFramework
|
|
1415
1606
|
|
|
1416
|
-
end # module
|
|
1607
|
+
end # module Jamf
|