mirror of
https://github.com/fleetdm/fleet
synced 2026-05-24 09:28:54 +00:00
Update mdm-commands.md (#29252)
Top down rewrite of the MDM command article with the intended purpose of giving a clear example on using the API to deliver an MDM command in addition to using fleetctl.
This commit is contained in:
parent
7c69c69728
commit
5e8c5a52f3
1 changed files with 152 additions and 31 deletions
|
|
@ -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`.
|
||||
|
||||
```
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
|
|
@ -37,11 +41,11 @@ First, we'll need to create a `restart-device.xml` file locally with this payloa
|
|||
</plist>
|
||||
```
|
||||
|
||||
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
|
||||
```
|
||||
<Exec>
|
||||
<Item>
|
||||
<Target>
|
||||
|
|
@ -56,34 +60,151 @@ The `restart-device.xml` file will have this payload instead:
|
|||
</Exec>
|
||||
```
|
||||
|
||||
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:
|
||||
|
||||
```
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Command</key>
|
||||
<dict>
|
||||
<key>Identifier</key>
|
||||
<string>com.some.profile</string>
|
||||
<key>RequestType</key>
|
||||
<string>RemoveProfile</string>
|
||||
</dict>
|
||||
<key>CommandUUID</key>
|
||||
<string>16F4301E-7A88-42AD-8523-A2F73F9D38FA</string>
|
||||
</dict>
|
||||
</plist>
|
||||
```
|
||||
|
||||
### 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=<insert-command-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 '<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Command</key>
|
||||
<dict>
|
||||
<key>Identifier</key>
|
||||
<string>com.some.profile</string>
|
||||
<key>RequestType</key>
|
||||
<string>RemoveProfile</string>
|
||||
</dict>
|
||||
<key>CommandUUID</key>
|
||||
<string>16F4301E-7A88-42AD-8523-A2F73F9D38FA</string>
|
||||
</dict>
|
||||
</plist>' | 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=<insert-command-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"
|
||||
```
|
||||
|
||||
<meta name="category" value="guides">
|
||||
<meta name="authorGitHubUsername" value="noahtalerman">
|
||||
|
|
|
|||
Loading…
Reference in a new issue