February 20, 2022

Uploading Windows apps using REST APIs

Welcome to day 20 of Let’s Git Commit(ted) to </Dev> Resources!  The topic for today will focus on using the skills you have developed in your Git Commit(ted) journey to automate a common task: Uploading Windows apps using the Workspace ONE Unified Endpoint Management (UEM) REST APIs! A common desire for learning developer-oriented skills, such as working with APIs, is to automate commonly reoccurring tasks. Automating tasks provides an ROI by reducing the time and errors from your IT administrators completing tedious tasks and enables them to focus on business-critical tasks. Automation also reduces the friction of adopting better practices, such as frequent application patching, to reduce device risk and increase employee satisfaction.  

Welcome to day 20 of Let’s Git Commit(ted) to </Dev> Resources!  A common desire for learning developer-oriented skills, such as working with APIs, is to automate commonly reoccurring tasks. Automating tasks provides an ROI by reducing the time and errors from your IT administrators completing tedious tasks and enables them to focus on business-critical tasks. Automation also reduces the friction of adopting better practices, such as frequent application patching, to reduce device risk and increase employee satisfaction.

The topic for today will focus on using the skills you have developed in your Git Commit(ted) journey to automate a common task: Uploading Windows apps using the Workspace ONE Unified Endpoint Management (UEM) REST APIs! You will utilize the Mobile Application Management (MAM) APIs to accomplish the following task:

  1. Optionally upload a local or remote image to use for the app icon
  2. Upload the application binary to Workspace ONE UEM
  3. Create an Internal Application using the uploaded binary

EUC-Samples to the Rescue!

Mike Nelson has an App Upload sample in the euc-samples GitHub repository available here. The UploadApp.ps1 PowerShell sample is a fantastic starting point for automating this process and I will be referencing and using this sample to demonstrate the APIs used for uploading and creating Windows applications.

EUC-Samples Setup

If you are using the UploadApp.ps1 sample referenced above, note that I have completed the following setup steps:

  1. I’ve cloned the euc-samples repository and navigated to the euc-samples/UEM-Samples/Utilities and Tools/Generic/AppUpload directory. Feel free to make a copy of the UploadApp.ps1 and Templates directory if you wish to keep the original files for reference.
  2. I opened the UploadApp.ps1 file and edited the following variables at the top of the script:
    1. $UserName: Provide an administrator account username that has permission to manage applications and API privileges.
    2. $Password: Provide the administrator account password.
    3. $ApiKey: Provide the API Key that will be used to authorize the API calls. The API Key is available from the Workspace ONE UEM administrator console under Groups & Settings > All Settings > System > Advanced > API > REST API.
    4.  $OrgGroupId: This sample sets the OrgGroupId to a particular org group for each execution. This can be obtained in a few ways:
      1. In the Workspace ONE UEM administrator console, navigate to the organization group you wish to upload the application to. Then navigate to Groups & Settings > Groups > Organization Groups > Details. The URL of this page is in the following format: https://{host}/AirWatch/#/OrganizationGroup/Details/Index/###. The integer value at the end of the URL is your OrgGroupId.
      2. You can use the REST APIs to query the IDs of organization groups. The GET system/groups/search?name={orgGroupName} API returns a list of organization groups that contains the provided name value. The OrgGroupId for each result is listed in the Id object under the Value property.
    5. $ServerURL: Provide the REST API URL for your environment without the trailing /api. You can retrieve the REST API URL through the Workspace ONE UEM administrator console by navigating to Groups & Settings > All Settings > System > Advanced > Site URLs. Find the REST API URL field and copy the FQDN without the trailing /api path, such as https://cn135.awmdm.com.
    6. $AppFilePath: Provide the full file path to an application binary (.exe, .msi) you wish to upload to Workspace ONE UEM.
    7. $AppMetaDataFilePath: I recommend making a copy of the sample.json file found in the /App Upload/Templates directory and naming it after the app you wish to upload, such as 7zip.json for the 7-Zip application. Since each individual application will have slightly modified metadata, such as the BlobId and HowToInstall parameters (more on these later), it’s worth separating them into unique files while you are learning the APIs and using the provided UploadApp.ps1 sample.
    8. (OPTINAL) $AppIconFilePath and $AppIconFileLink: Optionally provide a local image path using $AppIconFilePath OR provide a remote image URL using $AppIconFileLink. The script will not use both and prioritizes the $AppIconFilePath, so be sure to only populate the variable you intend to use.

