> 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/da/config/hosting/azure.md).

# Azure

Udrul PowerShell Universal til Azure ved hjælp af webapps i containere eller standardwebapps med konfiguration af persistens, SQL-lager og videresendte headere.

PowerShell Universal er et ASP.NET Core-webprogram og kan hostes i Windows Azure Web Apps.

## Webapp i en container

Containerwebapps gør det muligt at bruge Docker-images som webapps i Azure. I Azure-portalen kan De oprette en Docker Container-webapp ved hjælp af guiden App Services \ Create Web App.

Når De har valgt en ressourcegruppe, tildelt et navn og valgt en beregningsplan, kan De oprette webappen.

Dernæst skal De udrulle imaget til Deres web-app. Det gør De ved at vælge Deployment Center og konfigurere det image, der skal hentes. De kan enten hente en version med et fast tag (f.eks. 2.7.3) eller hente den seneste, så Deres web-app holdes automatisk ajour med nye PowerShell Universal-udgivelser. Brug tagget med suffikset `azure`. Det er forudkonfigureret til at køre i Azure.

{% hint style="info" %}
I produktionsmiljøer foreslår vi at angive en tagget version for at undgå utilsigtede opdateringer af Deres container, når den genstartes. Som standard opdaterer Azure automatisk containere, når et tag, f.eks. latest, opdateres. Dette giver Dem mulighed for at styre opdateringer af Deres PowerShell Universal-version.
{% endhint %}

### Lokal persistens

Som standard skriver containeren til mappen `/home`.

De skal sikre, at miljøvariablen `WEBSITES_ENABLE_APP_SERVICE_STORAGE` er angivet til true. Dette konfigurerer objektbeholderen, så mappen `/home` er vedvarende, og det er her, konfigurationsdataene for PowerShell Universal gemmes.

### Git og SQL

Hvis De vælger at bruge git-integration i PowerShell Universal, anbefaler vi at opsætte en SQL-server og en database til lager. Git bruges til at synkronisere konfigurationsfiler, når containeren startes. SQL gemmer git-konfigurationsindstillingerne sammen med ressourcer som job, app-tokens og identiteter.

De skal bruge en Azure SQL-database for at komme i gang. Når De har oprettet ressourcen, skal De kopiere forbindelsesstrengen fra databasen for at angive den til PowerShell Universal.

Sørg for, at De har tilladt Azure-tjenester at få adgang til databasen.

For at aktivere SQL-understøttelse bør De angive plugins i PowerShell Universal til at bruge SQL-pluginnet i programkonfigurationen for Deres webapp.

Opret en `Plugins__0`-indstilling med værdien `SQL`. Angiv derefter værdien af `Data__ConnectionString` til Deres SQL Server-database.

Når De har konfigureret SQL, kan De starte Deres container. Databaseskemaet oprettes, når containeren starter. Dernæst skal De konfigurere git i PowerShell Universal ved at klikke på Source Control > Git > Settings. Angiv Deres fjernlager, gren, brugernavn, adgangskode eller personligt adgangstoken og synkroniseringstilstand. Push-only anbefales ikke i denne konfiguration, fordi containerens tilstand går tabt mellem genstarter. Sørg for, at initialiseringstilstanden er angivet til Clone.

{% hint style="info" %}
Git-indstillinger gemmes i Deres SQL-database og hentes, hver gang containeren startes.
{% endhint %}

### Videresendte headere

Containere er typisk hostet bag en omvendt proxy og kender ikke den faktiske eksterne URL uden yderligere konfiguration. For at sikre, at systemer, der kræver den eksterne URL, f.eks. OpenID Connect, modtager de rette oplysninger, skal De angive miljøvariablen `ASPNETCORE_FORWARDEDHEADERS_ENABLED` til `true`.

