diff --git a/articles/mdm-commands.md b/articles/mdm-commands.md
index b1e5918c5e..17ab1b4207 100644
--- a/articles/mdm-commands.md
+++ b/articles/mdm-commands.md
@@ -1,29 +1,33 @@
# MDM commands
-In Fleet you can run MDM commands to take action on your macOS, iOS, iPadOS, and Windows hosts, like restarting the host, remotely.
+MDM commands can be sent to macOS, iOS / iPadOS and Windows hosts managed in Fleet using the following general steps:
-## Custom commands
+1. Create a payload that functions as the MDM command.
+2. Choose a target host, or, a set of target hosts on which to run the MDM command.
+3. Execute the MDM command by using the `fleetctl` command line interface (CLI) or by sending the payload in a Fleet API call.
+4. If needed, verify the MDM command result with an additional `fleetctl` command or API call.
-You can run custom commands and view a specific command's results using the `fleetctl` command-line interface.
+### Step 1: Create an MDM command payload
-To run a custom command, we will do the following steps:
+An MDM command payload can be created in mulitple ways.
-1. Create a `.xml` with the request payload
-2. Choose a target host
-3. Run the command using `fleetctl`
-4. View our command's results using `fleetctl`
+For Apple devices, the payload is a `.plist` that can be copied like this example from [Apple's developer documentation](https://developer.apple.com/documentation/devicemanagement/remove-profile-command), created with the [iMazing Profile Editor](https://imazing.com/profile-editor) or exported from a 3rd party MDM solution.
-### Step 1: Create an XML file
+For Windows, the payload is standard `xml` and command options can be referenced in the [Microsoft CSP Policy docuementation](https://learn.microsoft.com/en-us/windows/client-management/mdm/policy-configuration-service-provider).
You can run any command supported by [Apple's MDM protocol](https://developer.apple.com/documentation/devicemanagement/commands_and_queries) or [Microsoft's MDM protocol](https://learn.microsoft.com/en-us/windows/client-management/mdm/).
-> The lock and wipe commands are only available in Fleet Premium
+The end result simply needs to be a standard, plain text file with the correct key / values for obtaining the intended result on the host device.
-For example, to restart a macOS host, we'll use the "Restart a Device" command documented by Apple [here](https://developer.apple.com/documentation/devicemanagement/restart_a_device#3384428).
+> Lock and wipe commands are only available in Fleet Premium.
-First, we'll need to create a `restart-device.xml` file locally with this payload:
+### Examples
-```xml
+To restart a macOS host, we can use the "Restart a Device" MDM command documented by Apple [here](https://developer.apple.com/documentation/devicemanagement/restart_a_device#3384428).
+
+Below is the text to be used as the MDM command payload. Save it as a file and name it something like `apple-restart-device.xml`.
+
+```
@@ -37,11 +41,11 @@ First, we'll need to create a `restart-device.xml` file locally with this payloa
```
-To restart a Windows host, we'll use the "Reboot" command documented by Microsoft [here](https://learn.microsoft.com/en-us/windows/client-management/mdm/reboot-csp).
+To restart a Windows host, we can use the "Reboot" command documented by Microsoft [here](https://learn.microsoft.com/en-us/windows/client-management/mdm/reboot-csp).
-The `restart-device.xml` file will have this payload instead:
+Below is the text to be used as the MDM command payload. Save it as a file and name it something like `windows-restart-device.xml`.
-```xml
+```
-
@@ -56,34 +60,151 @@ The `restart-device.xml` file will have this payload instead:
```
+To prepare an MDM command payload for use with the Fleet API, generate a UUID to be used as the `CommandUUID`, e.g.,
+
+In Terminal, execute the following command:
+
+```
+% uuidgen
+16F4301E-7A88-42AD-8523-A2F73F9D38FA
+```
+
+> It's not necessary to add the `CommandUUID` to the MDM command payload, but, already having it available makes it's easier and quicker to verify the MDM command result if a check is needed.
+
+A `.plist` with the `CommandUUID` key / value added will look something like this:
+
+```
+
+
+
+
+ Command
+
+ Identifier
+ com.some.profile
+ RequestType
+ RemoveProfile
+
+ CommandUUID
+ 16F4301E-7A88-42AD-8523-A2F73F9D38FA
+
+
+```
+
### Step 2: Choose a target host
-To run a command, we need to specify a target host by hostname.
+Run the `fleetctl get hosts --mdm` command to get a list of hosts that are enrolled in Fleet and have MDM enabled. This may not be practical in Fleet environments with a large number hosts without using command line tools to parse the output, e.g.,
-1. Run the `fleetctl get hosts --mdm` command to get a list of hosts that are enrolled to Fleet and have MDM turned on.
-2. Find your target host's hostname. You'll need this hostname to run the command.
+Use something like `grep` with `fleetctl`:
-### Step 3: Run the command
+```
+% fleetctl get hosts --mdm | grep -i 'someSearchStringHere'
+Client Version: 4.67.3
+Server Version: 4.67.3
+| 1B848BE8-some-uuid | someComputer | darwin | 5.17.0 | online |
+| 08C7634C-some-uuid | someOtherComputer | windows | 5.17.0 | online |
+```
-1. Run the `fleetctl mdm run-command --payload=restart-device.xml --hosts=hostname ` command.
+Or, something like `jq` for API output:
-> Replace the --payload and --hosts flags with your XML file and hostname respectively.
+```
+% curl -LSs \
+--request GET \
+--header 'Accept: application/json' \
+--header "Authorization: Bearer $fleet_key" \
+"$fleet_url/api/v1/fleet/hosts" | jq '.hosts[] | select(.computer_name | contains("someSearchStringHere"))'
+```
-2. Look at the on-screen information. In the output you'll see the command to see results.
+> You will need a [Fleet API token](https://fleetdm.com/docs/rest-api/rest-api#retrieve-your-api-token) in your `fleetctl` configuration or for any interaction with the Fleet API to work.
-### Step 4: View the command's results
+### Step 3: Execute the MDM command
-1. Run the `fleetctl get mdm-command-results --id=`
-2. Look at the on-screen information.
+To deliver the MDM command payload with `fleetctl`, use something like the following that:
-## List recent commands
+- references the MDM command payload file created above, and
+- references the intended host targets, e.g.,
-You can view a list of the 1,000 latest commands:
+`fleetctl mdm run-command --payload='apple-restart-device.xml' --hosts='someHostname'`
-1. Run `fleetctl get mdm-commands`
-2. View the list of latest commands, most recent first, along with the timestamp, targeted hostname, command type, execution status and command ID.
+For targeting multiple hosts, the `--hosts` option can be populated with comma-separated values.
-The command ID can be used to view command results as documented in [step 4 of the previous section](#step-4-view-the-commands-results).
+To prepare the MDM command payload for execution in a Fleet API call, it must be base64-encoded. This is true for Apple and Windows MDM command payloads. E.g., to encode the `.plist` in Terminal:
+
+```
+% echo '
+
+
+
+ Command
+
+ Identifier
+ com.some.profile
+ RequestType
+ RemoveProfile
+
+ CommandUUID
+ 16F4301E-7A88-42AD-8523-A2F73F9D38FA
+
+' | base64
+PD94bWwgdmVyc2lvbj0iMS4wIiBlSomeMorebase64blahblahblah...
+```
+
+Then, to deliver the MDM command payload via the Fleet API, use a command that conforms to the `curl` example below. (This can be achieved with any programmatic solution, e.g., python `requests` or `urllib.request`).
+
+```
+% fleet_key='yourfleetAPItoken'
+% fleet_url='https://your.url.com'
+% /usr/bin/curl -LSs \
+--request POST \
+--header 'Content-Type: application/json' \
+--header "Authorization: Bearer $fleet_key" \
+--data '{"command":"PD94bWwgdmVyc2lvbj0iMS4wIiBlSomeMorebase64blahblahblah...","host_uuids":["some-host-uuid"]}' \
+"$fleet_url/api/v1/fleet/commands/run"
+```
+
+For targeting multiple hosts, the `"host_uuids"` key / value is a json array that can be populated with multiple host uuid values, e.g.,
+
+`"host_uuids":["some-host-uuid-1","some-host-uuid-2","some-host-uuid-3"]`
+
+### Step 4: Verify the MDM command result
+
+To verify the MDM command result with `fleetctl`, use something like the command below:
+
+`fleetctl get mdm-command-results --id=`
+
+If you generated the `CommandUUID`, add that value in the `--id` field. If you did not generate a command ID, one will be added to the MDM command by Fleet and it should appear in a succesful response after execution or in the MDM command results stored in Fleet.
+
+To verify the MDM command result with the Fleet API, use a command that conforms to the `curl` example below:
+
+```
+% /usr/bin/curl -LSs \
+--request GET \
+--header 'Accept: application/json' \
+--header "Authorization: Bearer $fleet_key" \
+"$fleet_url/api/v1/fleet/commands/results?command_uuid=16F4301E-7A88-42AD-8523-A2F73F9D38FA"
+```
+
+> The `?command_uuid=` parameter appended to the URL is populated with the same `CommandUUID` string that was used to populate the `CommandUUID` key / value in the base64-encoded `.plist` in Step 1.
+
+## Troubleshooting
+
+You can view a list of the 1,000 most recent MDM commands executed in Fleet by running:
+
+`fleetctl get mdm-commands`
+
+The output will be sorted by "most recent first" and will include timestamp, targeted hostname, command type, execution status and command ID.
+
+The command ID can be used to view MDM command results as documented in Step 4.
+
+You can also get this list of MDM commands from the Fleet API with:
+
+```
+% /usr/bin/curl -LSs \
+--request GET \
+--header 'Accept: application/json' \
+--header "Authorization: Bearer $fleet_key" \
+"$fleet_url/api/v1/fleet/commands/results"
+```