I use the following files for my walkthrough:

  • Notepad++ 8.2 Installer: The latest Notepad++ installer binary at the time of writing is 8.2, which is available here.
  • Notepad++ png icon: A copy of the Notepad++ icon downloaded locally as a .png.
  • sample.json from the euc-samples /App Upload/Templates directory. I’ve duplicated this file and renamed it npp.json.
  • UploadApp.ps1 from the euc-samples App Upload directory as mentioned above. I’ve filled out the variables at the top of the script as described in step 2 above.
    • My $AppFilePath points to the Notepad++ 8.2 installer that I downloaded.
    • My $AppMetaDataFilePath points to the npp.json file that I duplicated from the sample.json file.
    • My $AppIconFilePath points to a local copy of the Notepad++ icon (in .png format) that I downloaded.
  • For reference, my UploadApp.ps1 variables are set as the following:

    Figure 1: UploadApp.ps1 variables
    Here are the UploadApp.ps1 variables from Figure 1 in copyable format:

 

### Variables ###
$UserName = '*******'
$Password = '*******'
$ApiKey = 'b2+u*************A94='
$OrgGroupId = 884
$ServerURL = 'https://cn###.awmdm.com'

$AppFilePath = 'C:\Projects\App Upload Example\npp.8.2.Installer.x64.exe'
$AppMetaDataFilePath = 'C:\Projects\App Upload Example\Templates\npp.json'

# To upload an app icon, either populate $AppIconFilePath with a local image file OR provide a link to a remote image file
# When using $AppIconFileLink, the Username and Password fields are only required if the remote file requires authentication to access
$AppIconFilePath = 'C:\Projects\App Upload Example\npp.png'
$AppIconFileLink = ''
$AppIconFileLinkUsername = ''
$AppIconFileLinkPassword = ''

# Set to 20 MB - 100 MB is the max recommended. For slower connections set to lower settings like 5MB
$ChunkSize = 20 * 1024 * 1024
 

Task 1: Optionally Upload the Local App Icon

To give our application an icon, we need to upload the local app icon as a blob, which allows UEM to reference this blob file as the icon associated with Notepad++. The following logic accomplishes this task:

  1. Load the image file bytes into a byte array.
    1. See UploadApp.ps1 lines 179 – 189 for an example.
  2. Call the POST /api/mam/blobs/uploadblob API to load the file as a blob into UEM.
    1. See UploadApp.ps1 lines 194-199 and the UploadBlob function as examples.
  3. Upon success, the response returns a uuid property for the blob that needs to be saved to reference in a later step. This associates the uploaded image file as our app icon when we upload the app binary to UEM.
    1. See UploadApp.ps1 line 202 and the response from the UploadBlob function as an example.

Additional points about the POST /api/mam/blobs/uploadblob API:

  • Remember that full API documentation can be viewed for your UEM version. The uploadblob API is located under MAM REST API V1 > API Reference > BlobsV1.
  • Additional information about the API parameters and supported file types can be found in the API documentation instructions linked above.
  • There are two required API parameters: filename and organizationGroupId. Although the other parameters may be optional based on your use case (local file vs. remote file), these two will always be included.

Although the POST /api/mam/blobs/uploadblob API can also be used to upload application files, such as our Notepad++ installer, there is a more efficient API for uploading larger application files by loading chunks of the file at a time. You’ll see this API in action in the next step. However, uploadblob is great for smaller assets, such as our image files.

Task 2: Upload the Local Application Installer

The next step is to upload the application installer file to Workspace ONE UEM. This is similar to the uploadblob process we used for the image, but there is a more efficient API for larger files: POST /mam/apps/internal/uploadchunk.

The uploadchunk API uploads fractions of a file at a time, dictated by the ChunkData property you specify in the post body request. The uploadchunk API is recommended for applications 2GB or larger in size and requires File Storage to be configured. This API is more involved than uploadblob, so let’s break down how it works. The required post body is as follows:

{
  "TransactionId": "GUID Value", (empty string on first call)
  "ChunkData": "QA==",
  "ChunkSequenceNumber": 1,
  "TotalApplicationSize": 10000,
  "ChunkSize": 5000
}

  • TransactionId is a string that is either empty on the first API request or provides the TransactionId (a GUID value) that was received from the previously completed POST /mam/apps/internal/uploadchunk. This TransactionId is how UEM combines the separately uploaded chunks into a single file once the file is fully uploaded.
  • ChunkData is a Base64 encoded string of the byte segment you are sending in this request body. In the above request body example, the application has a total size of 10,000 bytes and the ChunkSize is set to 5,000, so this ChunkData field needs to contain the first 5,000 bytes of the application in a Base64 encoded string.
  • ChunkSequenceNumber starts as 1 for each new request and is incremented by 1 for each new chunk of the file that is uploaded until the file has been fully uploaded.
  • TotalApplicationSize is the size of your application installer file in bytes.
  • ChunkSize is the number of bytes that the current uploadchunk API request is uploading.

In the AppUpload.ps1 example, remember that the $ChunkSize variable set at the top is responsible for determining the ChunkSize of the uploadchunk API request, which by default is set to 20 MB. This means 20 MB chunks of your application installer file will be uploaded at a time and sequenced together until the entire file has been uploaded.

Figure 2: ChunkSize

Here is the code from Figure 2 in copyable format:

 

# Set to 20 MB - 100 MB is the max recommended. For slower connections set to lower settings like 5MB
$ChunkSize = 20 * 1024 * 1024

The following logic accomplishes this task:

  1. Determine the ChunkSize you would like to use (recommended 20 MB – 100 MB).
    1. See UploadApp.ps1 line 33 for setting the ChunkSize.
  2. Using your application’s total size and the chunk size you wish to upload with each request, use the POST /mam/apps/internal/uploadchunk API and format the post body correctly.
    1. See UploadApp.ps1 lines 249 – 256 for setting up the initial properties (TransactionId is an empty string for the first request, ChunkSequenceNumber is 1, and reading in bytes from your application).
    2. See UploadApp.ps1 lines 261 -291 and the UploadChunk function to see how to continuously loop through the bytes of your file to upload your chunk size in sequential order. This requires that the TransactionId gets set to the returned TransactionId from the previous uploadchunk API response and that the ChunkSequenceNumber is incremented by 1 each time.
      Note: Don’t forget to Base64 encode your byte string for the ChunkData property!
  3. When the final uploadchunk API is completed and the entire application byte array has been uploaded, save the final transactionId that was returned from the uploadchunk API response. You will use this in the next step to make the application available in the Workspace ONE UEM administration console.
    1. See UploadApp.ps1 lines 296 – 300 for handling the final uploadchunk API call and setting the transactionId property in the npp.json metadata.

Task 3: Create an Internal Application using the Uploaded Application Binary

The final step is to create an Internal Application in Workspace ONE UEM by using the uploaded application binary file and the optionally uploaded application icon file. For this process, you will use the POST /api/mam/apps/internal/begininstall API and supply the following:

  • The final TransactionId of the uploaded application binary file from the uploadchunk API from Task 2
  • The blob UUID of the uploaded application image file from the uploadblob API from Task 1 (if completed)
  • A JSON object that determines the properties of the application, such as the application  name, version, supported models, the install and uninstall command details. You can either use the /mam/apps/internal/begininstall API documentation (API documentation > MAM REST API V1 > API Reference > InternalAppsV1 > begininstall) or the provided sample.json files in the project Templates folder.

The begininstall API will cause the application to be uploaded in the Workspace ONE UEM administration console under Apps & Books > Applications > Native > Internal, where it can be edited or assigned to users and devices.

The JSON object provided to the begininstall API has many properties, so let’s dive through each section to get a better understanding of what is required, what is optional, and what fields will be completed by the UploadApp.ps1 script.

BeginInstall JSON: Application Details

Open the provided sample.json file in the Templates directory.

