Skip to content

Compliance: tenant-wide counts plus the per-policy state of a single device.

Two complementary views:

  • the summary singletons give the whole-tenant picture (compliant / non-compliant / in-grace-period / error counts), and
  • the per-device collections show which compliance and configuration policies a device is failing, which is what you need when a user opens a ticket.

    python compliance.py # tenant summary + every device python compliance.py --device-name LAPTOP # which policies one device fails

Permissions

Requires delegated permission DeviceManagementConfiguration.Read.All and DeviceManagementManagedDevices.ReadWrite.All.

Reference

View source

from __future__ import annotations

import argparse

from office365.graph_client import GraphClient
from office365.runtime.client_request_exception import ClientRequestException
from tests.settings import client_id, password, tenant, username


def print_summary(client: GraphClient) -> None:
    """Print the tenant-wide compliance and configuration state summaries."""
    summary = client.device_management.device_compliance_policy_device_state_summary.get().execute_query()
    print("Compliance policy summary (tenant):")
    for name in (
        "compliant_device_count",
        "non_compliant_device_count",
        "in_grace_period_count",
        "error_device_count",
        "conflict_device_count",
        "unknown_device_count",
    ):
        print(f"  {name:28s} {getattr(summary, name) or 0}")

    configuration = client.device_management.device_configuration_device_state_summaries.get().execute_query()
    print("\nConfiguration profile summary (tenant):")
    for name in ("compliant_device_count", "non_compliant_device_count", "error_device_count", "conflict_device_count"):
        print(f"  {name:28s} {getattr(configuration, name) or 0}")


def print_device_states(device) -> None:
    """Print the per-policy states (compliance and configuration) for one device."""
    print(f"\n{device.device_name or '(unnamed)'}  [{device.compliance_state or 'unknown'}]")

    policies = device.device_compliance_policy_states.get().execute_query()
    print(f"  Compliance policies ({len(policies)}):")
    for state in policies:
        print(f"    {state.display_name or '(unnamed)':40s} {state.state or '?'}")

    profiles = device.device_configuration_states.get().execute_query()
    print(f"  Configuration profiles ({len(profiles)}):")
    for state in profiles:
        print(f"    {state.display_name or '(unnamed)':40s} {state.state or '?'}")


def main() -> None:
    parser = argparse.ArgumentParser(description="Show Intune compliance state")
    parser.add_argument("--device-name", help="Substring to match a device name (per-device detail)")
    args = parser.parse_args()

    client = GraphClient(tenant=tenant).with_username_and_password(client_id, username, password)

    try:
        print_summary(client)
    except ClientRequestException as exc:
        print(f"[skipped] {exc.code}: {exc.message}")
        print("Grant admin consent for DeviceManagementConfiguration.Read.All and re-run.")
        return

    query = client.device_management.managed_devices
    if args.device_name:
        name = args.device_name.replace("'", "''")
        query = query.filter(f"contains(deviceName, '{name}')")
    devices = list(query.get_all().execute_query())
    if not devices:
        print("\nNo managed devices matched.")
        return
    for device in devices:
        print_device_states(device)


if __name__ == "__main__":
    main()

← Back to Devices