# Protokollverwaltung

### Logging in Azure Monitor aktivieren

Ab Version 3.0 werden SCEPman sowie der Certificate Master die Microsoft Log Ingestion API verwenden, um Protokolle in Azure Monitor zu schreiben. Dabei wird das Konzept eines Log Analytics Workspace genutzt, um die Daten zu speichern und die Analyse zu ermöglichen, sowie eine Data Collection Rule, die zwischen der App Service und dem Protokollspeicher vermittelt. Dies ermöglicht einen moderneren Ansatz, einschließlich RBAC-basierter Berechtigungen für SCEPman, um auf den LAW zuzugreifen.

Das Erstellen des Log Analytics Workspace sowie die Konfiguration der Data Collection Rule werden automatisch durchgeführt, indem `Complete-SCEPmanInstallation` des SCEPman PowerShell-Moduls ausgeführt wird.

{% hint style="info" %}
Das **Standardaufbewahrungs** zeitraum für Daten, die in einer Log Analytics-Tabelle gespeichert sind, beträgt **30 Tage**. Falls ein anderer Aufbewahrungszeitraum erforderlich ist, passen Sie die Konfiguration der Tabelle "SCEPman\_CL" entsprechend an.
{% endhint %}

#### Data Collector API erneut aktivieren

Wenn Sie aus irgendeinem Grund die vorherige API wieder verwenden möchten, können Sie dies tun, indem Sie die mit Log Ingestion verbundenen App-Service-Variablen entfernen und die Variablen erneut hinzufügen, die von der Data Collector API verwendet werden sollen.

Zu entfernende **Variablen**:

