> For the complete documentation index, see [llms.txt](https://docs.devolutions.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.devolutions.net/powershell-universal/de/config/hosting/azure.md).

# Azure

PowerShell Universal ist eine ASP.NET Core-Webanwendung und kann in Windows Azure Web Apps gehostet werden.

## Container-Web-App

Container-Web-Apps ermöglichen die Verwendung von Docker-Images als Web-Apps in Azure. Im Azure-Portal können Sie eine Docker-Container-Web-App mit dem Assistenten App Services \ Create Web App erstellen.

Sobald Sie eine Ressourcengruppe ausgewählt, einen Namen zugewiesen und einen Compute-Plan gewählt haben, können Sie die Web-App erstellen.

![Container-Web-App](/files/XfBwf8XaylxtivUX00EE)

Als Nächstes müssen Sie das Image in Ihrer Web-App bereitstellen. Wählen Sie dazu das Deployment Center und konfigurieren Sie das abzurufende Image. Sie können entweder eine statische getaggte Version (wie 2.7.3) abrufen oder die neueste Version, sodass Ihre Web-App automatisch mit neuen PowerShell Universal-Releases aktuell bleibt. Verwenden Sie das Tag mit dem Suffix `azure`. Es ist für die Ausführung in Azure vorkonfiguriert.

{% hint style="info" %}
Für Produktionsumgebungen empfehlen wir, eine getaggte Version festzulegen, um unbeabsichtigte Aktualisierungen Ihres Containers beim Neustart zu vermeiden. Standardmäßig aktualisiert Azure Container automatisch, wenn ein Tag wie latest aktualisiert wird. So können Sie Aktualisierungen Ihrer PowerShell Universal-Version steuern.
{% endhint %}

<figure><img src="/files/01EmYW8oRxGoy7rmcS8t" alt=""><figcaption><p>Docker-Konfiguration</p></figcaption></figure>

### Lokale Persistenz

Standardmäßig schreibt der Container in das Verzeichnis `/home`.

Sie müssen sicherstellen, dass die Umgebungsvariable `WEBSITES_ENABLE_APP_SERVICE_STORAGE` auf true gesetzt ist. Damit wird der Container so konfiguriert, dass der Ordner `/home` persistent ist, und dort werden die Konfigurationsdaten für PowerShell Universal gespeichert.

### Git und SQL

Wenn Sie die Git-Integration in PowerShell Universal verwenden möchten, empfehlen wir, einen SQL-Server und eine Datenbank für die Speicherung einzurichten. Git wird verwendet, um Konfigurationsdateien beim Start des Containers zu synchronisieren. SQL speichert die Git-Konfigurationseinstellungen neben Ressourcen wie Jobs, App-Tokens und Identitäten.

Für den Anfang benötigen Sie eine Azure SQL-Datenbank. Nachdem Sie die Ressource erstellt haben, müssen Sie die Verbindungszeichenfolge aus der Datenbank kopieren, um sie PowerShell Universal bereitzustellen.

<figure><img src="/files/7NkqRh1oSSnRFftHQh3x" alt=""><figcaption></figcaption></figure>

Stellen Sie sicher, dass Sie Azure-Diensten den Zugriff auf die Datenbank erlaubt haben.

<figure><img src="/files/9cXKFfOFTf2sv6WKu7Ia" alt=""><figcaption></figcaption></figure>

Um die SQL-Unterstützung zu aktivieren, sollten Sie die Plugins innerhalb von PowerShell Universal so einstellen, dass das SQL-Plugin in der Anwendungskonfiguration Ihrer Web-App verwendet wird.

Erstellen Sie eine Einstellung `Plugins__0` mit dem Wert `SQL`. Setzen Sie anschließend den Wert `Data__ConnectionString` auf Ihre SQL-Server-Datenbank.

<figure><img src="/files/s1azvJjLKJXzMzTRTbEj" alt=""><figcaption></figcaption></figure>

Sobald Sie SQL konfiguriert haben, können Sie Ihren Container starten. Das Datenbankschema wird beim Start des Containers erstellt. Als Nächstes müssen Sie Git innerhalb von PowerShell Universal konfigurieren, indem Sie auf Settings \ Git klicken. Geben Sie Ihr Remote, den Branch, Benutzernamen, Passwort oder ein persönliches Zugriffstoken sowie den Synchronisierungsmodus ein. Push-only wird in dieser Konfiguration nicht empfohlen, da der Containerzustand zwischen Neustarts verloren geht. Stellen Sie sicher, dass der Initialisierungsmodus auf Clone gesetzt ist.

{% hint style="info" %}
Git-Einstellungen werden in Ihrer SQL-Datenbank gespeichert und bei jedem Start des Containers abgerufen.
{% endhint %}

<figure><img src="/files/pm674XCeE9WXx5RAKNqK" alt=""><figcaption></figcaption></figure>

### Weitergeleitete Header

Container werden typischerweise hinter einem Reverse Proxy gehostet und kennen die tatsächliche externe URL ohne zusätzliche Konfiguration nicht. Um sicherzustellen, dass Systeme, die die externe URL benötigen, wie OpenID Connect, die richtigen Informationen erhalten, müssen Sie die Umgebungsvariable `ASPNETCORE_FORWARDEDHEADERS_ENABLED` auf `true` setzen.

![](/files/viKx8Edc8Q4I1LTAiv46)

Weitere Informationen finden Sie in diesem Blogbeitrag von [Microsoft](https://devblogs.microsoft.com/dotnet/forwarded-headers-middleware-updates-in-net-core-3-0-preview-6/).

### Bicep

Sie können die folgende Bicep-Vorlage verwenden, um eine Container-Web-App mit persistentem Speicher bereitzustellen.

```bicep
@description('Name of Azure Web App')
param siteName string = 'psu-${uniqueString(resourceGroup().id)}'

@description('The version of PowerShell Universal')
param version string = '5.4.4'

@description('App Service Plan Pricing Tier')
@allowed([
  'B1'
  'B2'
  'B3'
  'S1'
  'S2'
  'S3'
  'P1V2'
  'P2V2'
  'P2V3'
])
param servicePlanPricingTier string = 'S2'
var servicePlanName = '${siteName}-asp'

@description('Location for all the resources.')
param location string = resourceGroup().location

var servicePlanPricingTiers = {
  F1: {
    tier: 'Free'
  }
  B1: {
    tier: 'Basic'
  }
  B2: {
    tier: 'Basic'
  }
  B3: {
    tier: 'Basic'
  }
  S1: {
    tier: 'Standard'
  }
  S2: {
    tier: 'Standard'
  }
  S3: {
    tier: 'Standard'
  }
  P1V2: {
    tier: 'Standard'
  }
  P2V2: {
    tier: 'Standard'
  }
  P2V3: {
    tier: 'Standard'
  }
}

resource planResource 'Microsoft.Web/serverfarms@2024-04-01' = {
  name: servicePlanName
  location: location
  sku: {
    name: servicePlanPricingTier
    tier: servicePlanPricingTiers[servicePlanPricingTier].tier
    capacity: 1
  }
  kind: 'linux'
  properties: {
    reserved: true
  }
}

resource siteResource 'Microsoft.Web/sites@2024-04-01' = {
  name: siteName
  location: location
  properties: {
    serverFarmId: planResource.id
    siteConfig: {
      linuxFxVersion: 'DOCKER|ironmansoftware/universal:${version}-azure'
    }
  }
}

resource siteWebAppsettingsResource 'Microsoft.Web/sites/config@2024-04-01' = {
  parent: siteResource
  name: 'appsettings'
  properties: {
    WEBSITES_ENABLE_APP_SERVICE_STORAGE: 'true'
  }
}

```

### Container-Sidecars

Container-Web-Apps unterstützen außerdem [Sidecar-Container](https://learn.microsoft.com/en-us/azure/app-service/overview-sidecar), mit denen Sie zusätzliche Container neben dem PowerShell Universal-Container ausführen können. Dies ist nützlich zur Unterstützung von Diensten wie Proxys, Agents, Collectors oder anderen Begleitprozessen. Wenn Sie PowerShell Universal in dieser Konfiguration hosten, stellen Sie sicher, dass der Web-Container den richtigen HTTP-Port bereitstellt. Standardmäßig lauscht PowerShell Universal auf Port `5000`.

## Standard-Web-App

### Manuelles Erstellen einer Web-App

Im Azure-Portal müssen Sie eine neue Web App-Ressource erstellen. PowerShell Universal benötigt derzeit den .NET 10-Runtime-Stack. Sie können entweder Linux oder Windows verwenden.

{% hint style="info" %}
Wenn Sie beim Konfigurieren Ihrer WebApp in Azure einen Windows-Hostingplan anstelle eines Linux-Hostingplans wählen, müssen Sie einen Basic Plan (B1) oder höher wählen, um 64-Bit-Apps verwenden zu können. Außerdem müssen Sie zu Settings > Configuration > General setting > Platform gehen und 64-bit auswählen, bevor Sie den Befehl `Publish-AzWebApp` ausführen, sonst schlägt die Installation fehl.
{% endhint %}

<figure><img src="/files/9uFiC6BOMzDmHeX5auGC" alt=""><figcaption></figcaption></figure>

**Startbefehl (nur Linux)**

Beim Hosten in einer Linux-Umgebung müssen Sie den Startbefehl unter Settings \ Configuration \ General Settings \ Startup Command auf Folgendes setzen.

```
dotnet Universal.Server.dll
```

Im folgenden Beispiel verwenden wir das Azure PowerShell-Modul, um die Web-App manuell bereitzustellen.

Zunächst müssen Sie Azure PowerShell installieren.

```powershell
Install-Module Az
```

Nach der Installation müssen Sie sich mit Ihrem Abonnement verbinden.

```powershell
Connect-AzAccount
```

### Windows-Dateien bereitstellen

Wenn Sie Windows verwenden, müssen Sie die Windows-ZIP-Datei herunterladen. Damit wird die neueste Version von PowerShell Universal heruntergeladen.

```powershell
$LatestVersion = Invoke-RestMethod https://imsreleases.blob.core.windows.net/universal/production/v5-version.txt
Invoke-WebRequest "https://imsreleases.blob.core.windows.net/universal/production/$LatestVersion/Universal.win7-x64.$LatestVersion.zip" -OutFile .\Universal.zip
```

### Linux-Dateien bereitstellen

Wenn Sie Linux verwenden, müssen Sie die Linux-ZIP-Datei herunterladen. Damit wird die neueste Version von PowerShell Universal heruntergeladen.

```powershell
$LatestVersion = Invoke-RestMethod https://imsreleases.blob.core.windows.net/universal/production/v5-version.txt
Invoke-WebRequest "https://imsreleases.blob.core.windows.net/universal/production/$LatestVersion/Universal.linux-x64.$LatestVersion.zip" -OutFile .\Universal.zip
```

Nachdem wir nun das Az-Modul konfiguriert und die Universal-ZIP heruntergeladen haben, können wir die Web-App bereitstellen.

```powershell
$Parameters = @{
    Force = $true
    ResourceGroupName = 'psudemo2_group'
    Name = 'psudemo2'
    ArchivePath = '.\Universal.zip'
}
Publish-AzWebApp @Parameters
```

{% hint style="info" %}
Sie können in Azure unter Deployment Center > Logs nach dem Status Success (Active) sehen, um sicherzustellen, dass die Dateien erfolgreich bereitgestellt/installiert wurden.
{% endhint %}

### Erforderliche Einstellungsanpassungen

Diese Einstellungen können auf der Registerkarte Configuration innerhalb der Application settings festgelegt werden.

<figure><img src="/files/wyZ0PH5I6Xxc09nN6W1L" alt=""><figcaption></figcaption></figure>

#### JWT-Signaturschlüssel

Der Standard-JWT-Signaturschlüssel hat keine ausreichende Länge und muss aktualisiert werden. Dies kann in `appsettings.json` oder mithilfe von Umgebungsvariablen erfolgen.

#### appsettings.json

```
  "Jwt": {
    "SigningKey": "xXyt9UpJKB4Pb*4$hprd!JJoyOcK4ZOV**O7Hug9&@gYHc$",
    "Issuer": "IronmanSoftware",
    "Audience": "PowerShellUniversal"
  },
```

#### Umgebungsvariable

```
$Env:Jwt__SigningKey = 'xXyt9UpJKB4Pb*4$hprd!JJoyOcK4ZOV**O7Hug9&@gYHc$'
```

#### API-URL

Azure Web Apps verwenden einen Reverse Proxy und PowerShell Universal erkennt die externe URL nicht korrekt. Beim Ausführen von Jobs verwendet Universal die Management-API, um automatisch Job-, Skript- und Zeitplaninformationen nachzuschlagen. Das bedeutet, dass dies fehlschlägt, wenn die externe API-URL nicht korrekt adressiert werden kann.

Die API-URL sollte die externe HTTP-Adresse Ihrer Web-App sein. Sie können dies in `appsettings.json` oder mithilfe einer Umgebungsvariable aktualisieren.

#### appsettings.json

```
"Api": {
 "Url": "https://psudemo.azurewebsites.net"
 },
```

#### Umgebungsvariable

```
$Env:Api__Url = "https://psudemo.azurewebsites.net"
```

#### NodeName

Sie können den Namen der PowerShell Universal-Instanz festlegen, indem Sie NodeName angeben. Dadurch wird sichergestellt, dass Neustarts die PowerShell Universal-Datenbank nicht beeinträchtigen. Dies ist für LiteDB-Installationen nicht erforderlich.

```
$Env:NodeName = "psuazure"
```

#### PORT und WEBSITES\_PORT (nur Linux)

Um den Standardport in einer Linux-Web-App zu überschreiben, müssen Sie die Einstellungen PORT und WEBSITES\_PORT auf 5000 setzen.

Nach der Veröffentlichung der Web-App können Sie Ihre PowerShell Universal-Instanz aufrufen, indem Sie zur URL der Web-App navigieren.

#### Persistenter Speicher

Die Standarddatei `appsettings.json` speichert die Datenbank- und Konfigurationsdateien an einem nicht persistenten Ort. Sie können Umgebungsvariablen hinzufügen, um sie in den persistenten Speicher Ihrer Web-App zu verschieben.

**Data\_\_RepositoryPath**

Die Umgebungsvariable `Data__RepositoryPath` legt den Speicherort der Konfigurationsdateien für Universal fest. Setzen Sie den Wert auf Folgendes.

```
D:\home\Data\PowerShellUniversal\Repository
```

### Aktualisieren Ihrer Web-App

Wenn eine neue Version von PowerShell Universal veröffentlicht wird, müssen Sie die Anwendungsdateien für Ihre Web-App aktualisieren. Wir empfehlen, das Anwendungsverzeichnis zu entfernen und die Dateien neu bereitzustellen. Die Datenbank- und Konfigurationsdateien werden nicht im Anwendungsverzeichnis gespeichert.

Sie können die Dateien für Ihre Web-App mithilfe der Kudu-Befehls-API löschen. Ihre Kudu-Anmeldeinformationen verwenden Basic-Authentifizierung und sind dieselben wie Ihre [Bereitstellungsanmeldeinformationen](https://github.com/projectkudu/kudu/wiki/Deployment-credentials).

Um alle Dateien in Ihrer Web-App zu löschen, führen Sie den folgenden Befehl aus.

```powershell
$Parameters = @{
   Uri = "https://psudemo2.scm.azurewebsites.net/api/command"
   Credential = (Get-Credential)
   Body = (@{
      command = "rd /s /q D:\home\site\wwwroot"
      dir = "D:\home\site\wwwroot"
   } | ConvertTo-Json)
}

Invoke-RestMethod @Parameters
```

Nachdem Sie die Anwendungsdateien gelöscht haben, können Sie sie erneut bereitstellen, indem Sie die Schritte zur manuellen Erstellung erneut ausführen.

## Application Gateway

Sie können PowerShell Universal so konfurieren, dass es hinter einem Application Gateway innerhalb von Azure ausgeführt wird. Dies ist hilfreich, um Lastenausgleich und Hochverfügbarkeit für mehrere PowerShell Universal-Instanzen bereitzustellen.

Konfigurieren Sie zunächst einen Backend-Pool, der auf eine oder mehrere Azure Web Apps mit PowerShell Universal verweist.

<figure><img src="/files/PmHQ8MEkYXfBg3WKWENn" alt=""><figcaption><p>Backend-Pool</p></figcaption></figure>

Für die Backend-Einstellungen sollten Sie sicherstellen, dass Sie HTTPS mit einem Zertifikat einer bekannten Zertifizierungsstelle verwenden. Cookie-basierte Affinität ist erforderlich, um sicherzustellen, dass Sitzungen an einen einzelnen Knoten gebunden sind.

<figure><img src="/files/7zzDV3E7DTgd9ZVRDSDa" alt=""><figcaption><p>Backend-Pool-Einstellungen</p></figcaption></figure>

Damit Azure die richtige Web-App bereitstellen kann, müssen Sie sicherstellen, dass die Einstellung Override with new host name konfiguriert ist. Verwenden Sie den Hostnamen für das Backend-Ziel.

<figure><img src="/files/9jq7q6Q0r8dDeSaYdJUC" alt=""><figcaption><p>Backend-Einstellungen Hostname</p></figcaption></figure>

Stellen Sie sicher, dass die Backend-Pool-Regel als Ziel und nicht als Weiterleitung konfiguriert ist.

<figure><img src="/files/8w2sNJNB7hfUvJUXnj4M" alt=""><figcaption><p>Application Gateway-Regel</p></figcaption></figure>

Konfigurieren Sie eine Header-Rewrite-Regel, um den öffentlich zugänglichen Hostnamen als Header `X-Forwarded-Host` weiterzugeben. PowerShell Universal verwendet diesen, um intern URLs zu erstellen.

<figure><img src="/files/JBcm78l3fBSYWafNyIXv" alt=""><figcaption><p>Rewrite-Regel</p></figcaption></figure>

Die obige Rewrite-Regel ist eine Voraussetzung für die Authentifizierungsmethoden OpenID Connect und SAML2.

Schließlich können Sie die öffentliche IP-Adresse Ihres Application Gateways über einen DNS-Anbieter mit einem benutzerdefinierten Hostnamen konfigurieren. Erstellen Sie einen A-Eintrag in Ihrer DNS-Verwaltung.

<figure><img src="/files/TlmgwrUtlGmGaDA9TRnw" alt=""><figcaption><p>DNS-Eintrag</p></figcaption></figure>


---

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

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.devolutions.net/powershell-universal/de/config/hosting/azure.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
