fleet icon indicating copy to clipboard operation
fleet copied to clipboard

Add ability to see MDM information for Windows hosts

Open noahtalerman opened this issue 3 years ago • 31 comments

Problem

As an engineer managing thousands of hosts and I'm overwhelmed with tracking these goals:

  • Know which Windows hosts are enrolled to mobile device management (MDM).
  • Know which Windows hosts are enrolled to which MDM solution.

This makes is hard to understand how my organization is doing in our effort to enroll all Windows hosts to MDM.

This also makes is hard to understand how my organization is doing in our effort to move from one MDM solution to another.

Goal

Add ability to see to see MDM information for Windows hosts.

Parent Epic

  • #397

Requirements

  • User can see the number of Windows hosts (hosts count) that match the following criteria.

    • Enrolled (automatic) to MDM
    • Enrolled (manual) to MDM
    • Unenrolled to MDM. Servers are not included.
  • User can see the number of hosts (macOS + Windows) that match the above criteria. Servers are not included.

  • User can navigate to the Hosts page to view and filter a list of hosts that are filtered by the above criteria. Windows and macOS hosts can appear in the same list.

  • The user can see the number of hosts (count) that are enrolled to a specific MDM solution. A unique MDM solution is determined by the MDM's "Server URL."

  • User can navigate to the Hosts page to view and filter a list of hosts filtered by a specific MDM solution. Windows and macOS hosts that are enrolled to the same MDM solution appear in the same list.

Figma

https://www.figma.com/file/hdALBDsrti77QuDNSzLdkx/%F0%9F%9A%A7-Fleet-EE-(dev-ready%2C-scratchpad)?node-id=9244%3A307803

Child issues

  • #7860
  • #7861

noahtalerman avatar Jul 07 '22 14:07 noahtalerman

Zach: Look into the Windows registry.

noahtalerman avatar Jul 07 '22 16:07 noahtalerman

Posibly relevant: https://www.powershellgallery.com/packages/ModernWorkplaceClientCenter/0.1.3/Content/Functions%5CInvoke-AnalyzeMDMEnrollmentStatus.ps1

zwass avatar Jul 07 '22 16:07 zwass

Lots of good info in the registry Screen Shot 2022-07-07 at 5 51 50 PM

zwass avatar Jul 08 '22 00:07 zwass

Problem: How to distinguish between Windows workstations and servers? Do we need to to achieve the goal?

noahtalerman avatar Jul 21 '22 14:07 noahtalerman

Nice!

Lots of good info in the registry

@zwass can you tell if there's a piece of info that would let us know this is the 1 MDM solution that the Windows device is currently enrolled to?

In your screenshot, it looks like there's several MDM solutions under Enrollments.

@defensivedepth tagging you here. I think you might be able to give us some leads to help answer my question.

noahtalerman avatar Aug 12 '22 18:08 noahtalerman

When I looked, the other "Enrollments" seemed to be empty. I think we probably just pick the first one that has data for ProviderID.

zwass avatar Aug 12 '22 18:08 zwass

Yes, I think something like this would work:

select key,data from registry where path like 'HKEY_LOCAL_MACHINE\Software\Microsoft\Enrollments\%\ProviderID';

image

defensivedepth avatar Aug 13 '22 18:08 defensivedepth

I should mention that when I disconnected the test system from MiradoreMDM and reran that query, there were no results.

defensivedepth avatar Aug 16 '22 13:08 defensivedepth

when I disconnected the test system from MiradoreMDM and reran that query, there were no results.

Great. Thank you for testing this.

@defensivedepth does the MDM's server URL (ex. https://miradore.test.com) exist in the registry ? If so, what would the osquery query look like to get this information.

We'd Fleet to create a report of all the Windows hosts talking to a specific MDM server. This way, an organization migrating from one MiradoreMDM server A to to MiradoreMDM server B can see how many Windows hosts are still enrolled in A.

Today, for macOS, we're using the server_url column in the mdm table included in the macadmins osquery extension. This extension uses Kolide Launcher's mdm table: https://github.com/kolide/launcher/blob/master/pkg/osquery/table/mdm.go#L19

noahtalerman avatar Aug 16 '22 18:08 noahtalerman

I think the DiscoveryServiceFullURL is what you would be looking for:

select key,data from registry where path like 'HKEY_LOCAL_MACHINE\Software\Microsoft\Enrollments\%\DiscoveryServiceFullURL';

