In diesem kurzen Blog möchte ich dir zeigen, wie du mit GPT eine Zusammenfassung des Intune Management Extension Logs erstellen kannst. Dieses Skript liest die Logdatei der Intune Management Extension im Ordner ProgramData/Microsoft/IntuneManagementExtension/Logs aus und übergibt den aktuellsten Inhalt des Logs an GPT, sodass du weniger Zeit damit verbringst, dich durch tausende unübersichtliche Logzeilen zu scrollen.
Die Fehlersuche bei der App- und Richtlinienverteilung auf Windows-Endgeräten landet fast immer bei genau dieser einen Logdatei, und sie von Hand zu lesen ist mühsam. Ein IME Log Summarizer macht aus dem rohen, ausführlichen Log einen kurzen, gut lesbaren Bericht, der hervorhebt, was auf dem Gerät tatsächlich schiefgelaufen ist. Wenn du deine Geräte bereits mit Microsoft Intune verwaltest, ist das ein schneller Mehrwert, den du in wenigen Minuten einrichten kannst.

Inhaltsverzeichnis
Wie funktioniert das
GPT verwendet den Inhalt des Logs und erstellt eine Zusammenfassung, weist dich aber auch auf mögliche Fehler auf dem Gerät hin. Das ist ein sehr einfacher Ansatz, doch mein Ziel ist es, dir zu zeigen, wie du KI im Device Management einsetzen kannst, um mehr Einblicke zu gewinnen und Zeit zu sparen. Statt nach Schlüsselwörtern zu suchen, liest der IME Log Summarizer den aktuellsten Teil des Logs und erklärt in verständlicher Sprache, welche Apps oder Richtlinien fehlgeschlagen sind und warum.
Der Ablauf ist bewusst minimal gehalten: die Logdatei einlesen, sie auf den neuesten Inhalt kürzen, damit sie in das Kontextfenster des Modells passt, an ein Azure OpenAI Deployment senden und das Ergebnis ausgeben. Du kannst das Skript lokal auf einem einzelnen Gerät ausführen oder in der fortgeschrittenen Variante das Log remote für jedes registrierte Gerät abrufen.
Vorbereitung und Voraussetzungen
Du musst ein Azure OpenAI Deployment erstellen. Sobald das erledigt ist, musst du den azure_endpoint und den api_key in das Skript eintragen. Für die fortgeschrittene Remote-Variante benötigst du außerdem eine Entra-ID-App-Registrierung mit Graph-Berechtigungen, damit der IME Log Summarizer die Log-Sammlung von Intune anfordern und herunterladen kann.
Einfacher Ansatz
Hier findest du ein einfaches Skript, das lokal auf einem Gerät funktioniert. Dieser lokale IME Log Summarizer eignet sich perfekt für schnelle Prüfungen, während du bereits an dem Rechner angemeldet bist, den du untersuchst.
import os
from openai import AzureOpenAI
file_path = os.path.join('C:\\', 'ProgramData', 'Microsoft', 'IntuneManagementExtension', 'Logs', 'IntuneManagementExtension.log')
with open(file_path, 'r') as file:
log_content = file.read()
log_content = log_content[-128000:]
prompt = f"""
You are an senior intune engineer. Your task is to find errors in the [Intune Management Extension log]. Give the user a summary of the log an point him to potential errors on an structured way. Explain to the user what is mean and how he can check and troubleshoot this.
[Intune Management Extension log]
{log_content}
[END Intune Management Extension log]
"""
client = AzureOpenAI(
azure_endpoint="https://YOUR_ENDPOINT.openai.azure.com/",
api_key="YOUR_APIKEY",
api_version="2024-02-01",
)
completion = client.chat.completions.create(
model="gpt-4o",
temperature=0,
messages=[
{
"role": "user",
"content": prompt,
}
]
)
print(completion.choices[0].message.content)
Fortgeschrittener Ansatz
Bei diesem Ansatz ermöglichen wir es dem Skript zusätzlich, remote zu arbeiten. Dafür müssen wir die Logdatei vom Gerät hochladen und für die Zusammenfassung verwenden. Das macht den IME Log Summarizer auch im großen Maßstab nützlich, denn so kannst du ein Gerät analysieren, auf das du keinen physischen Zugriff hast. Das funktioniert folgendermaßen:

Bevor wir das Skript ausführen, müssen wir eine Voraussetzung erfüllen. Wir benötigen eine App-Registrierung mit den folgenden Berechtigungen:

Das ist das vollständige Skript:
"""This script is used to summarize the Intune Management Extension (IME) logs for a given device."""
import os
import urllib.request
import ssl
import zipfile
import requests
import msal
from openai import AzureOpenAI
from loguru import logger
CLIENT_ID = "CLIENT_ID"
TENANT_ID = "TENANT_ID"
CLIENT_SECRET = "CLIENT_SECRET"
OPEN_AI_API_KEY = "YOUR_API_KEY"
OPEN_AI_ENDPOINT = "https://YOUR_ENDPOINT.openai.azure.com/"
DEVICE_ID = "INTUNE_DEVICE_ID"
def get_access_token(client_id, client_secret, tenant_id):
"""Get an access token for the Microsoft Graph API using the"""
authority = f"https://login.microsoftonline.com/{tenant_id}"
app = msal.ConfidentialClientApplication(
client_id,
authority=authority,
client_credential=client_secret,
)
result = app.acquire_token_for_client(
scopes=["https://graph.microsoft.com/.default"]
)
if "access_token" in result:
return result["access_token"]
else:
raise Exception("Could not obtain access token") # pylint: disable=broad-exception-raised
def collect_logs(device_id, client_id, client_secret, tenant_id):
"""Load all apps from the Microsoft Graph API"""
token = get_access_token(client_id, client_secret, tenant_id)
headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
response = requests.post(
f"https://graph.microsoft.com/beta/deviceManagement/managedDevices('{device_id}')/createDeviceLogCollectionRequest",
json={"templateType": 0},
headers=headers,
)
print(response.json())
response.raise_for_status()
return response.json()["value"]
def get_log_status(device_id, client_id, client_secret, tenant_id):
"""Load all apps from the Microsoft Graph API"""
token = get_access_token(client_id, client_secret, tenant_id)
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
"consistencylevel": "eventual",
}
response = requests.get(
f"https://graph.microsoft.com/beta/deviceManagement/managedDevices('{device_id}')/logCollectionRequests?$select=id,status,managedDeviceId,errorCode,requestedDateTimeUTC,receivedDateTimeUTC,initiatedByUserPrincipalName&",
headers=headers,
)
response.raise_for_status()
logs = response.json()["value"]
logs.sort(key=lambda x: x["requestedDateTimeUTC"])
return logs[-1]
def download_logs(device_id, log_id, client_id, client_secret, tenant_id):
"""Load all apps from the Microsoft Graph API"""
token = get_access_token(client_id, client_secret, tenant_id)
headers = {
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
}
response = requests.post(
f"https://graph.microsoft.com/beta/deviceManagement/managedDevices('{device_id}')/logCollectionRequests('{log_id}')/createDownloadUrl",
headers=headers,
json={},
)
response.raise_for_status()
return response.json()["value"]
def summarize_logs(file_path):
"""Summarize the Intune Management Extension logs"""
with open(file_path, "r") as file:
log_content = file.read()
log_content = log_content[-128000:]
prompt = f"""
You are an senior intune engineer. Your task is to find errors in the [Intune Management Extension log]. Give the user a summary of the log an point him to potential errors on an structured way. Explain to the user what is mean and how he can check and troubleshoot this.
[Intune Management Extension log]
{log_content}
[END Intune Management Extension log]
"""
client = AzureOpenAI(
azure_endpoint=OPEN_AI_ENDPOINT,
api_key=OPEN_AI_API_KEY,
api_version="2024-02-01",
)
completion = client.chat.completions.create(
model="gpt-4o",
temperature=0,
messages=[
{
"role": "user",
"content": prompt,
}
],
)
print(completion.choices[0].message.content)
def main():
"""Main function for the Streamlit app"""
logger.info("Starting IME Summarizer")
log_status = get_log_status(DEVICE_ID, CLIENT_ID, CLIENT_SECRET, TENANT_ID)
logger.info(log_status)
if log_status["status"] != "completed":
logger.error("Log collection is not completed yet")
return
log_id = log_status["id"].replace(f"{DEVICE_ID}_", "")
log_download_url = download_logs(
DEVICE_ID, log_id, CLIENT_ID, CLIENT_SECRET, TENANT_ID
).replace('"', "")
# Download zip
logger.info(log_download_url)
ssl._create_default_https_context = ssl._create_unverified_context
urllib.request.urlretrieve(log_download_url, "logs.zip")
# uzip logs.zip
with zipfile.ZipFile("logs.zip", "r") as zip_ref:
zip_ref.extractall("logs")
# find folder
log_folder = None
for folder in os.listdir("logs"):
if "ProgramData_Microsoft_IntuneManagementExtension_Logs" in folder:
log_folder = folder
break
logger.info(log_folder)
# Summarize logs
summarize_logs(f"logs/{log_folder}/intunemanagementextension.log")
if __name__ == "__main__":
main()
Um die Log-Sammlung zu starten, kannst du vorab Folgendes ausführen:
def main():
"""Start log collection"""
log = collect_logs(DEVICE_ID, CLIENT_ID, CLIENT_SECRET, TENANT_ID)
logger.info(log)
Die Ausgabe:

Fazit zum IME Log Summarizer
Mehr braucht es nicht, um einen funktionierenden IME Log Summarizer für Microsoft Intune aufzusetzen. Mit ein paar Zeilen Python und einem Azure OpenAI Deployment erhältst du ein Werkzeug, das das unübersichtliche Log für dich liest und dir eine klare Zusammenfassung der Fehler zurückgibt. Wenn du weitere Ideen zur Intune-Automatisierung suchst, schau dir die anderen Beiträge auf jannikreinhard.com an und passe diesen IME Log Summarizer an deinen eigenen Workflow an.
Zwei häufige Stolperfallen solltest du im Blick behalten. Die erste ist das Kontextfenster: Das Skript behält nur die letzten 128.000 Zeichen des Logs, sodass ein Fehler, der früher am Tag aufgetreten ist, eventuell bereits abgeschnitten wurde. Wenn du einem bestimmten Fehler nachgehst, notiere dir zuerst den Zeitstempel und stelle sicher, dass er in den Ausschnitt fällt, den du an das Modell sendest. Die zweite betrifft das Vertrauen: GPT erkennt Muster gut, kann einen unbekannten Fehlercode aber falsch deuten, prüfe seine Ergebnisse daher immer gegen das rohe Log, bevor du danach handelst.
This script is not working at all, the error msg is pasted below for you reference
At line:10 char:1
The ‘from’ keyword is not supported in this version of the language.
At line:12 char:1
The ‘from’ keyword is not supported in this version of the language.
At line:24 char:31
Missing argument in parameter list.
At line:28 char:18
Missing argument in parameter list.
At line:30 char:41
Missing expression after ‘,’ in pipeline element.
At line:35 char:7
Missing ‘(‘ after ‘if’ in if statement.
At line:35 char:23
Unexpected token ‘in’ in expression or statement.
At line:41 char:27
Missing argument in parameter list.
At line:43 char:39
Missing argument in parameter list.
At line:44 char:31
Did you run this in an python environment. Try to run python -m {script path}