Text, timeline</p>
<p>Description automatically generated

Figure 3: Application details

Here is the code from Figure 3 in copyable format:

{
    "BlobId": 0,
    "IconBlobUuId": “”,
    "TransactionId": “”,
    "ApplicationName": "TODO - Fill in",
    "PushMode": "0",
    "Description": "",
    "SupportEmail": "",
    "SupportPhone": "",
    "Developer": "",
    "DeveloperEmail": "",
    "DeveloperPhone": "",
    "AutoUpdateVersion": false,
    "LocationGroupId": 0,
    "AppVersion": "1.0.0",
    "EnableProvisioning": false,
    "FileName": "placeholder.zip",
    "SupportedProcessorArchitecture": "TODO - x86 or x64",
    "IsDependencyFile": false,
          ……
}

Green: Required, but UploadApp.ps1 will fill in details
Blue: Required, must be input manually by user
Yellow: Optional, but UploadApp.ps1 will fill in details (if applicable)
Not highlighted: Optional, must be input manually by the user if desired

The first few lines control the application details. If you inspect an Internal application in Workspace ONE UEM, you will notice that several of these fields map to the fields on the Details tab.

Required properties:

  • BlobId or TransactionId: If the uploadblob API was used to upload the application file, you would need to supply the blobId returned from the uploadblob API response. If the uploadchunk API was used to upload the application file, you would need to supply the final transactionId returned from the uploadchunk API response. For UploadApp.ps1, uploadchunk is used so the TransactionId will be populated.
  • ApplicationName: The name of the application which appears in Workspace ONE UEM to administrators and users.
  • LocationGroupId: The id of the location group where the application is uploaded to in Workspace ONE UEM.
  • FileName: The filename of the application installer that was uploaded.
  • SupportedProcessorArchitecture: x86 or x64, depending on what processor architecture your uploaded application installer was for.
  • IsDependencyFile: A Boolean value indicating whether this is a dependency file or not. Standalone application installers will use false as they are not a dependency file.

BeginInstall JSON: Device Type and Supported Models

Open the provided sample.json file in the Templates directory.

Text</p>
<p>Description automatically generated

Figure 4: Device type and supported models

Here is the code from Figure 4 in copyable format:

    "DeviceType": "WinRT",
    "SupportedModels": {
        "Model": [
            {
                "ModelId": 83,
                "ModelName": "Desktop"
            }
        ]
    },

Green: Required, but UploadApp.ps1 will fill in details
Blue: Required, must be input manually by user
Yellow: Optional, but UploadApp.ps1 will fill in details (if applicable)
Not highlighted: Optional, must be input manually by the user if desired

The next section determines which devices this application supports, in this case, Windows desktops.

Required properties:

  • DeviceType: The ID or Name of the device type of the application. See Appendix A for available values. In this case, since it is a Windows Desktop application, we are using the corresponding DeviceType of WinRT.
  • SupportedModels: This object contains an array of Model types which determines which devices can install this application. If more than one device type is supported, you can provide multiple Models in the array. In this case, we only provide a single model which is for the Windows Desktop (ID: 83, Name: Desktop). See Appendix B for available values.

BeginInstall JSON: Deployment Options: When to Install

Open the provided sample.json file in the Templates directory.

Table</p>
<p>Description automatically generated with medium confidence

Figure 5: Deployment options: when to install

Here is the code from Figure 5 in copyable format:

    "DeploymentOptions": {
        "WhenToInstall": {
            "DataContingencies": [],
            "DiskSpaceRequiredInKb": 0,
            "DevicePowerRequired": 0,
            "RamRequiredInMb": 0
        },
       
    },

Green: Required, but UploadApp.ps1 will fill in details
Blue: Required, must be input manually by user
Yellow: Optional, but UploadApp.ps1 will fill in details (if applicable)
Not highlighted: Optional, must be input manually by the user if desired

The next major section, DeploymentOptions, informs Workspace ONE UEM of a number of properties. The first section under DeploymentOptions is WhenToInstall, which is a list of requirements that must be satisfied before an install can begin. The necessary properties are already provided in the sample.json, but you can update the values to match any pre-installation requirements you may desire.