Yderligere oplysninger kan De læse i dette blogindlæg fra [Microsoft](https://devblogs.microsoft.com/dotnet/forwarded-headers-middleware-updates-in-net-core-3-0-preview-6/).

### Bicep

De kan bruge følgende Bicep-skabelon til at udrulle en webapp i en container med vedvarende lager.

{% code collapsedlinecount="10" %}

```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|devolutions/powershell-universal:${version}-azure'
    }
  }
}

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

```

{% endcode %}

### Container-sidecars

Webapps i containere understøtter også [sidecar-containere](https://learn.microsoft.com/en-us/azure/app-service/overview-sidecar), så De kan køre yderligere containere ved siden af PowerShell Universal-containeren. Det er nyttigt til understøttende tjenester som proxyer, agenter, indsamlere eller andre ledsagende processer. Når De hoster PowerShell Universal i denne konfiguration, skal De sikre, at webcontaineren eksponerer den korrekte HTTP-port. Som standard lytter PowerShell Universal på port `5000`.

## Standardwebapp

### Manuel oprettelse af en webapp

I Azure Portal skal De oprette en ny Web App-ressource. PowerShell Universal kræver i øjeblikket .NET 10-runtime-stakken. De kan bruge enten Linux eller Windows.

{% hint style="info" %}
Hvis De vælger en Windows-hostingplan frem for en Linux-hostingplan i Azure, når De konfigurerer Deres WebApp, skal De vælge en Basic Plan (B1) eller højere for at kunne bruge 64-bit-apps. De skal også gå til Settings > Configuration > General setting > Platform og vælge 64-bit, før De kører kommandoen `Publish-AzWebApp`, ellers mislykkes installationen.
{% endhint %}

**Startup Command (kun Linux)**

Når De hoster i et Linux-miljø, skal De angive startkommandoen under Settings \ Configuration \ General Settings \ Startup Command til følgende.

{% code collapsedlinecount="10" %}

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

{% endcode %}

I eksemplet nedenfor vil vi bruge Azure PowerShell-modulet til at udrulle Web App manuelt.

De skal først installere Azure PowerShell.

{% code collapsedlinecount="10" %}

```powershell
Install-Module Az
```

{% endcode %}

Når det er installeret, skal De oprette forbindelse til Deres abonnement.

{% code collapsedlinecount="10" %}

```powershell
Connect-AzAccount
```

{% endcode %}

### Udrul Windows-filer

Hvis De bruger Windows, skal De downloade Windows ZIP-filen. Dette eksempel downloader PowerShell Universal 2026.3.0.0.

{% code collapsedlinecount="10" %}

```powershell
$Version = '2026.3.0.0'
Invoke-WebRequest "https://cdn.devolutions.net/download/Devolutions.PowerShellUniversal.win-x64.$Version.zip" -OutFile .\Universal.zip
```

{% endcode %}

### Udrul Linux-filer

Hvis De bruger Linux, skal De downloade Linux-ZIP-filen. Dette eksempel downloader PowerShell Universal 2026.3.0.0.

{% code collapsedlinecount="10" %}

```powershell
$Version = '2026.3.0.0'
Invoke-WebRequest "https://cdn.devolutions.net/download/Devolutions.PowerShellUniversal.linux-x64.$Version.zip" -OutFile .\Universal.zip
```

{% endcode %}

Nu hvor vi har konfigureret Az-modulet og downloadet Universal-ZIP-filen, kan vi udrulle Web App.

{% code collapsedlinecount="10" %}

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

{% endcode %}

{% hint style="info" %}
De kan kontrollere i Azure under Deployment Center > Logs efter Status Success (Active) for at sikre, at filer blev udrullet / installeret korrekt.
{% endhint %}

### Nødvendige justeringer af indstillinger

Disse indstillinger kan angives i fanen Configuration under Application settings.

#### JWT-signeringsnøgle

Standard-JWT-signeringsnøglen er ikke tilstrækkelig lang og skal opdateres. Det kan gøres i `appsettings.json` eller ved hjælp af miljøvariabler.

#### appsettings.json

{% code collapsedlinecount="10" %}

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

{% endcode %}

#### Miljøvariabel

{% code collapsedlinecount="10" %}

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

{% endcode %}

#### API-URL

Azure Web Apps bruger en omvendt proxy, og PowerShell Universal registrerer ikke den eksterne URL hensigtsmæssigt. Når der køres job, bruger Universal Management API til automatisk at slå oplysninger om job, script og tidsplan op. Det betyder, at dette mislykkes, hvis den ikke kan adressere den eksterne API-URL korrekt.

API-URL'en skal være den eksterne HTTP-adresse for Deres Web App. De kan opdatere den i `appsettings.json` eller ved hjælp af en miljøvariabel.

#### appsettings.json

{% code collapsedlinecount="10" %}

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

{% endcode %}

#### Miljøvariabel

{% code collapsedlinecount="10" %}

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

{% endcode %}

#### NodeName

De kan angive navnet på PowerShell Universal-instansen ved at angive NodeName. Det sikrer, at genstarter ikke påvirker PowerShell Universal-databasen. Dette er ikke påkrævet for LiteDB-installationer.

{% code collapsedlinecount="10" %}

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

{% endcode %}

#### PORT og WEBSITES\_PORT (kun Linux)

For at tilsidesætte standardporten i en Linux-webapp skal De angive indstillingen PORT og WEBSITES\_PORT til 5000.

Når De har publiceret Web App, skal De se Deres PowerShell Universal-instans ved at navigere til URL'en for Web App.

#### Vedvarende lager

Standardfilen `appsettings.json` gemmer databasen og konfigurationsfilerne på en ikke-vedvarende placering. De kan tilføje miljøvariabler for at flytte dem til vedvarende lager i Deres webapp.

**Data\_\_RepositoryPath**

Miljøvariablen `Data__RepositoryPath` angiver placeringen af konfigurationsfilerne for Universal. Angiv værdien til følgende.

{% code collapsedlinecount="10" %}

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

{% endcode %}

### Opdatering af Deres Web App

Når en ny version af PowerShell Universal udgives, skal De opdatere programfilerne til Deres Web App. Vi anbefaler at fjerne programkataloget og udrulle filerne igen. Databasen og konfigurationsfilerne gemmes ikke i programkataloget.

De kan slette filerne til Deres Web App ved hjælp af Kudu-kommando-API'en. Deres Kudu-legitimationsoplysninger bruger Basic-godkendelse og er de samme som Deres [udrulningslegitimationsoplysninger](https://github.com/projectkudu/kudu/wiki/Deployment-credentials).

For at slette alle filerne i Deres Web App skal De køre følgende kommando.

{% code collapsedlinecount="10" %}

```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
```

{% endcode %}

Når De har slettet programfilerne, kan De udrulle dem igen ved at køre de manuelle oprettelsestrin igen.

## Application Gateway

De kan konfigurere PowerShell Universal til at køre bag en Application Gateway i Azure. Det er nyttigt til at levere belastningsfordeling og høj tilgængelighed til flere PowerShell Universal-instanser.

Konfigurer først en backendpulje, der er rettet mod en eller flere Azure Web Apps, som kører PowerShell Universal.

For backendindstillingerne bør De sikre, at De bruger HTTPS med et velkendt CA-certifikat. Cookiebaseret affinitet er påkrævet for at sikre, at sessioner er bundet til en individuel node.

For at Azure kan levere den rigtige webapp, skal De sikre, at indstillingen Override with new host name er konfigureret. Brug værtsnavnet til backendmålet.

Sørg for, at backendpuljereglen er konfigureret som målet og ikke som omdirigering.

Konfigurer en omskrivningsregel for headeren, så det offentlige værtsnavn videregives som headeren `X-Forwarded-Host`. PowerShell Universal bruger denne til internt at opbygge URL'er.

Ovenstående omskrivningsregel er et krav for godkendelsesmetoderne OpenID Connect og SAML2.

Til sidst kan De konfigurere den offentlige IP-adresse for Deres Application Gateway ved hjælp af en DNS-udbyder til et brugerdefineret værtsnavn. Opret en A-post i Deres DNS-administration.


---

# 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.devolutions.net/powershell-universal/da/config/hosting/azure.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.