image

Here is what else is available to query:

image

defensivedepth avatar Aug 16 '22 19:08 defensivedepth

@defensivedepth is Windows Autopilot used every time a device enrolls to MDM? Or, is there another enrollment method? I think Apple has 2 enrollment methods (DEP and manual/user enrollment).

For devices enrolled using Windows Autopilot, is there a way to determine if the the device was registered manually or automatically?

Here are some Microsoft docs on each of these methods: https://docs.microsoft.com/en-us/mem/autopilot/automatic-registration

noahtalerman avatar Sep 01 '22 15:09 noahtalerman

@noahtalerman Let me check a couple things

defensivedepth avatar Sep 01 '22 21:09 defensivedepth

No, Windows Autopilot is not used very time a device enrolls to MDM. There are multiple ways that a device can be enrolled -

In the above miradore example, I used the manual process outlined here: https://www.miradore.com/knowledge/windows/enrolling-windows-10-devices-full-enrollment/

You can also also auto-enroll devices that are connected to Azure AD - as an example, that process for miradore is outlined here: https://www.miradore.com/knowledge/windows/configuring-azure-ad-enrollment/

You can also use Windows Autopilot, which automates things even further.

At this point, it's not clear to me that there is an easy way to differentiate the automated vs. manual enroll. (You can certainly infer some things...) What is the intent for trying to find this out?

defensivedepth avatar Sep 03 '22 17:09 defensivedepth

@defensivedepth thank you for digging into this.

What is the intent for trying to find this out?

If it's valuable, we'd like to tell users which Windows devices were enrolled to MDM automatically v. manually. It's unclear whether or not this is valuable yet.

For macOS, an admin may have more control/more features (ex. non-removable MDM) for devices enrolled automatically (via what Apple calls DEP). I'm not sure if this is similar for Windows. Do you know?

noahtalerman avatar Sep 06 '22 14:09 noahtalerman

@defensivedepth here's one feature. It appears that users can only use the Autopilot reset feature for Windows devices that are Azure AD joined (not Hybrid Azure AD joined): https://docs.microsoft.com/en-us/mem/autopilot/windows-autopilot-reset

Screen Shot 2022-09-06 at 11 11 04 AM

noahtalerman avatar Sep 06 '22 15:09 noahtalerman

Notes for Noah:

  • AutoPilot docs: https://docs.microsoft.com/en-us/mem/autopilot/windows-autopilot
    • Do devices enrolled with Autopilot have more features?
  • Azure AD devices docs: https://docs.microsoft.com/en-us/azure/active-directory/devices/overview
    • Is AD required for devices that enroll with Autopilot?

noahtalerman avatar Sep 06 '22 19:09 noahtalerman

If it's valuable, we'd like to tell users which Windows devices were enrolled to MDM automatically v. manually. It's unclear whether or not this is valuable yet.

@defensivedepth it looks like admins have a higher level of control over hosts enrolled to MDM and joined to Azure AD. The Autopilot reset feature is only supported on these hosts.

Admins have less control over hosts enrolled to MDM and hybrid joined. Autopilot reset is not supported.

Is there a way to detect if a host is joined v. hybrid joined?

Here's the latest iteration of UI changes in Fleet:

Screen Shot 2022-09-07 at 10 43 37 AM

noahtalerman avatar Sep 07 '22 14:09 noahtalerman

The ntdomains table gives info on non-Azure domain-connected status:

Not connected: image

Connected to a non-Azure AD domain: image

The following registry location stores Azure Domain info:

image

So something like this would tell us that it is joined to Azure AD:

select data as TenantID from registry where path like 'HKEY_LOCAL_MACHINE\system\CurrentControlSet\Control\CloudDomainJoin\JoinInfo\%\Tenantid';

image

That should be enough to construct a query / set of queries to determine if it is hybrid or not.

defensivedepth avatar Sep 10 '22 16:09 defensivedepth

I should mention that a cli utility dsregcmd /status gives this info as well:

image

image

defensivedepth avatar Sep 10 '22 17:09 defensivedepth

How should Fleet bucket Windows hosts in the context of MDM enrollment?

Decision:

Use "Enrolled (automatic)," "Enrolled (manual)," and "Unenrolled" buckets.