Required Properties for WhenToInstall:

  • DataContingencies: An array of DataContingencies (such as App Exists, File Exists, Registry Exists, etc.) that are required to be true before the install can start. This property is beyond the scope of this overview, so the sample.json has left this as the default, empty array.
  • DiskSpaceRequiredInKb: A pre-determined amount of disk space in kilobytes that is required. Useful if your installer file will download external content that is larger than the posted install file (such as Office365).
  • DevicePowerRequired: An integer from 0 – 100 indicating battery power percentage that the device must be at before starting the install. 0 ignores the battery percentage.
  • RamRequiredInMb: A pre-determined amount of memory (RAM) in Megabytes that must be present on the device before the install can start. This is useful to restrict lower-end devices from installing applications they cannot run due to memory requirements not being met.

BeginInstall JSON: Deployment Options: How to Install

Open the provided sample.json file in the Templates directory.

Text, application</p>
<p>Description automatically generated

Figure 6: Deployment options: how to install

Here is the code from Figure 6 in copyable format:

    "DeploymentOptions": {
       
        "HowToInstall": {
            "InstallContext": "Device",
            "InstallCommand": "npp.8.2.Installer.x64.exe /S",
            "AdminPrivileges": true,
            "DeviceRestart": "DoNotRestart",
            "RetryCount": 3,
            "RetryIntervalInMinutes": 5,
            "InstallTimeoutInMinutes": 30,
            "InstallerRebootExitCode": "",
            "InstallerSuccessExitCode": ""
        },
       
    },

Green: Required, but UploadApp.ps1 will fill in details
Blue: Required, must be input manually by user
Yellow: Optional, but UploadApp.ps1 will fill in details (if applicable)
Not highlighted: Optional, must be input manually by the user if desired

The next DeploymentOptions sub-section is HowToInstall. This informs Workspace ONE UEM of the commands that should be run to install the app and how it should be installed.

Required Properties for HowToInstall:

  • InstallContent: Device installs the application for all users on the device, User installs the application for the single user.
  • InstallCommand: The command that needs to be run to install the application. In the case of Notepad++, I call the installer filename with /S to indicate a silent install.
  • AdminPrivileges: A Boolean value that indicates whether Admin privileges are required for the install (true) or not required (false).
  • DeviceRestart: Dictates if the device needs to reboot after the install completes. The options are DoNotRestart, ForceRestart (a forced system-initiated restart), and RestartIfNeeded (a user-initiated restart).
  • RetryCount: Determines how many times the install should be re-attempted in the case of failure.
  • RetryIntervalInMinutes: Determines how long, in minutes, the process should wait to attempt a reinstall if it fails.
  • InstallTimeoutInMinutes: Determines how long, in minutes, the process should attempt to run the installer until we consider the install as a failure. Since silent installers may run into issues that the user cannot interact with and would need to be restarted after a period of time.
  • InstallerRebootExitCode and InstallerSuccessExitCode: If the installer provides an exit or success code when the installer cancels/exits or completes, those values can be provided here.

BeginInstall JSON: Deployment Options: When to Call Install Complete

Open the provided sample.json file in the Templates directory.

Figure 7: Deployment options: when to call install complete

Here is the code from Figure 7 in copyable format:

    "DeploymentOptions": {
       
        "WhenToCallInstallComplete": {
            "UseAdditionalCriteria": true,
            "IdentifyApplicationBy": "DefiningCriteria",
            "CriteriaList": [
                {
                    "CriteriaType": "FileExists",
                    "FileCriteria": {
                        "Path": "%ProgramFiles%\\Notepad++\\notepad++.exe",
                        "VersionCondition": "Any",
                        "MajorVersion": 0,
                        "MinorVersion": 0,
                        "RevisionNumber": 0,
                        "BuildNumber": 0,
                        "ModifiedOn": "1990/01/01"
                    },
                    "LogicalCondition": "End"
                }               
            ]
        }
    },

Green: Required, but UploadApp.ps1 will fill in details
Blue: Required, must be input manually by user
Yellow: Optional, but UploadApp.ps1 will fill in details (if applicable)
Not highlighted: Optional, must be input manually by the user if desired