* [AppConfig:LoggingConfig:DataCollectionEndpointUri](https://app.gitbook.com/o/-LhPlvZ6dc8XcqY7tdZw/s/-LoGejQeUQcw7lqnQ3WX/~/edit/~/changes/787/scepman-configuration/application-settings/dependencies-azure-services/logging#appconfig-loggingconfig-datacollectionendpointuri)
* [AppConfig:LoggingConfig:RuleId](https://app.gitbook.com/o/-LhPlvZ6dc8XcqY7tdZw/s/-LoGejQeUQcw7lqnQ3WX/~/edit/~/changes/787/scepman-configuration/application-settings/dependencies-azure-services/logging#appconfig-loggingconfig-ruleid)

Zu hinzufügende Variablen:

* [AppConfig:LoggingConfig:WorkspaceId](https://app.gitbook.com/o/-LhPlvZ6dc8XcqY7tdZw/s/-LoGejQeUQcw7lqnQ3WX/~/edit/~/changes/787/scepman-configuration/application-settings/dependencies-azure-services/logging#appconfig-loggingconfig-workspaceid)
* [AppConfig:LoggingConfig:SharedKey](https://app.gitbook.com/o/-LhPlvZ6dc8XcqY7tdZw/s/-LoGejQeUQcw7lqnQ3WX/~/edit/~/changes/787/scepman-configuration/application-settings/dependencies-azure-services/logging#appconfig-loggingconfig-sharedkey)

SCEPman übernimmt die Einstellungen nach einem Neustart automatisch und verwendet dann wieder die Data Collector API.

## KQL-Abfragebeispiele

### Probleme mit Ihrer SCEPman-Instanz anzeigen

```kusto
SCEPman_CL
| where Level == "Warn" or Level == "Error" or Level == "Fatal"
```

### Anzahl ausgestellter Zertifikate nach Endpunkt im ausgewählten Zeitrahmen

{% hint style="success" %}
Diese Abfrage funktioniert garantiert mit SCEPman 3.0 und neuer, wenn die Log Ingestion API zum Protokollieren verwendet wird. Änderungen an SCEPman, die diese Abfrage unbrauchbar machen, gelten als Breaking Changes.
{% endhint %}

{% tabs %}
{% tab title="Log Ingestion API ( Standard )" %}

```kql
SCEPman_CL
| where Level == "Info" and Message startswith_cs "Issued a certificate with serial number"
| project Message, RequestBase = trim_end('/', replace_string(replace_string(replace_regex(RequestUrl, "(/pkiclient\\.exe)?(\\?operation=PKIOperation(&message=.+)?)?", ""),"certsrv/mscep/mscep.dll","intune"),"step/enrollment","activedirectory"))
| summarize IssuanceCount = count() by Endpoint = extract("/([a-zA-Z]+)$", 1, RequestBase)
```

{% endtab %}

{% tab title="Data Collector API ( Alt )" %}

```kusto
SCEPman_CL
| where Level == "Info" and Message startswith_cs "Issued a certificate with serial number"
| project Message, RequestBase = trim_end('/', replace_string(replace_string(replace_regex(RequestUrl_s, "(/pkiclient\\.exe)?(\\?operation=PKIOperation(&message=.+)?)?", ""),"certsrv/mscep/mscep.dll","intune"),"step/enrollment","activedirectory"))
| summarize IssuanceCount = count() by Endpoint = extract("/([a-zA-Z]+)$", 1, RequestBase)
```

{% endtab %}
{% endtabs %}

Ab SCEPman 2.8 gibt es pro ausgestelltem Zertifikat immer genau einen Protokolleintrag auf Info-Ebene, dessen Protokollnachricht mit "Issued a certificate with serial number " beginnt, gefolgt von der Seriennummer. Aufgrund des unlösbaren [Zwei-Armeen-Problem](https://en.wikipedia.org/wiki/Two_Generals%27_Problem)kann es jedoch vorkommen, dass das erstellte Zertifikat den Anforderer nie erreicht oder ein anderer Fehler die eigentliche Registrierung verhindert. Ebenso kann es bei schweren Fehlern vorkommen, dass ein Protokolleintrag ohne entsprechenden Datenbankeintrag existiert oder umgekehrt.

### Unterscheidbare Zertifikate mit OCSP-Prüfung

{% tabs %}
{% tab title="Log Ingestion API ( Standard )" %}

```kusto
let map_certtype = datatable(serial_start:string, readable:string)
[
  "40", "Intune-Gerät",
  "41", "Intune-Gerät",
  "42", "Nicht konformes Intune-Gerät",
  "50", "Statisch",
  "51", "Statisch",
  "60", "Intune-Benutzer",
  "61", "Intune-Benutzer",
  "64", "Jamf-Benutzer",
  "65", "Jamf-Benutzer",
  "6C", "Jamf-Benutzer auf Gerät",
  "6D", "Jamf-Benutzer auf Gerät",
  "70", "Domänencontroller",
  "7C", "Jamf-Benutzer auf Computer",
  "7D", "Jamf-Benutzer auf Computer",
  "54", "Jamf-Computer",
  "55", "Jamf-Computer",
  "44", "Jamf-Gerät",
  "45", "Jamf-Gerät"
];
SCEPman_CL
| where LogCategory == "Scepman.Server.Controllers.OcspController" and Level == "Info"
| where Message startswith_cs "OCSP Response"
| project serial = extract("Serial Number ([A-F0-9]+)", 1, Message)
| distinct serial
| extend serial_start = substring(serial,0,2)
| join kind=leftouter map_certtype on serial_start
| summarize count() by (readable)
```

{% endtab %}

{% tab title="Data Collector API ( Alt )" %}

```kql
let map_certtype = datatable(serial_start:string, readable:string)
[
  "40", "Intune-Gerät",
  "41", "Intune-Gerät",
  "42", "Nicht konformes Intune-Gerät",
  "50", "Statisch",
  "51", "Statisch",
  "60", "Intune-Benutzer",
  "61", "Intune-Benutzer",
  "64", "Jamf-Benutzer",
  "65", "Jamf-Benutzer",
  "6C", "Jamf-Benutzer auf Gerät",
  "6D", "Jamf-Benutzer auf Gerät",
  "70", "Domänencontroller",
  "7C", "Jamf-Benutzer auf Computer",
  "7D", "Jamf-Benutzer auf Computer",
  "54", "Jamf-Computer",
  "55", "Jamf-Computer",
  "44", "Jamf-Gerät",
  "45", "Jamf-Gerät"
];
SCEPman_CL
| where LogCategory_s == "Scepman.Server.Controllers.OcspController" and Level == "Info"
| where Message startswith_cs "OCSP Response"
| project serial = extract("Serial Number ([A-F0-9]+)", 1, Message)
| distinct serial
| extend serial_start = substring(serial,0,2)
| join kind=leftouter map_certtype on serial_start
| summarize count() by (readable)
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions: 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.scepman.com/de/azure-konfiguration/log-configuration.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.
