> For the complete documentation index, see [llms.txt](https://docs.realmjoin.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.realmjoin.com/de/dev-reference/report-functions/publish-rjrbfilestostoragecontainer.md).

# Publish-RjRbFilesToStorageContainer

Laden Sie lokale Dateien aus Azure Automation-Runbooks in einen Azure Storage-Container hoch und geben Sie zeitlich begrenzte SAS-Downloadlinks zurück.

## Übersicht

`Publish-RjRbFilesToStorageContainer` ist der Standard-Helfer zum Bereitstellen von Reportdateien (CSV, XLSX, ZIP, …) aus RealmJoin-Reporting-Runbooks über Azure Blob Storage. Er lädt eine oder mehrere lokale Dateien in einen Ziel-Container hoch und gibt für jeden Blob einen zeitlich begrenzten SAS-Downloadlink zurück, der sich für die Einbindung in Report-E-Mails, Teams-Nachrichten oder Runbook-Ausgaben eignet.

Wesentliche Merkmale:

* **Keine `Az.Storage` Abhängigkeit** — Blob-Operationen werden direkt über die Azure Storage REST-API ausgeführt (Containererstellung, Upload, SAS-Token-Generierung). Dadurch wird der bekannte Assembly-Konflikt zwischen `Az.Storage` und `ExchangeOnlineManagement` beseitigt, der in gemischten Reporting-Runbooks auftritt.
* **Selbstverbindend** — wenn kein `Az` Kontext aktiv ist, ruft die Funktion transparent `Connect-RjRbAzAccount`. Ein optionales `-SubscriptionId` wechselt den Kontext vor jeder Speicheroperation.
* **Container automatisch erstellt** — wenn der Ziel-Container noch nicht existiert, wird er im laufenden Betrieb erstellt; ein vorhandener Container (HTTP 409) wird als Erfolg behandelt.
* **Uploads auf Basis von HttpClient** — verwendet `System.Net.Http.HttpClient` direkt, da Azure Automations `Invoke-RestMethod` Interceptor erforderliche benutzerdefinierte Header (`x-ms-blob-type`) bei Binärdaten entfernt.
* **Schreibgeschützte SAS-Links** — jede zurückgegebene URL ist mit dem Schlüssel des Storage Account signiert, auf einen einzelnen Blob beschränkt, ausschließlich für HTTPS gültig und gültig für `LinkExpiryDays` Tage (Standard 6).

Die zentralen Speicher-Einstellungen (Ressourcengruppe, Kontoname, Ablauf-Tage, Blob-Namenspräfix), die von einem typischen Runbook verwendet werden, sind in der RealmJoin-Anpassungs-JSON enthalten und werden dokumentiert in [Runbook-Berichtseinstellungen — Bereitstellung über Storage Account](/de/automatisierung/runbooks/runbook-report-settings.md#storage-account-delivery). Dieses Dokument konzentriert sich auf den Aufruf der Funktion aus einem Runbook.

## Voraussetzungen

### Azure Storage Account

Ein vorhandener Azure Storage Account (allgemein empfohlen wird v2) ist erforderlich. Der Ziel-Container muss nicht im Voraus existieren — er wird beim ersten Gebrauch automatisch erstellt.

### Azure RBAC auf dem Storage Account

Die verwaltete Identität des Automation Accounts (oder der vom Runbook verwendete Service Principal) benötigt die folgenden Berechtigungen für den Storage Account:

| Aktion                                              | Erforderlich für                                                                             |
| --------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| `Microsoft.Storage/storageAccounts/read`            | Lesen des Storage Account                                                                    |
| `Microsoft.Storage/storageAccounts/listKeys/action` | Abrufen des Kontoschlüssels, der für SharedKey-Signierung und SAS-Generierung verwendet wird |

Weisen Sie die integrierte Rolle zu **Reader and Data Access** für den Storage Account zu: Es ist die kleinste integrierte Rolle, die beides abdeckt. Containererstellung, Upload und SAS-Generierung werden mit dem Kontoschlüssel autorisiert und benötigen keine weiteren Azure RBAC-Berechtigungen. **Storage Account Contributor** funktioniert ebenfalls, ermöglicht jedoch zusätzlich die Verwaltung und Löschung des Storage Account. **Storage Blob Data Contributor** allein ist *nicht* ausreichend, da die Funktion Anforderungen mit dem Kontoschlüssel signiert, statt AAD-gestützte Blob-Operationen zu verwenden.

Da die Funktion sich mit dem Kontoschlüssel authentifiziert, muss der Shared-Key-Zugriff auf dem Storage Account zulässig sein (`allowSharedKeyAccess` darf nicht `false`sein). Der Schlüssel gewährt Zugriff auf alle Daten im Storage Account, daher wird ein dedizierter Storage Account für Berichte empfohlen.

### Modulverbindung

Die Funktion benötigt das `Az.Accounts` Modul in der Runbook-Umgebung (`Get-AzContext`, `Set-AzContext`, `Connect-AzAccount`, `Invoke-AzRestMethod`). Deklarieren Sie es explizit im verwendenden Runbook:

```powershell
#Requires -Modules @{ModuleName = "RealmJoin.RunbookHelper"; ModuleVersion = "0.8.6" }
#Requires -Modules @{ModuleName = "Az.Accounts"; ModuleVersion = "5.3.4" }
```

Wenn `Az.Accounts` zur Laufzeit nicht verfügbar ist, schlägt die Funktion frühzeitig mit einer klaren Fehlermeldung fehl — sie prüft im Vorfeld auf `Get-AzContext` und löst *"Publish-RjRbFilesToStorageContainer erfordert das Modul 'Az.Accounts'. Fügen Sie #Requires -Modules @{ModuleName = 'Az.Accounts'; ModuleVersion = '5.3.4'} zum aufrufenden Runbook hinzu."* bevor ein Azure-Aufruf ausgeführt wird.

> **Warum ist `Az.Accounts` nicht als `RequiredModules` Eintrag in `RealmJoin.RunbookHelper.psd1`?**
>
> `Az.Accounts` absichtlich nur unter `ExternalModuleDependencies` (informativ) und *nicht* unter `RequiredModules` (durchgesetzt zur `Import-Module` Zeit):
>
> * **Nur für das bezahlen, was Sie nutzen.** Viele Runbooks verwenden nur Graph-basierte Helfer (z. B. `Send-RjRbReportEmail` ohne `-UseNativeGraphRequest`oder `Invoke-RjRbRestMethodGraph`) und berühren nie ein Az.\*-Cmdlet. Das Hochstufen `Az.Accounts` zu `RequiredModules` würde jedes konsumierende Runbook zwingen, das Modul mitzuliefern, selbst wenn nichts im eigenen Codepfad es benötigt — was die Kaltstartzeit in Azure Automation messbar erhöht.
> * **Versionsstreitigkeiten vermeiden.** Eine harte `RequiredModules` Einschränkung löst beim Import eine automatische Auflösung aus und kann eine bestimmte `Az.Accounts` Version hereinziehen, die mit der vom Runbook selbst festgelegten kollidiert (Az.\*-Untermodule sind notorisch versionssensitiv). Wenn das Runbook seine eigenen `#Requires -Modules` deklarieren lässt, bleibt die Versionswahl beim Aufrufer.
> * **Autorität pro Runbook.** In Azure Automation ist der kanonische Ort für die Deklaration von Modulanforderungen auf Runbook-Ebene über `#Requires`, nicht auf Ebene des Hilfsmoduls. Das Hilfsmodul macht die Abhängigkeit informativ sichtbar (über `ExternalModuleDependencies` im Manifest) und über die Laufzeitprüfung oben, sodass eine Fehlkonfiguration mit einer umsetzbaren Meldung laut fehlschlägt, statt stillschweigend einen Versionskonflikt zu maskieren.

`Az.Storage` ist **nicht** erforderlich und sollte nicht im selben Runbook importiert werden, um den oben genannten Assembly-Konflikt zu vermeiden.

## Schnellstart

Der minimal funktionsfähige Aufruf erfordert die lokalen Dateipfade, den Containernamen, die Ressourcengruppe und den Namen des Storage Account:

```powershell
$csvPath = Join-Path $env:TEMP 'devices.csv'
$exportData | Export-Csv -Path $csvPath -NoTypeInformation -Encoding UTF8

$results = Publish-RjRbFilesToStorageContainer `
    -FilePaths          $csvPath `
    -ContainerName      'reports' `
    -ResourceGroupName  'rg-reports' `
    -StorageAccountName 'stcontosoreports'

$results | Format-Table BlobName, EndTime, SASLink
```

Dies lädt `devices.csv` in den `reports` Container in `stcontosoreports` und gibt ein Objekt mit Blob-Namen, SAS-Ablaufzeitstempel und einer sofort nutzbaren Download-URL zurück, die standardmäßig 6 Tage gültig ist.

## Parameter

### Erforderlich

| Parameter            | Typ        | Beschreibung                                                                                                                                                                                                                                                                                                           |
| -------------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `FilePaths`          | `string[]` | Ein oder mehrere lokale Dateipfade zum Hochladen. Jeder Pfad muss auf eine vorhandene Datei verweisen (`Test-Path -PathType Leaf`); die Funktion wirft im Vorfeld, wenn ein Eintrag fehlt.                                                                                                                             |
| `ContainerName`      | `string`   | Ziel-Blob-Container. Wird automatisch erstellt, falls er nicht existiert. Muss den Azure-Container-Namensregeln entsprechen (Kleinbuchstaben, 3–63 Zeichen, alphanumerisch + Bindestrich). Der Containername ist eine *pro Runbook* Entscheidung und wird im Runbook festgelegt, nicht in den zentralen Einstellungen. |
| `ResourceGroupName`  | `string`   | Ressourcengruppe, die den Storage Account enthält. Wird normalerweise mit der zentralen Einstellung `RJReport.StorageAccount.ResourceGroup`.                                                                                                                                                                           |
| `StorageAccountName` | `string`   | Name des Azure Storage Account. Wird normalerweise mit der zentralen Einstellung `RJReport.StorageAccount.StorageAccountName`.                                                                                                                                                                                         |

### Optional

| Parameter           | Typ      | Standard          | Beschreibung                                                                                                                                                                                                                                            |
| ------------------- | -------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `SubscriptionId`    | `string` | aktueller Kontext | Azure-Abonnement, das den Storage Account hostet. Wenn angegeben, `Set-AzContext -Subscription` wird vor jeder Speicheroperation aufgerufen. Weglassen, um den aktuellen `Az` Kontext zu verwenden.                                                     |
| `LinkExpiryDays`    | `int`    | `6`               | Gültigkeit des SAS-Links in Tagen. Validiert auf `[1, 3650]`. Derselbe Ablaufzeitstempel wird auf alle Blobs in einem einzelnen Aufruf angewendet. Wird normalerweise mit der zentralen Einstellung verknüpft `RJReport.StorageAccount.LinkExpiryDays`. |
| `AddBlobNamePrefix` | `bool`   | `$false`          | Wenn `$true`, werden Blob-Namen mit `yyyyMMdd-HHmmss-` (Zeitstempel von `Get-Date` zum Upload-Zeitpunkt) vorangestellt, um Überschreibungen bei wiederholten Ausführungen zu verhindern. Der ursprüngliche Dateiname bleibt als Suffix erhalten.        |

> **Hinweis:** Die Zuordnung zwischen diesen Parametern und der zentralen RealmJoin-Anpassungs-JSON (einschließlich der empfohlenen Standardwerte) ist dokumentiert in [Runbook-Berichtseinstellungen — Bereitstellung über Storage Account](/de/automatisierung/runbooks/runbook-report-settings.md#storage-account-delivery).

## Verwendungsbeispiele

### Empfohlenes Runbook-Muster

Dies ist das kanonische Muster, das von Reporting-Runbooks verwendet wird. Die Speicher-Konfiguration wird aus der zentralen RealmJoin-Anpassung über `Use-RJInterface -Type Setting`, der Container ist pro Runbook fest codiert, und eine fehlende Konfiguration führt dazu, dass das Runbook mit einer umsetzbaren Meldung abbricht:

```powershell
#Requires -Modules @{ModuleName = "RealmJoin.RunbookHelper"; ModuleVersion = "0.8.6" }
#Requires -Modules @{ModuleName = "Az.Accounts"; ModuleVersion = "5.3.4" }

param(
    [string] $ContainerName = "my-runbook-output",

    [ValidateScript( { Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process; Use-RJInterface -Type Setting -Attribute "RJReport.StorageAccount.ResourceGroup" } )]
    [string] $ResourceGroupName,

    [ValidateScript( { Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process; Use-RJInterface -Type Setting -Attribute "RJReport.StorageAccount.StorageAccountName" } )]
    [string] $StorageAccountName,

    [ValidateScript( { Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process; Use-RJInterface -Type Setting -Attribute "RJReport.StorageAccount.LinkExpiryDays" } )]
    [ValidateRange(1, 3650)]
    [int] $LinkExpiryDays = 6
)

Connect-RjRbAzAccount

if ((-not $ResourceGroupName) -or (-not $StorageAccountName)) {
    "## Um in einen Storage Account zu exportieren, verwenden Sie bitte die RJ Runbooks Customization"
    "## ( https://portal.realmjoin.com/settings/runbooks-customizations ) zur Konfiguration:"
    "##   - RJReport.StorageAccount.ResourceGroup"
    "##   - RJReport.StorageAccount.StorageAccountName"
    throw "Fehlende Storage Account-Konfiguration."
}

# … die Exportdatei erzeugen …
$exportPath = "myReport.csv"

$uploadResults = Publish-RjRbFilesToStorageContainer `
    -FilePaths          @($exportPath) `
    -ContainerName      $ContainerName `
    -ResourceGroupName  $ResourceGroupName `
    -StorageAccountName $StorageAccountName `
    -LinkExpiryDays     $LinkExpiryDays `
    -AddBlobNamePrefix  $true

$uploadResult = $uploadResults[0]
"## Export erstellt."
"## Ablauf des Links: $($uploadResult.EndTime)"
$uploadResult.SASLink | Out-String
```

Einige Konventionen, die es sich lohnt beizubehalten, wenn dieses Muster übernommen wird:

* Die drei zentralen Einstellungen (`Ressourcengruppe`, `StorageAccountName`, `LinkExpiryDays`) werden als Runbook-Parameter bereitgestellt und über `Use-RJInterface -Type Setting`, aber typischerweise *ausgeblendet* in der Runbook-Anpassung (`"Hide": true`) damit Endbenutzer sie nie sehen.
* Der Containername wird pro Runbook fest codiert (oft über einen `param` Standardwert), damit Lebenszyklusrichtlinien und Zugriffskontrollen pro Exporttyp angepasst werden können — er ist absichtlich *nicht* eine zentrale Einstellung.
* `AddBlobNamePrefix $true` ist der sichere Standard für periodische Exporte, die bei jedem Lauf denselben Dateinamen erzeugen.
* Die Funktion wird innerhalb des Haupt- `try { … } catch { throw $_ } finally { Disconnect-AzAccount … }` Blocks des Runbooks aufgerufen, damit partielle Fehler an den Automation-Job weitergereicht werden und der Az-Kontext auch bei Erfolg freigegeben wird.

### Mehrere Dateien in einem Aufruf

`FilePaths` akzeptiert ein Array; jede Datei wird nacheinander hochgeladen und für jeden hochgeladenen Blob wird ein Ergebnisobjekt zurückgegeben.

```powershell
$results = Publish-RjRbFilesToStorageContainer `
    -FilePaths          @($csvPath, $xlsxPath) `
    -ContainerName      'reports' `
    -ResourceGroupName  $ResourceGroupName `
    -StorageAccountName $StorageAccountName

foreach ($r in $results) {
    "Hochgeladen $($r.BlobName) — Download bis $($r.EndTime): $($r.SASLink)"
}
```

### Benutzerdefinierte Link-Laufzeit und explizites Abonnement

```powershell
Publish-RjRbFilesToStorageContainer `
    -FilePaths          $exportPaths `
    -ContainerName      'quarterly-reports' `
    -ResourceGroupName  $ResourceGroupName `
    -StorageAccountName $StorageAccountName `
    -SubscriptionId     '00000000-0000-0000-0000-000000000000' `
    -LinkExpiryDays     30
```

Nützlich, wenn das Runbook mehrere Abonnements umfasst oder wenn die nachgelagerten Empfänger ein längeres Zeitfenster als die 6-Tage-Standarddauer benötigen.

### Kombination mit `Send-RjRbReportEmail`

Ein gängiges Muster ist es, umfangreiche Daten in den Blob-Speicher hochzuladen und den SAS-Link in eine Bericht-E-Mail einzubetten, sodass die E-Mail deutlich unter dem 4-MB-Graph `sendMail` Limit bleibt:

```powershell
$uploaded = Publish-RjRbFilesToStorageContainer `
    -FilePaths          $csvPath `
    -ContainerName      'reports' `
    -ResourceGroupName  $ResourceGroupName `
    -StorageAccountName $StorageAccountName `
    -AddBlobNamePrefix  $true

$linkLine = "[Download {0}]({1}) (gültig bis {2:yyyy-MM-dd HH:mm} UTC)" -f `
    $uploaded[0].BlobName, $uploaded[0].SASLink, $uploaded[0].EndTime.ToUniversalTime()

$reportMd = @"
# Geräteinventar

Die vollständige Geräteliste ist als Download verfügbar:

$linkLine
"@

Send-RjRbReportEmail `
    -EmailFrom       $emailFrom `
    -EmailTo         'it-reports@contoso.com' `
    -Subject         "Device Inventory — $(Get-Date -Format 'yyyy-MM-dd')" `
    -MarkdownContent $reportMd
```

Siehe [Send-RjRbReportEmail](/de/dev-reference/report-functions/send-rjrbreportemail.md) für den E-Mail-Teil dieses Musters.

## Verhalten & Fehlerbehandlung

### Vorab-Dateivalidierung

Bevor ein Azure-Aufruf ausgeführt wird, iteriert die Funktion über `FilePaths` und löst aus `Datei '<path>' wurde nicht gefunden.` für den ersten fehlenden Eintrag. Dies verhindert partielle Uploads, wenn der Aufrufer sich vertippt.

### Auflösung des Azure-Kontexts

`Get-AzContext` wird zuerst geprüft. Wenn kein Kontext vorhanden ist oder der Kontext kein `Konto` hat (z. B. eine frische Runbook-Ausführung), ruft die Funktion `Connect-RjRbAzAccount` auf, um die verwaltete Identität zu authentifizieren. Wenn `-SubscriptionId` angegeben ist, `Set-AzContext -Subscription` wird anschließend aufgerufen.

### Containererstellung

Der Container wird mit einer `PUT …?restype=container` Anfrage erstellt:

* **HTTP 201** — Container erstellt.
* **HTTP 409** — Container existiert bereits; als Erfolg behandelt.
* **Jeder andere Status** — die Funktion löst aus `Containererstellung fehlgeschlagen (<status>): <body>`. Ein HTTP 403 mit `KeyBasedAuthenticationNotPermitted` bedeutet, dass der Shared-Key-Zugriff auf dem Storage Account deaktiviert ist.

### Upload-Fehler

Jede Datei wird über `HttpClient.SendAsync`hochgeladen. Ein nicht erfolgreicher Status beendet den Aufruf mit `Blob-Upload fehlgeschlagen (<status>): <body>`, einschließlich des von Azure Storage zurückgegebenen Rohfehlers. Früher bereits im selben Aufruf hochgeladene Dateien bleiben im Storage Account — der Aufrufer möchte den Aufruf möglicherweise in try/catch kapseln und bei inakzeptablen partiellen Uploads eine Bereinigung ausführen.

### Schlüsselabruffehler

`Invoke-AzRestMethod` wird verwendet, um den ARM- `listKeys` Endpunkt aufzurufen. Wenn der Antwortstatus etwas anderes als 200 ist, löst die Funktion aus `Konnte Storage-Account-Schlüssel für '<account>' in der Ressourcengruppe '<rg>' nicht abrufen. Status: <status>`. Die häufigsten Ursachen sind:

* Fehlendes `Microsoft.Storage/storageAccounts/listKeys/action` auf der verwalteten Identität.
* Falscher Abonnementskontext (kombinieren mit `-SubscriptionId`).
* Tippfehler in `StorageAccountName` oder `ResourceGroupName`.
* Die zentralen Einstellungen `RJReport.StorageAccount.ResourceGroup` / `RJReport.StorageAccount.StorageAccountName` nicht konfiguriert — siehe [Runbook-Berichtseinstellungen](/de/automatisierung/runbooks/runbook-report-settings.md#storage-account-delivery).

### Eigenschaften von SAS Token

Die generierten Token verwenden:

* `sv=2023-11-03` (signierte Version)
* `sr=b` (auf Blob-Ebene)
* `sp=r` (nur lesend)
* `spr=https` (nur HTTPS)
* `st` auf 5 Minuten in der Vergangenheit gesetzt (Toleranz für Uhrzeitabweichungen) und `se` zu `LinkExpiryDays` ab dem Zeitpunkt des Aufrufs.

Token werden mit dem Schlüssel des Storage Account signiert. **Jeder mit dem Link kann den Blob bis zum Ablauf herunterladen** — behandeln Sie die zurückgegebene SAS-URL als Geheimnis.

## Ausgaben

Jeder erfolgreiche Upload erzeugt ein `PSCustomObject` mit diesen Eigenschaften:

| Eigenschaft | Typ        | Beschreibung                                                                                                         |
| ----------- | ---------- | -------------------------------------------------------------------------------------------------------------------- |
| `BlobName`  | `string`   | Der endgültige Blobname im Container, einschließlich des Zeitstempelpräfixes, falls `AddBlobNamePrefix` ist `$true`. |
| `EndTime`   | `datetime` | Ablauf des SAS in lokaler Zeit (auch in der URL als UTC kodiert).                                                    |
| `SASLink`   | `string`   | Vollständig qualifizierte HTTPS-Download-URL mit eingebettetem SAS Token.                                            |

Die Ergebnisse werden in derselben Reihenfolge zurückgegeben wie `FilePaths`. Auch beim Hochladen einer einzelnen Datei ist der Rückgabewert ein Array — indizieren Sie es (`$results[0]`) oder iterieren Sie mit `foreach` anstatt es als Skalar zu behandeln.

## Siehe auch

* [Runbook-Berichtseinstellungen — Bereitstellung über Storage Account](/de/automatisierung/runbooks/runbook-report-settings.md#storage-account-delivery) — zentrale Konfiguration des Storage Account, des Link-Ablaufs und des von Berichts-Runbooks verwendeten Blob-Namenspräfixes.
* [Send-RjRbReportEmail](/de/dev-reference/report-functions/send-rjrbreportemail.md) — begleitende Hilfsfunktion zum Versenden von Berichten per E-Mail; wird häufig mit dieser Funktion kombiniert, um die E-Mail-Nutzlast klein zu halten.
* Microsoft Docs: [Mit gemeinsamem Schlüssel autorisieren](https://learn.microsoft.com/en-us/rest/api/storageservices/authorize-with-shared-key) — vom Hilfsprogramm verwendetes Signaturschema.
* Microsoft Docs: [Einen Service-SAS erstellen](https://learn.microsoft.com/en-us/rest/api/storageservices/create-service-sas) — SAS Token-Format, das zurückgegeben wird in `SASLink`.


---

# 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.realmjoin.com/de/dev-reference/report-functions/publish-rjrbfilestostoragecontainer.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