Options:

  • Use "Enrolled (automatic)," "Enrolled (manual)," and "Unenrolled" buckets.
  • Use "Enrolled (joined)," "Enrolled (hybrid joined)," and "Unenrolled" buckets.
  • Use "Enrolled (autopilot + joined)," "Enrolled (autopilot + hybrid joined)," "Enrolled (joined)," "Enrolled (hybrid joined)," and "Unenrolled" buckets.

Reasoning:

  • Hypothesis is that the most important distinction between the above buckets is that Windows Autopilot allows the admin to block users from unenrolling from MDM.
  • Apple DEP enrollment provides the same "block users from unenrolling" feature.
  • The Fleet UI currently displays "Enrolled (automatic)," "Enrolled (manual)," and "Unenrolled" buckets for macOS hosts. Fleet can bring Windows hosts into the same counts/list.
  • Later, we can add a separate "Azure active directory" table for just Windows if being able to see which hosts are joined v. hybrid joined is valuable. It may be because only joined josts can use the Windows Autopilot reset feature: https://docs.microsoft.com/en-us/mem/autopilot/windows-autopilot-reset

noahtalerman avatar Sep 13 '22 15:09 noahtalerman

@lukeheath here's the Fleet API updates we discussed to accomplish the goal:

  • Expand the GET /host_summary API route to include MDM data. Expected behavior for GET /host_summary API route becomes...
    • "Call this route and get all the data you see on the Home page."
    • Call this route with a specific team and/or platform and get back the data that's available for that team and/or platform.
    • We'll iterate towards this expected behavior.
  • Expand the GET /host/{id} endpoint to include MDM data. Expected behavior for GET /hosts/{id} API route becomes
    • "Call this route and get all the data you see on the Host details page."
    • If data is not available then the data is not included.
  • Sunset GET /macadmins and GET /host/{id}/macadmins API routes.

noahtalerman avatar Sep 14 '22 17:09 noahtalerman

@lukeheath I assigned you this issue and moved it to the designed column.

noahtalerman avatar Sep 14 '22 18:09 noahtalerman

@noahtalerman Need anything else from my side of things?

defensivedepth avatar Sep 14 '22 19:09 defensivedepth

@defensivedepth curious to get your feedback when you get the chance!

The current plan is the include both Windows and macOS hosts in the following tables:

Screen Shot 2022-09-15 at 9 36 15 AM

Screen Shot 2022-09-15 at 9 37 20 AM

Goals:

  • How many hosts, and which hosts, are enrolled in an MDM?
  • How many hosts, and which hosts, can be unenrolled from an MDM by the user?
  • How many hosts, and which hosts, are enrolled in a specific MDM solution?

noahtalerman avatar Sep 15 '22 13:09 noahtalerman

@noahtalerman Looks really good to me!

defensivedepth avatar Sep 15 '22 13:09 defensivedepth

Engineering note: Assigned engineer should schedule call with Noah to discuss this ticket and knowledge transfer the research Noah has already done.

lukeheath avatar Sep 19 '22 21:09 lukeheath

@noahtalerman After some thought, a better API design approach will be separate smaller endpoints instead of moving towards large /host_summary and /host/{id} endpoints. This is because we can provide a better user experience by loading data as soon as it is available.

Some data operations take longer to return than others. If we go the single big response route, we can't load any data on the page until the slowest operation finishes. That could add up to 2 seconds or more to page load times. With smaller individual requests, we can load the fast data as soon as it comes back.

For this ticket, that means adding this data at a new /hosts/mdm endpoint instead of inside the /host_summary endpoint.

lukeheath avatar Sep 20 '22 19:09 lukeheath

provide a better user experience by loading data as soon as it is available.

Got it. Makes sense.

new /hosts/mdm endpoint

@lukeheath what do you think about naming the API route /host_summary/mdm?

This way, we can add future API routes behind the /host_summary namespace. This communicates to the user that the information returned by these API routes will be summary data (aggregate data, host counts, etc.).

In addition, we'll soon design API routes for MDM features in Fleet./hosts/mdm has the potential to conflict with these API routes.

noahtalerman avatar Sep 21 '22 14:09 noahtalerman

@noahtalerman Good point re: conflicting with future endpoints. I think the endpoint /hosts/summary/ would accomplish the same goal and be more RESTy. I'll update the specs.

lukeheath avatar Sep 21 '22 17:09 lukeheath

@lukeheath /hosts/summary shares a similar but slightly different name/path from existing /host_summary route. Calling this out to double check that you're aware.

noahtalerman avatar Sep 21 '22 20:09 noahtalerman