MaaS360¶
Table of Contents¶
Release Notes¶
v1.0.2¶
Converted workflows to Python3
v1.0.1¶
Added App Host support
v1.0.0¶
Initial Release
Overview¶
This package enables Mobile Device Management (MDM) actions from IBM Resilient.
The MaaS360 function package enables users to perform the following Mobile Device Management (MDM) actions:
Basic device search.
Get a list of software and versions installed ona device.
Locate a device.
Lock a device.
Wipe a device.
Cancel a pending wipe.
Stop app distribution across specific target devices.
Delete an app from the MaaS360 catalog.
Installation¶
Requirements¶
Resilient platform >=
v35.0.0
App Host >=
v1.2.132
(if using App Host)To setup up an App Host see: ibm.biz/res-app-host-setup
An Integration Server running
resilient_circuits>=35.0.0
(if using an Integration Server)To set up an Integration Server see: ibm.biz/res-int-server-guide
If using an API key account, minimum required permissions are:
Name
Permissions
Org Data
Read
Function
Read
Proxy supported: Yes
Install¶
To install or uninstall an App using the App Host see ibm.biz/res-install-app
To install or uninstall an Integration using the Integration Server see the ibm.biz/res-install-int
App Configuration¶
The following table describes the settings you need to configure in the app.config file. If using App Host, see the Resilient System Administrator Guide. If using the integration server, see the Integration Server Guide.
Config |
Required |
Example |
Description |
---|---|---|---|
maas360_host_url |
Yes |
|
The URL of your MaaS360 instance |
maas360_billing_id |
Yes |
|
The billing or account ID for your MaaS360 Account |
maas360_platform_id |
Yes |
|
The platform ID of your MaaS360 instance. Can be seen when you create an Access Key |
maas360_app_id |
Yes |
|
The App ID of the Access Key. For help on managing Access Keys for your MaaS360 instance refer to www.ibm.com/support/knowledgecenter/ |
maas360_app_version |
Yes |
|
The App Version when creating the Access Key. Generally |
maas360_app_access_key |
Yes |
|
The Access Key |
maas360_username |
Yes |
|
The username used to login to the MaaS360 instance |
maas360_password |
Yes |
|
The password for the account used to login to the MaaS360 instance |
maas360_request_timeout |
No |
|
The number of seconds to timeout after making a request to MaaS360. If you are seeing read |
maas360_basic_search_page_size |
Yes |
|
Limit number of devices returned at one time. Allowed page sizes: 25, 50, 100, 200, 250. Default value: 250 |
maas360_basic_search_match |
No |
|
When set to |
maas360_basic_search_sort_attribute |
No |
|
Sort attribute. Possible values: |
maas360_basic_search_sort_order |
No |
|
Sort Order. Possible values: |
maas360_wipe_device_notify_me |
Yes |
|
Whether to notify the administrator on successful device wipe. |
maas360_wipe_device_notify_user |
Yes |
|
Whether to notify the user on successful device wipe. |
maas360_wipe_device_notify_others |
Yes |
|
Comma separated list of other email addresses to notify on successful device wipe |
Custom Layouts¶
A new incident tab is needed in the Layouts section of the Resilient platform to contain two custom data tables like the screenshot below:
Function - MaaS360 Basic Search¶
Function searches for devices by Device Name, Username, Phone Number, Platform, Device Status and other Device Identifiers.
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
No |
|
Full MaaS360 Device ID string that needs to be searched for |
|
|
No |
|
Full Email address string that needs to be searched for |
|
|
No |
|
Full IMEI or MEID of the device |
|
|
No |
|
Partial (Starts with) or full Device Name string that needs to be searched for |
|
|
No |
|
Partial (Starts with) or full Phone Number that needs to be searched for |
|
|
No |
|
Partial (Starts with) or full Username string that needs to be searched for |
|
|
No |
|
Windows, Mac, iOS, BlackBerry, Android, Windows Mobile, Symbian, Windows Phone 7, Others |
Outputs:
results = {
"content": {
"count": 1,
"device": {
"appComplianceState": "In Compliance",
"customAssetNumber": "",
"deviceName": "dummy_device@gmail.com-STV100-1",
"deviceOwner": "",
"deviceStatus": "Active",
"deviceType": "Smartphone",
"emailAddress": "dummy_device@gmail.com",
"encryptionStatus": "Encryption Complete",
"firstRegisteredInEpochms": 1549629133338,
"imeiEsn": 351623070066166,
"installedDate": "2019-02-08T12:32:13",
"installedDateInEpochms": 1549629133338,
"isSupervisedDevice": False,
"jailbreakStatus": "No",
"lastMdmRegisteredInEpochms": 1549629133378,
"lastRegisteredInEpochms": 1549629133338,
"lastReported": "2019-04-23T16:11:23",
"lastReportedInEpochms": 1556035883843,
"maas360DeviceID": "Androiddeviceid",
"maas360ManagedStatus": "Enrolled",
"mailboxDeviceId": "",
"mailboxLastReported": "",
"mailboxLastReportedInEpochms": "",
"mailboxManaged": "",
"manufacturer": "blackberry",
"mdmMailboxDeviceId": "",
"model": "STV100-1",
"osName": "Android 6.0.1 (MMB29M)",
"osServicePack": "",
"osVersion": "6.0.1",
"ownership": "Corporate Owned",
"passcodeCompliance": "Compliant",
"phoneNumber": "",
"platformName": "Android",
"policyComplianceState": "In Compliance",
"ruleComplianceState": "",
"selectiveWipeStatus": "N/a",
"sourceID": 1,
"testDevice": False,
"udid": "Androiddeviceid",
"unifiedTravelerDeviceId": "Androiddeviceid",
"userDomain": "gmail.com",
"username": "dummy_device@gmail.com",
"wifiMacAddress": "a4:e4:b8:73:a1:93"
},
"pageNumber": 1,
"pageSize": 1
},
"inputs": {
"maas360_device_id": "Androiddeviceid",
"maas360_email": None,
"maas360_imei_meid": None,
"maas360_partial_device_name": None,
"maas360_partial_phone_no": None,
"maas360_partial_username": None,
"maas360_platform_name": None
},
"metrics": {
"execution_time_ms": 9864,
"host": "host",
"package": "fn-maas360",
"package_version": "1.0.0",
"timestamp": "2019-05-13 13:21:40",
"version": "1.0"
},
"raw": "raw_json_string",
"reason": None,
"success": True,
"version": "1.0"
}
Workflows
Example Pre-Process Script:
inputs.maas360_device_id = rule.properties.maas360_rule_device_id if rule.properties.maas360_rule_device_id is not None else inputs.maas360_device_id
inputs.maas360_partial_device_name = rule.properties.maas360_rule_device_name if rule.properties.maas360_rule_device_name is not None else inputs.maas360_partial_device_name
inputs.maas360_email = rule.properties.maas360_rule_email if rule.properties.maas360_rule_email is not None else inputs.maas360_email
inputs.maas360_imei_meid = rule.properties.maas360_rule_imei_meid if rule.properties.maas360_rule_imei_meid is not None else inputs.maas360_imei_meid
inputs.maas360_partial_phone_no = rule.properties.maas360_rule_phone_no if rule.properties.maas360_rule_phone_no is not None else inputs.maas360_partial_phone_no
inputs.maas360_platform_name = rule.properties.maas360_rule_platform_name if rule.properties.maas360_rule_platform_name is not None else inputs.maas360_platform_name
inputs.maas360_partial_username = rule.properties.maas360_rule_username if rule.properties.maas360_rule_username is not None else inputs.maas360_partial_username
Example Post-Process Script:
from java.util import Date
def add_row(device):
device_dt = incident.addRow("maas360_device_dt")
device_dt.maas360_timestamp = Date()
device_dt.maas360_deviceid = device.get("maas360DeviceID")
device_dt.maas360_devicename = device.get("deviceName")
device_dt.maas360_username = device.get("username")
device_dt.maas360_platformname = device.get("platformName")
device_dt.maas360_devicetype = device.get("deviceType")
device_dt.maas360_lastreported = device.get("lastReported")
device_dt.maas360_devicestatus = device.get("deviceStatus")
# Print empty string instead of None
def string_value(value):
return value if value is not None else ""
def add_results_note(inputs, number_devices_found):
noteText = u"""{} device/s found in MaaS360 database with search parameters:
- partialDeviceName: '{}'
- partialUsername: '{}'
- partialPhoneNumber: '{}'
- imeiMeid: '{}'
- platformName: '{}'
- maas360DeviceId: '{}'
- email: '{}'""".format(
number_devices_found,
string_value(inputs.get("maas360_partial_device_name")),
string_value(inputs.get("maas360_partial_username")),
string_value(inputs.get("maas360_partial_phone_no")),
string_value(inputs.get("maas360_imei_meid")),
string_value(inputs.get("maas360_platform_name").get("name")) if inputs.get("maas360_platform_name") else "",
string_value(inputs.get("maas360_device_id")),
string_value(inputs.get("maas360_email"))
)
incident.addNote(noteText)
########################
# Mainline starts here #
########################
if results and results.get("success"):
count = 0
content = results.get("content")
if content:
count = content.get("count")
if count > 0:
# Add a row for each Device found
devices_list = [content.get("device")] if count == 1 else content.get("device")
map(lambda device: add_row(device), devices_list)
# Write results to a Note
inputs = results.get("inputs")
add_results_note(inputs, count)
Function - MaaS360 Action¶
MaaS360 Function performs different actions based on the chosen Menu Item Rule.
Available actions are:
Locate Device
Get Software Installed
Lock Device
Wipe Device
Cancel Pending Wipe
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
Yes |
|
Action Type field is automatically set based on the chosen Workflow action. |
|
|
No |
|
Full MaaS360 Device ID string that needs to be searched for |
MaaS360 Action - Locate Device¶
Outputs:
results = {
"content": {
"actionStatus": 0,
"description": "The action was executed successfully on the device.",
"latitude": 25.005112,
"locatedTime": "2019-05-13 17:45:12.0",
"longitude": 121.541535,
"maas360DeviceID": "deviceid"
},
"inputs": {
"maas360_action_type": {
"id": 202,
"name": "Locate Device"
},
"maas360_device_id": "deviceid"
},
"metrics": {
"execution_time_ms": 951,
"host": "host",
"package": "fn-maas360",
"package_version": "1.0.0",
"timestamp": "2019-05-13 15:18:51",
"version": "1.0"
},
"raw": "raw_json_string",
"reason": None,
"success": True,
"version": "1.0"
}
Example Pre-Process Script:
inputs.maas360_device_id = artifact.value
Example Post-Process Script:
########################
# Mainline starts here #
########################
if results and results.get("success"):
content = results.get("content")
if content:
latitude = content.get("latitude")
longitude = content.get("longitude")
device_id = content.get("maas360DeviceID")
if latitude and longitude:
noteText = u"Current or last know location for Device ID {} is {} latitude, {} longitude.".format(device_id, latitude, longitude)
incident.addNote(noteText)
else:
noteText = u"There is no current or last know location available for Device ID {}.".format(device_id)
incident.addNote(noteText)
MaaS360 Action - Get Software Installed¶
Outputs:
results = {
"content": {
"deviceSw": [
{
"swAttrs": [
{
"key": "Application ID",
"type": "string",
"value": "com.fiberlink.maas360forios"
},
{
"key": "Version",
"type": "string",
"value": 3.70.111
},
{
"key": "AppDataSize",
"type": "string",
"value": 3.79
},
{
"key": "File Size",
"type": "string",
"value": 175.18
},
{
"key": "Installed by MDM",
"type": "string",
"value": "Manage Status"
}
],
"swName": "MaaS360"
},
{
"swAttrs": [
{
"key": "Application ID",
"type": "string",
"value": "com.blackberry.ddt.bugreporter"
},
{
"key": "Version",
"type": "string",
"value": 1
},
{
"key": "AppDataSize",
"type": "string",
"value": 0
},
{
"key": "File Size",
"type": "string",
"value": 0
},
{
"key": "Install Location",
"type": "string",
"value": "Internal"
}
],
"swName": "BlackBerry Bug Reporter"
}
],
"lastSoftwareDataRefreshDate": "2019-04-18T00:13:07",
"maas360DeviceID": "deviceid"
},
"inputs": {
"maas360_action_type": {
"id": 201,
"name": "Get Software Installed"
},
"maas360_device_id": "deviceid"
},
"metrics": {
"execution_time_ms": 13019,
"host": "host",
"package": "fn-maas360",
"package_version": "1.0.0",
"timestamp": "2019-05-13 13:48:43",
"version": "1.0"
},
"raw": "raw_json_string",
"reason": None,
"success": True,
"version": "1.0"
}
Example Pre-Process Script:
inputs.maas360_device_id = artifact.value
Example Post-Process Script:
from java.util import Date
def add_row(device_id, app_Name, app_version, app_id, refresh_date):
app_dt = incident.addRow("maas360_installed_software_datatable")
app_dt.maas360_app_timestamp = Date()
app_dt.maas360_app_device_id = device_id
app_dt.maas360_app_app_name = app_Name
app_dt.maas360_app_app_version = app_version
app_dt.maas360_app_app_id = app_id
app_dt.maas360_app_lastSoftwareDataRefreshDate = refresh_date
########################
# Mainline starts here #
########################
if results and results.get("success"):
content = results.get("content")
if content:
device_id = content.get("maas360DeviceID")
refresh_date = content.get("lastSoftwareDataRefreshDate")
found_apps = False
apps = content.get("deviceSw")
if apps:
for app in apps:
if app:
app_Name = app.get("swName")
app_attrs = app.get("swAttrs")
if app_Name and app_attrs:
app_version_attr = filter(lambda att: att["key"] == 'Version', app_attrs)
# filter returns a list [{u'type': u'string', u'key': u'Version', u'value': u'3.70.111'}]
app_version = str(app_version_attr[0].get("value")) if app_version_attr else "N/A"
app_app_id_attr = filter(lambda att: att["key"] == 'Application ID', app_attrs)
# filter returns a list [{u'type': u'string', u'key': u'Application ID', u'value': u'com.fiberlink.maas360forios'}]
app_id = app_app_id_attr[0].get("value") if app_app_id_attr else "N/A"
# write results in the app datatable
add_row(device_id, app_Name, app_version, app_id, refresh_date)
found_apps = True
if found_apps:
noteText = u"Installed software was found for the Device ID {} and saved in the MaaS360 Installed Software datatable".format(device_id)
incident.addNote(noteText)
else:
noteText = u"No installed software found for the Device ID {}".format(device_id)
incident.addNote(noteText)
MaaS360 Action - Lock Device¶
Outputs:
results = {
"content": {
"actionID": 128294549,
"actionStatus": 0,
"description": "The action was executed successfully on the device.",
"maas360DeviceID": "deviceid"
},
"inputs": {
"maas360_action_type": {
"id": 203,
"name": "Lock Device"
},
"maas360_device_id": "deviceid"
},
"metrics": {
"execution_time_ms": 558,
"host": "host",
"package": "fn-maas360",
"package_version": "1.0.0",
"timestamp": "2019-05-13 15:27:03",
"version": "1.0"
},
"raw": "raw_json_string",
"reason": None,
"success": True,
"version": "1.0"
}
Example Pre-Process Script:
inputs.maas360_device_id = artifact.value
Example Post-Process Script:
########################
# Mainline starts here #
########################
if results and results.get("success"):
content = results.get("content")
if content:
noteText = u"Lock Device for Device ID: {}. {}".format(content.get("maas360DeviceID"), content.get("description"))
incident.addNote(noteText)
MaaS360 Action - Wipe Device¶
Outputs:
results = {
"content": {
"actionID": 128294800,
"actionStatus": 0,
"description": "The action was executed successfully on the device.",
"maas360DeviceID": "deviceid"
},
"inputs": {
"maas360_action_type": {
"id": 205,
"name": "Cancel Pending Wipe"
},
"maas360_device_id": "deviceid"
},
"metrics": {
"execution_time_ms": 915,
"host": "host",
"package": "fn-maas360",
"package_version": "1.0.0",
"timestamp": "2019-05-13 15:30:52",
"version": "1.0"
},
"raw": "raw_json_string",
"reason": None,
"success": True,
"version": "1.0"
}
Example Pre-Process Script:
inputs.maas360_device_id = artifact.value
Example Post-Process Script:
########################
# Mainline starts here #
########################
if results and results.get("success"):
content = results.get("content")
if content:
noteText = u"Cancel Pending Wipe for Device ID: {}. {}".format(content.get("maas360DeviceID"), content.get("description"))
incident.addNote(noteText)
Function - MaaS360 Stop App Distribution¶
Function stops a specific distribution of an app on target devices.
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
No |
|
Unique ID of the application |
|
|
Yes |
|
Type of the app |
|
|
No |
|
MaaS360 Device Group ID |
|
|
No |
|
Full MaaS360 Device ID string that needs to be searched for |
|
|
Yes |
|
Target Devices |
Outputs:
results = {
"content": {
"description": "Distribution stopped successfully.",
"status": "Success"
},
"inputs": {
"maas360_app_id": "com.some.app",
"maas360_app_type": {
"id": 250,
"name": "iOS Enterprise Application"
},
"maas360_device_group_id": None,
"maas360_device_id": " deviceid",
"maas360_target_devices": {
"id": 352,
"name": "Specific Device"
}
},
"metrics": {
"execution_time_ms": 11353,
"host": "host",
"package": "fn-maas360",
"package_version": "1.0.0",
"timestamp": "2019-05-16 10:23:59",
"version": "1.0"
},
"raw": "{\"status\": \"Success\", \"description\": \"Distribution stopped successfully.\"}",
"reason": None,
"success": True,
"version": "1.0"
}
Workflows
Example Pre-Process Script:
inputs.maas360_app_type = rule.properties.maas360_rule_app_type if rule.properties.maas360_rule_app_type is not None else inputs.maas360_app_type
inputs.maas360_app_id = artifact.value
inputs.maas360_target_devices = rule.properties.maas360_target_devices if rule.properties.maas360_target_devices is not None else inputs.maas360_target_devices
inputs.maas360_device_id = rule.properties.maas360_rule_device_id if rule.properties.maas360_rule_device_id is not None else inputs.maas360_device_id
inputs.maas360_device_group_id = rule.properties.maas360_device_group_id if rule.properties.maas360_device_group_id is not None else inputs.maas360_device_group_id
Example Post-Process Script:
# Print empty string instead of None
def string_value(value):
return value if value is not None else ""
def add_results_note(inputs, response_desc):
noteText = u"""Stop App Distribution - {} for input params:
- appId: '{}'
- appType: '{}'
- targetDevices: '{}'
- deviceId: '{}'
- deviceGroupId: '{}'.""".format(
response_desc,
inputs.get("maas360_app_id"),
inputs.get("maas360_app_type").name,
inputs.get("maas360_target_devices").name,
string_value(inputs.get("maas360_device_id")),
string_value(inputs.get("maas360_device_group_id"))
)
incident.addNote(noteText)
########################
# Mainline starts here #
########################
if results and results.get("success"):
content = results.get("content")
if content:
# Write results to a Note
inputs = results.get("inputs")
add_results_note(inputs, content.get("description"))
Function - MaaS360 Delete App¶
Function stops all distributions of the app and deletes the app.
Inputs:
Name |
Type |
Required |
Example |
Tooltip |
---|---|---|---|---|
|
|
No |
|
Unique ID of the application |
|
|
Yes |
|
Type of the app |
Outputs:
results = {
"content": {
"description": "Application deleted successfully.",
"status": "Success"
},
"inputs": {
"maas360_app_id": "com.some.app",
"maas360_app_type": {
"id": 251,
"name": "iOS App Store Application"
}
},
"metrics": {
"execution_time_ms": 16402,
"host": "host",
"package": "fn-maas360",
"package_version": "1.0.0",
"timestamp": "2019-05-16 10:34:50",
"version": "1.0"
},
"raw": "{\"status\": \"Success\", \"description\": \"Application deleted successfully.\"}",
"reason": None,
"success": True,
"version": "1.0"
}
Workflows
Example Pre-Process Script:
inputs.maas360_app_type = rule.properties.maas360_rule_app_type if rule.properties.maas360_rule_app_type is not None else inputs.maas360_app_type
inputs.maas360_app_id = artifact.value
Example Post-Process Script:
# Print empty string instead of None
def string_value(value):
return value if value is not None else ""
def add_results_note(inputs, response_desc):
noteText = u"""Delete App - {} for input params:
- appId: '{}'
- appType: '{}'""".format(
response_desc,
inputs.get("maas360_app_id"),
inputs.get("maas360_app_type").name
)
incident.addNote(noteText)
########################
# Mainline starts here #
########################
if results and results.get("success"):
content = results.get("content")
if content:
# Write results to a Note
inputs = results.get("inputs")
add_results_note(inputs, content.get("description"))
Script - Example: Create Artifact for Device ID¶
Script creates an Artifact for MaaS360 Device ID value based on the selected MaaS360 Device datatable row.
Object: maas360_device_dt
Script Text:
# Create an Artifact for MaaS360 Device ID value based on the selected MaaS360 Device datatable row.
# Artifact description
artifact_description = u"""Created by MaaS360 Basic Search results for Device Name '{}', Username '{}', Platform name '{}', Device Type '{}'""".format(
row.maas360_devicename,
row.maas360_username,
row.maas360_platformname,
row.maas360_devicetype)
# Artifact type
artifact_type = "maas360_device_id"
# Artifact value
artifact_value = row.maas360_deviceid
# Create an Artifact
if artifact_value:
incident.addArtifact(artifact_type, artifact_value, artifact_description)
Script - Example: Create Artifact for App ID¶
Script creates an Artifact for MaaS360 App ID value based on the selected MaaS360 Installed Software datatable row.
Object: maas360_installed_software_datatable
Script Text:
# Create an Artifact for MaaS360 App ID value based on the selected MaaS360 Installed Software datatable row.
# Artifact description
artifact_description = u"""Created by MaaS360 Get Software Installed results for Device ID '{}', App Name '{}', App Version '{}'""".format(
row.maas360_app_device_id,
row.maas360_app_app_name,
row.maas360_app_app_version)
# Artifact type
artifact_type = "maas360_app_id"
# Artifact value
artifact_value = row.maas360_app_app_id
# Create an Artifact
if artifact_value:
incident.addArtifact(artifact_type, artifact_value, artifact_description)
Data Table - MaaS360 Installed Software datatable¶
API Name:¶
maas360_installed_software_datatable
Columns:¶
Column Name |
API Access Name |
Type |
Tooltip |
---|---|---|---|
App ID |
|
|
- |
App Name |
|
|
- |
App Version |
|
|
- |
Device ID |
|
|
- |
Last Data Refresh Date |
|
|
- |
Timestamp |
|
|
- |
Data Table - MaaS360 Device datatable¶
API Name:¶
maas360_device_dt
Columns:¶
Column Name |
API Access Name |
Type |
Tooltip |
---|---|---|---|
Device ID |
|
|
- |
Device Name |
|
|
- |
Device Status |
|
|
- |
Device Type |
|
|
- |
Last Reported |
|
|
- |
Platform Name |
|
|
- |
Timestamp |
|
|
- |
Username |
|
|
- |
Custom Artifact Types¶
Display Name |
API Access Name |
Description |
---|---|---|
MaaS360 App Id |
|
Unique ID of the application |
MaaS360 Device Id |
|
MaaS360 Device ID string |
Rules¶
Rule Name |
Object |
Workflow/Script Triggered |
---|---|---|
Example: MaaS360 Lock Device |
artifact |
|
Example: MaaS360 Cancel Pending Wipe |
artifact |
|
Example: MaaS360 Basic Search |
incident |
|
Example: MaaS360 Get Software Installed |
artifact |
|
Example: MaaS360 Stop App Distribution |
artifact |
|
Example: Create Artifact for Device ID |
maas360_device_dt |
|
Example: MaaS360 Locate Device |
artifact |
|
Example: MaaS360 Delete App |
artifact |
|
Example: MaaS360 Wipe Device |
artifact |
|
Example: Create Artifact for App ID |
maas360_installed_software_datatable |
|
Troubleshooting & Support¶
If using the app with an App Host, see the Resilient System Administrator Guide and the App Host Deployment Guide for troubleshooting procedures. You can find these guides on the IBM Knowledge Center, where you can select which version of the Resilient platform you are using.
If using the app with an integration server, see the Integration Server Guide
For Support¶
This is an IBM Supported app. Please search https://ibm.com/mysupport for assistance.