Publish-RjRbFilesToStorageContainer

Lokale Dateien aus Azure Automation-Runbooks in einen Azure Storage-Container hochladen und zeitlich begrenzte SAS-Download-Links zurückgeben.

Überblick

Publish-RjRbFilesToStorageContainer ist der Standard-Helfer zum Bereitstellen von Berichtdateien (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 jedes Blob einen zeitlich begrenzten SAS-Downloadlink zurück, der sich für die Einbindung in Bericht-E-Mails, Teams-Nachrichten oder Runbook-Ausgaben eignet.

Wichtige 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 vermieden, der in gemischten Reporting-Runbooks auftritt.

  • Selbstverbindend — wenn kein Az Kontext aktiv ist, ruft die Funktion transparent Connect-RjRbAzAccountauf. Ein optionaler -SubscriptionId wechselt den Kontext vor jeder Speicheroperation.

  • Container automatisch erstellt — wenn der Ziel-Container noch nicht existiert, wird er on the fly erstellt; ein vorhandener Container (HTTP 409) wird als Erfolg behandelt.

  • HttpClient-basierte Uploads — verwendet System.Net.Http.HttpClient direkt, weil der Interceptor von Azure Automation's Invoke-RestMethod die erforderlichen benutzerdefinierten Header (x-ms-blob-type) bei Binärdaten entfernt.

  • Nur-Lese-SAS-Links — jede zurückgegebene URL wird mit dem Schlüssel des Storage Accounts signiert, ist auf ein einzelnes Blob beschränkt, nur per HTTPS verwendbar und gültig für LinkExpiryDays Tage (Standard 6).

Die zentralen Speichereinstellungen (Ressourcengruppe, Kontoname, Ablauf-Tage, Blob-Namenspräfix), die von einem typischen Runbook verwendet werden, stehen im RealmJoin-Anpassungs-JSON und sind dokumentiert in Runbook Report Settings — Storage Account Delivery. Dieses Dokument konzentriert sich darauf, die Funktion aus einem Runbook heraus aufzurufen.

Voraussetzungen

Azure Storage Account

Ein vorhandener Azure Storage Account (allgemein empfohlen: v2) ist erforderlich. Der Ziel-Container muss vorher nicht 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 auf dem Storage Account oder seiner Ressourcengruppe die folgenden Berechtigungen:

Aktion
Erforderlich für

Microsoft.Storage/storageAccounts/read

Lesen des Storage Accounts

Microsoft.Storage/storageAccounts/listKeys/action

Abrufen des Kontoschlüssels, der für SharedKey-Signierung und SAS-Generierung verwendet wird

Die integrierte Rolle Storage Account Contributor deckt beides ab. Storage Blob Data Contributor allein ist nicht ausreichend, da die Funktion Anforderungen mit dem Kontoschlüssel signiert, anstatt AAD-gestützte Blob-Operationen zu verwenden.

Modul-Konnektivität

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 konsumierenden Runbook:

Wenn Az.Accounts zur Laufzeit nicht verfügbar ist, schlägt die Funktion schnell mit einer klaren Fehlermeldung fehl — sie prüft vorab auf Get-AzContext und wirft "Publish-RjRbFilesToStorageContainer benötigt das Modul 'Az.Accounts'. Fügen Sie #Requires -Modules @{ModuleName = 'Az.Accounts'; ModuleVersion = '5.3.4'} zum aufrufenden Runbook hinzu." bevor ein Azure-Aufruf erfolgt.

Warum ist Az.Accounts nicht als RequiredModules Eintrag in RealmJoin.RunbookHelper.psd1?

Az.Accounts wird absichtlich nur unter ExternalModuleDependencies (informativ) und nicht unter RequiredModules (erzwingt bei Import-Module Zeit):

  • Bezahlen Sie nur für das, was Sie nutzen. Viele Runbooks verwenden nur Graph-basierte Helfer (z. B. Send-RjReportEmail ohne -UseNativeGraphRequest, oder Invoke-RjRbRestMethodGraph) und verwenden niemals ein Az.*-Cmdlet. Das Hochstufen von Az.Accounts zu RequiredModules würde jedes konsumierende Runbook zwingen, das Modul mitzuliefern, selbst wenn im Codepfad nichts es benötigt — was die Cold-Start-Zeit in Azure Automation messbar erhöht.

  • Vermeiden Sie Versionskonflikte. Eine harte RequiredModules Einschränkung löst beim Import automatisch eine Auflösung aus und kann eine bestimmte Az.Accounts Version mitbringen, die mit dem kollidiert, was das Runbook selbst festlegt (Az.*-Untermodule sind bekanntermaßen sehr versionssensitiv). Wenn das Runbook seine eigenen #Requires -Modules deklariert, bleibt die Versionswahl beim Aufrufer.

  • Autorität pro Runbook. In Azure Automation ist der kanonische Ort zum Deklarieren von Modulanforderungen auf Runbook-Ebene via #Requires, nicht auf Ebene des Hilfsmoduls. Das Hilfsmodul macht die Abhängigkeit informativ sichtbar (über ExternalModuleDependencies im Manifest) und über die obige Laufzeitprüfung, sodass Fehlkonfigurationen mit einer umsetzbaren Meldung laut fehlschlagen, statt einen Versionskonflikt stillschweigend zu verdecken.

Az.Storage ist nicht erforderlich und sollte nicht im selben Runbook importiert werden, um den oben erwähnten Assembly-Konflikt zu vermeiden.

Schnellstart

Der minimal notwendige Aufruf erfordert die lokalen Dateipfade, den Containernamen, die Ressourcengruppe und den Namen des Storage Accounts:

Dadurch wird devices.csv in den reports Container in stcontosoreports hochgeladen und ein Objekt mit dem Blob-Namen, dem SAS-Ablaufzeitstempel und einer sofort teilbaren Download-URL zurückgegeben, 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 vorab, wenn ein Eintrag fehlt.

ContainerName

string

Ziel-Blob-Container. Wird automatisch erstellt, wenn er nicht existiert. Muss den Azure-Container-Namensregeln entsprechen (klein geschrieben, 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. Normalerweise an die zentrale Einstellung gekoppelt RJReport.AzureStorage.ResourceGroup.

StorageAccountName

string

Name des Azure Storage Accounts. Normalerweise an die zentrale Einstellung gekoppelt RJReport.AzureStorage.StorageAccountName.

Optional

Parameter
Typ
Standard
Beschreibung

SubscriptionId

string

aktueller Kontext

Azure-Abonnement, das den Storage Account hostet. Falls 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. Normalerweise an die zentrale Einstellung gekoppelt RJReport.AzureStorage.LinkExpiryDays.

AddBlobNamePrefix

bool

$false

Wenn $truewerden Blob-Namen mit yyyyMMdd-HHmmss- (Zeitstempel von Get-Date zum Zeitpunkt des Uploads) präfixiert, um Überschreibungen bei wiederholten Läufen zu verhindern. Der ursprüngliche Dateiname bleibt als Suffix erhalten.

Hinweis: Die Zuordnung zwischen diesen Parametern und dem zentralen RealmJoin-Anpassungs-JSON (einschließlich der empfohlenen Standardwerte) ist dokumentiert in Runbook Report Settings — Storage Account Delivery.

Verwendungsbeispiele

Empfohlenes Runbook-Muster

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

Einige Konventionen, die es sich lohnt beizubehalten, wenn Sie dieses Muster übernehmen:

  • Die drei zentralen Einstellungen (ResourceGroup, StorageAccountName, LinkExpiryDays) werden als Runbook-Parameter bereitgestellt, die über Use-RJInterface -Type Setting, aber typischerweise verborgen in der Runbook-Anpassung ("Hide": true) damit Endbenutzer sie nie sehen.

  • Der Containername ist pro Runbook fest codiert (oft über einen param -Standardwert), sodass Lebenszyklusrichtlinien und Zugriffskontrollen pro Exporttyp angepasst werden können — er ist absichtlich nicht eine zentrale Einstellung.

  • AddBlobNamePrefix $true ist die sichere Standardoption für regelmäßige Exporte, die bei jedem Lauf denselben Dateinamen erzeugen.

  • Die Funktion wird im Hauptblock des Runbooks try { … } catch { throw $_ } finally { Disconnect-AzAccount … } aufgerufen, sodass Teilfehler 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 jedes hochgeladene Blob wird ein Ergebnisobjekt zurückgegeben.

Nützlich, wenn das Runbook mehrere Abonnements umfasst oder wenn nachgelagerte Empfänger ein längeres Zeitfenster als die Standardvorgabe von 6 Tagen benötigen.

Kombiniert mit Send-RjReportEmail

Ein gängiges Muster besteht darin, umfangreiche Daten in Blob Storage hochzuladen und den SAS-Link in eine Bericht-E-Mail einzubetten, wodurch die E-Mail deutlich unter dem 4-MB-Graph- sendMail Limit bleibt:

Siehe Send-RjReportEmail für die E-Mail-Seite dieses Musters.

Verhalten & Fehlerbehandlung

Vorab-Dateivalidierung

Bevor ein Azure-Aufruf erfolgt, durchläuft die Funktion FilePaths und wirft Datei '<path>' wurde nicht gefunden. für den ersten fehlenden Eintrag. Dadurch werden Teil-Uploads verhindert, wenn der Aufrufer einen Tippfehler übergibt.

Azure-Kontextauflösung

Get-AzContext wird zuerst geprüft. Wenn es keinen Kontext gibt oder der Kontext kein Konto hat (z. B. eine frische Runbook-Ausführung), ruft die Funktion Connect-RjRbAzAccount zur Authentifizierung der verwalteten Identität auf. 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; wird als Erfolg behandelt.

  • Jeder andere Status — die Funktion wirft Containererstellung fehlgeschlagen (<status>): <body>.

Uploadfehler

Jede Datei wird über HttpClient.SendAsynchochgeladen. Ein nicht erfolgreicher Status beendet den Aufruf mit Blob-Upload fehlgeschlagen (<status>): <body>, einschließlich des rohen Fehlers, den Azure Storage zurückgibt. Dateien, die in demselben Aufruf bereits hochgeladen wurden, bleiben im Storage Account — der Aufrufer sollte den Aufruf eventuell in try/catch einschließen und eine Bereinigung durchführen, wenn Teil-Uploads nicht akzeptabel sind.

Fehler beim Abrufen der Schlüssel

Invoke-AzRestMethod wird verwendet, um den ARM listKeys Endpunkt aufzurufen. Wenn der Antwortstatus etwas anderes als 200 ist, wirft die Funktion Fehler beim Abrufen der Storage-Account-Schlüssel für '<account>' in Ressourcengruppe '<rg>'. Status: <status>. Die häufigsten Ursachen sind:

  • Fehlendes Microsoft.Storage/storageAccounts/listKeys/action bei der verwalteten Identität.

  • Falscher Abonnementkontext (kombinieren mit -SubscriptionId).

  • Tippfehler in StorageAccountName oder ResourceGroupName.

  • Die zentralen Einstellungen RJReport.AzureStorage.ResourceGroup / RJReport.AzureStorage.StorageAccountName nicht konfiguriert — siehe Runbook-Berichteinstellungen.

SAS-Token-Merkmale

Die erzeugten Token verwenden:

  • sv=2023-11-03 (signierte Version)

  • sr=b (auf Blob beschränkt)

  • sp=r (schreibgeschützt)

  • spr=https (nur HTTPS)

  • st auf 5 Minuten in der Vergangenheit festgelegt (Toleranz für Uhrzeitabweichungen) und se zu LinkExpiryDays ab dem Zeitpunkt des Aufrufs.

Tokens 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 Ortszeit (auch in der URL als UTC codiert).

SASLink

string

Vollständig qualifizierte HTTPS-Download-URL mit eingebettetem SAS Token.

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

Siehe auch

Zuletzt aktualisiert

War das hilfreich?