The final sub-section of DeploymentOptions is WhenToCallInstallComplete, which informs Workspace ONE UEM if there are additional criteria that should be used to validate that an application installed successfully. There are two options here: DefiningCriteria or UsingCustomScript. Defining Criteria are checks that Workspace ONE UEM provides (App Exists, File Exists, RegistryExists, etc.) where custom scripts allows the admin to upload a script that reports back if the install is successful or not. Custom scripts are beyond the scope of this overview, and we will focus on using DefiningCriteria.

Required Properties for WhenToCallInstallComplete:

  • UseAdditionalCriteria: A Boolean value that indicates if you will supply additional criteria for WhenToCallInstallComplete. If you plan to use either DefiningCriteria or UsingCustomScript, this must be true.
  • IdentiyApplicationBy: As mentioned before, you can either use DefiningCriteria (Workspace ONE UEM provided logic to identify successful installs) or UsingCustomScript which sends a script you provide that will report back if the install was successful or not.
  • CriteriaList: When you use DefiningCriteria for the IdentifyApplicationBy property, you must provide an array of criteria objects in the CriteriaList array. The child objects of the CriteriaList will change based on the associated CriteriaType, which can be one of the following values:
    • AppExists: Checks if an application with a given application identifier is installed
    • AppDoesNotExist: Checks if an application with a given application identifier is not installed
    • FileExists: Checks if a file exists at a given file path
    • FileDoesNotExist: Checks if a file does not exist at a given file path
    • RegistryExists: Checks if a given registry path exists
    • RegistryDoesNotExist: Checks if a given registry path does not exist
  • VersionCondition: Each object in the CriteriaList will also contain a VersionCondition which lets you provide the MajorVersion, MinorVersion, RevisionNumber, and BuildNumber properties for comparison checks. An app version is formatted as MajorVersion.MinorVersion.RevisionNumber.BuildNumber (such as w.x.y.z) and the VersionCondition can be one of six values:
    • Any
    • EqualTo
    • GreaterThan
    • LessThan
    • NotEqualTo
    • GreaterThanOrEqualTo
    • LessThanOrEqualTo

The CriteriaList array objects change depending on which CriteriaType you provide. For this overview, we have provided two samples:

  1. sample.json in the Templates directory shows an AppExists criteria example
  2. The README.md for the Upload App sample shows a FileExists criteria example, which I am also showing in the sample above for Notepad++.

BeginInstall API

Whew! We went over a lot of details with the BeginInstall API, but hopefully that helps shine a light on how the JSON provided for this API maps to the configurations for Internal Apps seen in the Workspace ONE UEM administration console.

Once you have formatted your BeginInstall JSON appropriately, you can use the API to upload the application to Workspace ONE UEM. You can confirm that the application successfully installed by confirming the begininstall API response returned 200 OK with an Id and Uuid, or you can navigate to the Workspace ONE UEM administration console under Apps & Books > Applications > Native > Internal, and confirm the app installed.

Figure 8: Confirming the internal application in Workspace ONE UEM

Conclusion and Next Steps

With the AppUpload.ps1, you have now successfully completed the following tasks to upload an internal application to Workspace ONE UEM:

  1. Optionally upload an application icon file using the uploadblob MAM API
  2. Upload the application installer file using the uploadchunk MAM API
  3. Make the application installer and application icon available as an internal application using the begininstall API

For next steps, check out the following ideas:

  1. Use the API documentation and check out the MAM REST API V1 /apps/internal/{applicationId}/assignments API to check out how you can create (POST), modify (PUT), or delete (DELETE) assignments so that your intended users and groups get access to the newly installed internal application.
  2. Use the API documentation to review some of the begininstall properties we did not cover, especially if you are interested in other CriteriaList types or providing custom scripts to confirm installs were successful.

If you enjoyed this API overview and want to see more examples or a deeper dive – let us know!

Appendix A: Device Types

DeviceTypeID Name

1 WindowsMobile

2 Apple

5 Android

6 Athena

8 WindowsPhone

9 WindowsPc

10 AppleOsX

11 WindowsPhone8

12 WinRT

