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" 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()

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

Last updated