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.
@@ -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
- # Mixin Modules
12
- #####################################
9
+ module Jamf
13
10
 
14
- # This module provides the ability to work with MDM commands for objects that
15
- # can receive them.
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 = 'DeleteUser'.freeze
60
- UNLOCK_USER_ACCOUNT = 'UnlockUserAccount'.freeze
61
- ENABLE_REMOTE_DESKTOP = 'EnableRemoteDesktop'.freeze
62
- DISABLE_REMOTE_DESKTOP = 'DisableRemoteDesktop'.freeze
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 = 'Settings'.freeze
67
- CLEAR_PASSCODE = 'ClearPasscode'.freeze
68
- UPDATE_INVENTORY = 'UpdateInventory'.freeze
69
- CLEAR_RESTRICTIONS_PASSWORD = 'ClearRestrictionsPassword'.freeze
70
- ENABLE_DATA_ROAMING = 'SettingsEnableDataRoaming'.freeze
71
- DISABLE_DATA_ROAMING = 'SettingsDisableDataRoaming'.freeze
72
- ENABLE_VOICE_ROAMING = 'SettingsEnableVoiceRoaming'.freeze
73
- DISABLE_VOICE_ROAMING = 'SettingsDisableVoiceRoaming'.freeze
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 = 'PasscodeLockGracePeriod'.freeze
84
+ PASSCODE_LOCK_GRACE_PERIOD = 'passcodeLockGracePeriod'
78
85
 
79
86
  # supervised devices
80
87
 
81
- WALLPAPER = 'Wallpaper'.freeze
82
- DEVICE_NAME = 'DeviceName'.freeze
83
- SHUTDOWN_DEVICE = 'ShutDownDevice'.freeze
84
- RESTART_DEVICE = 'RestartDevice'.freeze
85
- ENABLE_LOST_MODE = 'EnableLostMode'.freeze
86
- DISABLE_LOST_MODE = 'DisableLostMode'.freeze
87
- DEVICE_LOCATION = 'DeviceLocation'.freeze
88
- PLAY_LOST_MODE_SOUND = 'PlayLostModeSound'.freeze
89
- ENABLE_APP_ANALYTICS = 'SettingsEnableAppAnalytics'.freeze
90
- DISABLE_APP_ANALYTICS = 'SettingsDisableAppAnalytics'.freeze
91
- ENABLE_DIAGNOSTIC_SUBMISSION = 'SettingsEnableDiagnosticSubmission'.freeze
92
- DISABLE_DIAGNOSTIC_SUBMISSION = 'SettingsDisableDiagnosticSubmission'.freeze
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
- SHUTDOWN_DEVICE,
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: SHUTDOWN_DEVICE,
205
- shutdown_device: SHUTDOWN_DEVICE,
206
- shut_down: SHUTDOWN_DEVICE,
207
- shutdown: SHUTDOWN_DEVICE,
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'.freeze
251
+ PENDING_STATUS = 'Pending'
245
252
 
246
253
  # the status to flush for 'failed'
247
- FAILED_STATUS = 'Failed'.freeze
254
+ FAILED_STATUS = 'Failed'
248
255
 
249
256
  # the status to flush for both pending and failed
250
- PENDINGFAILED_STATUS = 'Pending+Failed'.freeze
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'.freeze
265
+ BLANK_PUSH_RESULT = 'Command sent'
259
266
 
260
267
  # xml elements
261
268
 
262
- GENERAL_ELEMENT = 'general'.freeze
263
- COMMAND_ELEMENT = 'command'.freeze
264
- TARGET_ID_ELEMENT = 'id'.freeze
269
+ GENERAL_ELEMENT = 'general'
270
+ COMMAND_ELEMENT = 'command'
271
+ TARGET_ID_ELEMENT = 'id'
265
272
 
266
- COMPUTER_COMMAND_ELEMENT = 'computer_command'.freeze
267
- COMPUTER_ID_ELEMENT = 'computer_id'.freeze
268
- COMPUTER_COMMAND_UDID_ELEMENT = 'command_uuid'.freeze
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'.freeze
271
- DEVICE_LIST_ELEMENT = 'mobile_devices'.freeze
272
- DEVICE_ID_ELEMENT = 'id'.freeze
273
- DEVICE_COMMAND_STATUS_ELEMENT = 'status'.freeze
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 all it, have
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 or a target, call the matching instance method
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, command, opts: {}, api: nil, cnx: Jamf.cnx)
347
+ def send_mdm_command(targets, command_data, api: nil, cnx: Jamf.cnx)
336
348
  cnx = api if api
337
349
 
