> For the complete documentation index, see [llms.txt](https://docs.blusapphire.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.blusapphire.io/log-forwarding/03_log-forwarding-guide/log-forward/microsoft/ms-intune-integration.md).

# MS Intune Integration

## #**Log Integration procedure Introduction:**

This document outlines the process for integrating MS Intune with Logstash to collect and process Mobile Device Management (MDM) logs. Prerequisites

• Client credentials for MS Intune API access:

• Client ID

• Client Secret

• Tenant ID

## #Configuration:

• We are fetching the device logs through below Graph URLs.

<https://graph.microsoft.com/v1.0/deviceManagement/managedDevices> <https://graph.microsoft.com/v1.0/deviceManagement/managedDeviceOverview> <https://graph.microsoft.com/v1.0/deviceManagement/detectedApps>

Update the script with your MS intune Client details, Logstash details (host and port).

Code Snippet (Generate access token, Log Fetching and Processing Script)

Python import requests import socket import json import os

Replace these values with your own

tenant\_id = '98e37d3b-c3b5-4dad-916d-e0c5e9a8e9c4' client\_id = '910f5b05-59a3-4261-a568-b8c497cd1f53' client\_secret = 'YxC8Q\~JPWv0fFqA\_e1ih18cPC6DzeJFPFWtzbdm4' local\_host = '127.0.0.1' local\_port = 12225 # You can change this to the desired port processed\_device\_names\_file = 'processed\_ids.txt' processed\_device\_overview\_file = 'processed\_overview\.txt' processed\_detected\_apps\_file = 'processed\_apps.txt'

URLs to fetch logs from

graph\_urls = \[

'<https://graph.microsoft.com/v1.0/deviceManagement/managedDeviceOverview>'

]

graph\_urls = \[ '<https://graph.microsoft.com/v1.0/deviceManagement/managedDevices>', '<https://graph.microsoft.com/v1.0/deviceManagement/managedDeviceOverview>', '<https://graph.microsoft.com/v1.0/deviceManagement/detectedApps>' ]

Get access token

def get\_access\_token(tenant\_id, client\_id, client\_secret): token\_url = f"[https://login.microsoftonline.com/{tenant\_id}/oauth2/v2.0/token](https://login.microsoftonline.com/%7Btenant_id%7D/oauth2/v2.0/token)" token\_data = { 'grant\_type': 'client\_credentials', 'client\_id': client\_id, 'client\_secret': client\_secret, 'scope': '<https://graph.microsoft.com/.default>' }

```
token_response = requests.post(token_url, data=token_data)
token_response.raise_for_status()
access_token = token_response.json().get('access_token')
return access_token
```

Fetch logs

def fetch\_intune\_logs(access\_token, url): headers = { 'Authorization': f'Bearer {access\_token}' }

```
response = requests.get(url, headers=headers)
response.raise_for_status()
logs = response.json()

# Check if 'value' field exists
if 'value' in logs:
    return logs['value']
else:
    return [logs]
```

Send logs to localhost port

def send\_logs\_to\_localhost(logs, host, port): with socket.socket(socket.AF\_INET, socket.SOCK\_STREAM) as s: s.connect((host, port)) logs\_str = json.dumps(logs) s.sendall(logs\_str.encode('utf-8')) s.close()

Read all processed data from a file

def read\_processed\_data(file): if os.path.exists(file): with open(file, 'r') as f: try: return json.load(f) except json.JSONDecodeError: return \[] return \[]

Write new processed data to a file

def write\_processed\_data(file, data): with open(file, 'w') as f: json.dump(data, f)

def main(): try: access\_token = get\_access\_token(tenant\_id, client\_id, client\_secret) all\_logs = \[] processed\_data = \[]

```
    # Fetch logs from all URLs
    for url in graph_urls:
        logs = fetch_intune_logs(access_token, url)
       # print(logs)

        # Process logs based on URL
        if url == 'https://graph.microsoft.com/v1.0/deviceManagement/managedDevices':
            processed_device_names = read_processed_data(processed_device_names_file)
            new_logs = [log for log in logs if log.get('deviceName') not in processed_device_names]
            processed_data.extend(new_logs)
            new_device_names = [log.get('deviceName') for log in new_logs]
            write_processed_data(processed_device_names_file, processed_device_names + new_device_names)

        if url == 'https://graph.microsoft.com/v1.0/deviceManagement/managedDeviceOverview':
            processed_overviews = read_processed_data(processed_device_overview_file)
            new_logs = [log for log in logs if log.get('enrolledDeviceCount') not in processed_overviews]
            processed_data.extend(new_logs)
            new_counts = [log.get('enrolledDeviceCount') for log in new_logs]
            write_processed_data(processed_device_overview_file, processed_overviews + new_counts)

        elif url == 'https://graph.microsoft.com/v1.0/deviceManagement/detectedApps':
            processed_apps = read_processed_data(processed_detected_apps_file)
            new_logs = [log for log in logs if log.get('id') not in processed_apps]
            processed_data.extend(new_logs)
            new_ids = [log.get('id') for log in new_logs]
            write_processed_data(processed_detected_apps_file, processed_apps + new_ids)

        print(f"Processed logs from: {url}")

    # Send processed_data to localhost
    if processed_data:
        send_logs_to_localhost(processed_data, local_host, local_port)
        print(f"Logs fetched and processed successfully. Total new logs processed: {len(processed_data)}")
    else:
        print("No new logs to process.")

except Exception as e:
    print(f"An error occurred: {e}")
```

if name == "main":

main()

3. Setup a Logstash pipeline to fetch the logs at input port 12225/tcp and follow further steps.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.blusapphire.io/log-forwarding/03_log-forwarding-guide/log-forward/microsoft/ms-intune-integration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
