Intune - Device Query & Intune Advanced Analytics
Imagine... A world... Where live-querying devices directly from Intune is possible... 💭
Introducing Device Query... Just one of the new components released as part of the new Intune Advanced Analytics capability, the latter of which is also just one of many features now bundled up within the Intune Suite add-on. Whilst Intune Advanced Analytics is offered as part of the Intune Suite, it is worth mentioning that the feature can also be procured as a standalone add-on to Intune Plan 1.
If you didn't know already, the Intune Suite is a bundle of multiple advanced device management capabilities, each offering a sophisticated solution for further managing and securing your endpoints, above & beyond what's already included within the existing and standard Intune Plan 1 offering.
📈 So, how did we get to Intune Advanced Analytics? - Well, it all started with Advanced Endpoint Analytics, also a part of the Intune Suite, which builds upon the basic analytic offering that arrives with Intune Plan 1. This basic analytic offering provides foundational reporting capabilities around start-up performance & start-up times for enrolled endpoints, provides statistics around the reliability of installed applications, and gauges the device's potential to work from anywhere. Advanced Endpoint Analytics, however, introduces additional components such as the ability to identify anomalies across the endpoint estate, the ability to filter and categorise endpoints via Device Scopes, and the introduction of Device Timelines to view key events that have occurred on an endpoint in a chronological format, such as application crashes, boot times, and logons.
📊 Fast forward to Intune Advanced Analytics, which this blog post is focused on, further builds upon Advanced Endpoint Analytics by introducing access to near-real-time data, as well as incorporating further useful metrics such as visibility into hardware health, such as batteries. Near-real-time access to data is facilitated by the ability to directly query a device using KQL (Kusto Query) which is a natural language method of querying. Using device query, you can efficiently and seamlessly gain access to useful information such as Performance statistics, configuration, hardware specifications, software information, registry keys, and network information.
If you'd like to know a little bit more about the Intune Suite or Advanced Analytics, my overview video covering the Intune Suite add-on may be of interest to you: -
Let's jump into Intune Advanced Analytics: -
Prerequisites
Licensing
Intune Advanced Analytics is not included within the standard Intune Plan 1 offering and therefore must be procured via either of the following two methods: -
Intune Suite: Costed at $10 / £8.20 per user, per month, and includes a wealth of advanced device management capabilities beyond just Intune Advanced Analytics.
Standalone (Intune Advanced Analytics): Costed at $5 / £4.10 per user, per month, and includes the Intune Advanced Analytics and Advanced Analytics capabilities only.
It is also worth noting that the Intune Suite is available for a one-time 90-day trial, which I'd highly recommend starting with - You will not be disappointed!
Device Query
Device Query gifts administrators the ability to immediately query Intune enrolled Windows endpoints using Kusto Query Language (KQL), "live and direct" all from within the Intune portal itself. The feature enhances Intune's existing inventorying capability by establishing a live connection to devices, enabling administrators to access real-time information about a device's state and configuration. This provides valuable insights into various software and hardware profiles, helping IT support staff, security professionals, and administrators respond quickly to issues and threats.
Some of the key benefits of Device Query are listed below: -
Immediate and interactive "live" data querying for online cloud-managed devices.
Efficient remote access to useful entities such as registry hives, file metadata, services, and active processes.
Leverage a continuously evolving set of accessible entities to query.
All queries and results are encrypted from start to finish.
If KQL is not something you're already familiar with, Microsoft offers the following repository on the subject: - Kusto Query Language (KQL) overview - Azure Data Explorer & Real-Time Analytics | Microsoft Learn - KQL is a natural language method of querying which means it's more intuitive to pick-up and implement than others.
Device Query can currently be accessed on a per-device basis by simply finding and opening the target enrolled Windows device in question, and then browsing to "Device query" within.
Let's start by looking at the "Properties" pane which features all the available properties (tables) and entities (columns) we can query: -
We can already see just from the snippets above that there are some super cool and useful properties available, such as "Process" and "WindowsRegistry".
Let's begin with some super easy one-term queries to get us started, and then after we'll slowly transition to slightly more complex queries, which is where you'll start to see the real benefit of Device Query. For reference, KQL queries are usually formed with various operators, parameters, and functions to target and retrieve the exact data that is required - However, as mentioned, just to get us started in this first instance, we will simply query the name of the property (table).
OsVersion
First, we'll take a look at the "OsVersion" property, which as the name suggests, returns information relating to the target device's Operating System.
Okay, let's type "OsVersion" into the query window and then click "Run"...
OsVersion
And there we have it, just like that, the query has been delivered directly to the online device in a live and timely fashion, which has then responded with the requested information regarding its Operating System version. That was easy, wasn't it?
LogicalDrive
Let's do that again... After all, practice makes perfect. This time, we'll query the "LogicalDrive" property, which as the name suggests, returns information relating to the target device's logical storage drive, for example, C: drive.
LogicalDrive
Amazing! - Within a few seconds, we now have accurate and real-time information relating to the target device's C: drive, including its free and available storage space.
Let's now move on to slightly more adventurous and complex queries.
Process
Beginning with the "Process" property, we'll start by quickly running its simplest query as before, but only to get a feel of how the output looks. When run independently, we can see that the query returns all active processes currently running on the targeted device.
Process
Let's move on to expanding the "Process" property (table). By expanding a property, we are exposed to its various and corresponding entities (columns) that we can later leverage within our queries.
Now that we know the properties available entities, let's add one of them to the previous query. In this example, we'll once again request the active processes running on the device, but this time, we'll order (sort) the results by their "TotalSizeBytes" which is one of the available entities (columns) for the "Process" property. We'll also then instruct the query to only return the top 3 results, meaning the top 3 active processes on the device in terms of their consumption.
Process
| order by TotalSizeBytes
| take 3
And would you look at that, we can now easily see the top 3 running processes currently running on the target device in terms of their current consumption.
Next, we'll take a look at searching for a specific process on the endpoint, "Outlook.exe", which can be done by leveraging the "where" operator which kind of behaves like a filter. We'll also use the "project" operator to determine which entities (columns) should be returned within the results.
Process
| where ProcessName == 'outlook.exe'
| project ProcessId, ProcessName, Path, TotalSizeBytes
And what do you know, it looks like "Outlook.exe" was running on the device with a ProcessId of 18464.
Let's get slightly more clever with our next query. This time, we'll use KQL to "summarize" the active processes on the target device by their "ProcessName", counting how many occurrences of each exist, whilst sorting them in order.
Process
| summarize Count=count() by ProcessName
| order by Count
And there we have it, we can now see how many instances of each "ProcessName" are currently running on the target device, sorted in a descending fashion.
I think that's just about enough of the "Process" property.
WindowsRegistry
Moving onto the "WindowsRegistry" property, we'll now take a look at how this property (table) can be structured and queried. You might have guessed that this property refers to the Windows Registry (regedit). As with all previous queries, this one is no different in that it begins with the "property" that we'd like to query - However, with "WindowsRegistry", we also need to specify a "RegistryKey" to be queried.
The structure follows this format: - WindowsRegistry('RegistryKey')
In this example, we will query the following Defender for Endpoint key: -"HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Policy Manager"
Which would look like the below in a Device Query.
WindowsRegistry('HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Policy Manager')
Have you noticed a trend yet? - Device Query just works, and well. Here, we can see that all values within the specified registry key have been returned along with their details.
If we wanted to focus on one particular value within this registry key instead, we could use the "where" operator to formulate something like this...
WindowsRegistry('HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Policy Manager')
| where ValueName == 'AllowCloudProtection'
And just to prove that the data being returned is accurate, this is the same value within the actual registry hive of the endpoint: -
It's around about now that we quickly begin to realise the full potential of Device Query and how powerful it is now and will continue to become.
Let's now adapt the query to only return values within the same registry key that are set to "0", which in this case, translates to the corresponding Defender for Endpoint feature being "disabled".
WindowsRegistry('HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Policy Manager')
| where ValueData == '0'
And just as we expected, it did exactly what we asked, and quickly too.
I think it's time to move on to one of my favourite properties so far...
WindowsEvent
This property is one of my favourites so far, using "WindowsEvent" we can live-query the target devices' Event Viewer logs and retrieve real-time data. Similarly to the "WindowsRegistry" property we queried earlier, this property also needs to be structured uniquely.
The structure follows this format: - WindowsEvent('LogName')
In this example, we will query the "Security" Event Viewer log.
Which would look like this in a Device Query: -
WindowsEvent('Security')
In this example, we are still going to query the "WindowsEvent" property and Security log, but we're only interested in results that match "EventID" 4732 and include a "Message" that contains the term "Administrators".
If you didn't know, Event ID 4732 translates to "A member was added to a security-enabled local group", and we're filtering on the "Message" entity to only return events where the local "Administrators" group was involved.
WindowsEvent('Security')
| order by LoggedDateTime
| where EventId == 4732
| where Message contains 'Administrators'
And I think that's a full-house, another successful query to add to the list.
I reckon we've just about walked through enough examples of the different query possibilities now, so I'll leave the following as further, but "unexplained", examples: -
EncryptableVolume
Returns information relating to the presence of BitLocker encryption across the target devices volumes & drives.
EncryptableVolume
LocalUserAccount
Returns information relating to the local user accounts present on the target device.
LocalUserAccount
BiosInfo
Returns information relating to the target devices Bios.
BiosInfo
WindowsDriver
Returns information relating to the installed drivers on the target device.
WindowsDriver
| where DriverDescription contains 'HP'
WindowsService
Returns information relating to the services on the target device, be they active, inactive, or disabled.
WindowsService
| where DisplayName contains 'Defender'
WindowsService
| where StartMode == 'Disabled'
Battery Health
Intune Advanced Analytics also introduces a battery health report, which enables IT professionals to monitor and optimise device batteries. This report provides invaluable insights into capacity, runtime, use cycles, and overall health, helping prevent hardware issues whilst also supporting future plans for hardware renewal cycles. According to Microsoft, this is only the first step in a proactive approach to address hardware concerns, with plans to expand support to other device resources for a balanced approach to hardware procurement and user experience.
Battery Health can be assessed and measured on both an individual device basis and at a group level.
Device Level
Group Level
Reporting & Logs
Query executions relating to Device Query are logged within Intune's own Audit Logs.
The Future
Intune Advanced Analytics is a welcomed addition to the Intune Suite, and the fact that it can be procured as a standalone add-on too makes the feature only more accessible to the masses. We only need to appreciate the above to understand Device Query's full potential both now and in the future, it's a definite game-changer when it comes to proactive and reactive IT Support, and I'm eager to continue experimenting with the solution and building queries.
Equally, the new Battery Health reporting metric marks a clear, positive, and exciting start to hopefully further hardware-related health reports.
Admittedly, it could well be something I've missed, but I'd love for the Device Query function to support the KQL "render" operator in the future, much like it is in Log Analytics. When I attempted to use it in Device Query, the render operator was quite simply ignored - Not a blocker by any means though, this is purely preference!
What I tried and received: -
Versus what I hoped for: -
Anyway, what are you waiting for? - Happy Device Query'ing!
Comments