338
- command = validate_command(command)
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
- cmd_xml = mdm_command_xml(command, opts, targets)
345
-
346
- if JSS.devmode?
347
- puts "Sending XML:\n"
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
- # 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
358
+ puts "Sending data:\n#{data}" if JSS.devmode?
400
359
 
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
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 computers or mobile devices.
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 raw_targets_to_ids(targets, expand_groups: true, unmanaged_ok: false, api: nil, cnx: Jamf.cnx)
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
- # make sure its an array of ids
436
- targets.map! do |md|
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
- id
441
- end # map!
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
- # expand group members if needed
444
- if expand_groups && GROUP_TARGETS.include?(self::MDM_COMMAND_TARGET)
445
- target_ids = []
446
- targets.each { |group_id| target_ids += fetch(id: group_id).member_ids }
447
- targets = target_ids
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
- targets.each do |target_id|
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 # unles
411
+ end # unless
461
412
 
462
- targets
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
- # Generate the XML to send to the API, sending the MDM command to the targets
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 (see .send_mdm_command)]
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
- send_mdm_command targets, :blank_push, cnx: cnx
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, required for computers & computergroups
574
+ # @param passcode[String] a six-char passcode
565
575
  #
566
- # @param message[String] An optional message to display on mobiledevices & mobiledevicegroups
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: '', message: nil, api: nil, cnx: Jamf.cnx)
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
- case self::MDM_COMMAND_TARGET
576
- when *COMPUTER_TARGETS
577
- raise Jamf::InvalidDataError, 'Locking computers requires a 6-character String passcode' unless passcode.size == 6
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
- opts = { passcode: passcode }
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 passcode, required for computers & computergroups
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(targets, passcode: '', preserve_data_plan: false, api: nil, cnx: Jamf.cnx)
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
- case self::MDM_COMMAND_TARGET
605
- when *COMPUTER_TARGETS
606
- raise Jamf::InvalidDataError, 'Erasing computers requires a 6-character String passcode' unless passcode.size == 6
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
- opts = { passcode: passcode }
609
- when *DEVICE_TARGETS
610
- opts = {}
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 (see .send_mdm_command)
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
- send_mdm_command targets, :unmanage_device, cnx: cnx
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
- send_mdm_command targets, :unlock_user_account, opts: { user_name: user }, cnx: cnx
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
- send_mdm_command targets, :delete_user, opts: { user_name: user }, cnx: cnx
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
- send_mdm_command targets, :enable_remote_desktop, cnx: cnx
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
- send_mdm_command targets, :disable_remote_desktop, cnx: cnx
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(targets, api: nil, cnx: Jamf.cnx)
715
- cnx = api if api
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
- send_mdm_command targets, :clear_passcode, cnx: cnx
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
- send_mdm_command targets, :clear_restrictions_password, cnx: cnx
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
- send_mdm_command targets, :enable_data_roaming, cnx: cnx
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
- send_mdm_command targets, :disable_data_roaming, cnx: cnx
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
- send_mdm_command targets, :enable_voice_roaming, cnx: cnx
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
- send_mdm_command targets, :disable_voice_roaming, cnx: cnx
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
- send_mdm_command targets, :device_name, opts: { device_name: name }, cnx: cnx
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
- send_mdm_command targets, :wallpaper, opts: opts, cnx: cnx
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
- send_mdm_command targets, :passcode_lock_grace_period, opts: { passcode_lock_grace_period: secs }, cnx: cnx
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
- send_mdm_command targets, :shut_down_device, cnx: cnx
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
- send_mdm_command targets, :restart_device, cnx: cnx
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
- send_mdm_command targets, :enable_app_analytics, cnx: cnx
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
- send_mdm_command targets, :disable_app_analytics, cnx: cnx
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
- send_mdm_command targets, :enable_diagnostic_submission, cnx: cnx
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
- send_mdm_command targets, :disable_diagnostic_submission, cnx: cnx
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. Default is false
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
- raise ArgumentError, 'Either message: or phone_number: must be provided' unless message || phone
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
- opts = { always_enforce_lost_mode: enforce_lost_mode }
1006
- opts[:lost_mode_message] = message if message
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
- send_mdm_command targets, :enable_lost_mode, opts: opts, cnx: cnx
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
- send_mdm_command targets, :play_lost_mode_sound, cnx: cnx
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
- send_mdm_command targets, :disable_lost_mode, cnx: cnx
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: nil, api: nil, cnx: Jamf.cnx)
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 raw_targets_to_ids method, so that we can
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 = raw_targets_to_ids targets, cnx: cnx, expand_groups: false, unmanaged_ok: true
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
- self.class.device_lock @id, passcode: passcode_or_message, message: passcode_or_message, cnx: @cnx
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(passcode = '', preserve_data_plan: false)
1127
- self.class.erase_device @id, passcode: passcode, preserve_data_plan: preserve_data_plan, cnx: @cnx
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
- def clear_passcode
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 device_name(name)
1454
+ def set_device_name(name)
1263
1455
  self.class.device_name @id, name, cnx: @cnx
1264
1456
  end
1265
- alias set_name device_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, cnx: @cnx
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 MDM
1606
+ end # module MacOSRedeployMgmtFramework
1415
1607
 
1416
- end # module
1608
+ end # module Jamf