14 AppleTv

15 Qnx

16 ChromeBook

18 ChromeOS

19 IOTDevice

20 IOTGateway

21 Linux

Appendix B: Device Models

DeviceModelID DeviceTypeID Name LabelKey

1 2 iPhone Iphone

2 2 iPad Ipad

3 2 iPod Touch IpodTouch

5 5 Android Android

6 1 WindowsMobile WindowsMobile

8 8 WindowsPhone WindowsPhone

10 9 Windows PC WindowsPc

14 10 MacBook Pro MacBookPro

15 10 MacBook Air MacBookAir

16 10 Mac Mini MacMini

17 11 Windows Phone 8 WindowsPhone8

18 101 QLn220 Qln220

19 101 QLn320 Qln320

20 101 ZT220 ZT220

21 101 ZT230 Zt230

23 101 QLn420 Qln420

24 101 iMZ220 iMZ220

25 101 iMZ320 iMZ320

30 10 iMac iMac

31 10 Mac Pro MacPro

33 14 Apple TV AppleTv

34 101 ZD500R Zd500r

35 10 MacBook MacBook

36 101 ZT210 Zt210

37 15 QNX Qnx

38 102 B-EP4DL-G BEp4dlG

39 103 ADTP1 ADTP1

40 104 RL3 RL3

41 104 RL4 RL4

43 16 Google Chromebook ChromeBook

44 102 B-EP2DL-G BEp2dlG

45 101 ZD500 Zd500

46 101 ZT410 Zt410

47 101 ZT420 Zt420

48 104 RL3e RL3e

49 104 RL4e RL4e

52 101 ZQ510 ZQ510

53 101 ZQ520 ZQ520

54 11 Windows Phone 10 WindowsPhone10

56 104 LP3e Lp3e

57 201 Infinea BluePad InfineaBluePad

58 201 Infinea mPos InfineamPos

59 201 Infinea Tab M InfineaTabM

60 201 Infinea X InfineaX

61 201 Linea Pro 5 LineaPro5

62 201 Linea Pro 6 LineaPro6

63 102 BFV4DGS12QQRWL BFV4DGS12QQRWL

64 102 B-FP3D-GH40-QM-R BFP3DGH40QMR

65 18 ChromeOS ChromeOS

66 201 Infinea X2 InfineaX2

67 201 Infinea X Mini InfineaXMini

68 201 DPP 255 DPP255

69 201 DPP 450 DPP450

70 201 Linea Pro 7 LineaPro7

71 101 ZR638 ZR638

72 105 FP 90 III FP90III

73 101 ZD420 ZD420

74 101 ZD420-HC ZD420HC

75 101 ZD410 ZD410

76 101 ZD410-HC ZD410HC

77 105 TM-T88VI TMT88VI

78 105 TM-T88VI-iHub TMT88VIiHub

79 104 RP2 RP2

80 104 SAV2 SAV2

81 104 RP4 RP4

82 104 SAV4 SAV4

83 12 Desktop Desktop

84 19 IOTDevice IOTDevice

85 20 IOTGateway IOTGateway

86 12 HoloLens HoloLens

87 101 ZQ310 ZQ310

88 101 ZQ320 ZQ320

89 101 ZD620 ZD620

90 101 ZT510 ZT510

91 101 ZT610 ZT610

92 101 ZT620 ZT620

98 21 Linux Linux

99 21 Ubuntu Ubuntu

100 21 Debian Debian

101 21 Linux Mint LinuxMint

102 21 Raspbian Raspbian

103 21 Fedora Fedora

104 21 CentOS CentOS

105 21 Red Hat RedHat

106 21 openSUSE openSUSE

107 21 Gentoo Gentoo

108 21 Slackware Slackware

109 21 Alpine Alpine

110 21 Arch Linux Arch

111 21 Amazon Linux Amazon

112 21 TENS Linux Tens

Appendix C: Agenda

Make sure to check out the other blog posts in our 28-day series:

Filter Tags

Workspace ONE Workspace ONE Access Workspace ONE Intelligence Workspace ONE UEM Blog Technical Overview Intermediate Win10 and Windows Desktop Optimize