> 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/best-practices.md).

# Best Practices

## Allgemein

### Unveränderliche Konfiguration in der Produktion in Erwägung ziehen

PowerShell Universal basiert auf einem skriptbasierten Konfigurationssystem. Dadurch können neue Instanzen von PowerShell Universal ohne Datenbankaufrufe und direkt aus einem Repository von Skripten konfiguriert werden. Das bedeutet, dass es bei der Bereitstellung in der Produktion vorteilhaft ist, ein gut getestetes Artefakt als Grundlage für Ihre PowerShell Universal-Konfiguration zu verwenden.

Sie können Werkzeuge wie Docker Compose verwenden, um PowerShell Universal-Konfigurationsdateien in ein Container-Image zu schichten, ohne ein Produktionssystem manuell aktualisieren zu müssen. PowerShell Universal bietet außerdem eine [Deployment-](/powershell-universal/de/config/deployments.md)Funktion, mit der Konfigurationen direkt auf einer Instanz veröffentlicht werden können. Sie können dann ein System für Continuous Deployment verwenden, um Ihre Produktionsinstanzen als Teil eines automatisierten Workflows zu aktualisieren.

Je nach Ihren Anforderungen, die typischerweise von der Teamgröße und der Nutzung abhängen, ist diese Art der Konfiguration möglicherweise nicht erforderlich.

### Code First Editing deaktivieren, wenn es nicht verwendet wird

Die Funktion Code First Editing erkennt Änderungen im Repository-Verzeichnis mithilfe eines Dateisystem-Watchers. Diese Funktion ist nützlich, wenn eine PowerShell Universal-Konfiguration direkt aus dem Dateisystem mit Werkzeugen wie Visual Studio Code entwickelt wird. Allerdings kann dies unerwartete Nebenwirkungen haben, wenn Sie die Funktion nicht verwenden. Zum Beispiel kann das Schreiben von Dateien in das Repository, etwa von Protokollen, dazu führen, dass das PowerShell Universal-Konfigurationssystem sich unnötig neu lädt.

{% hint style="info" %}
Das Repository-Verzeichnis ist standardmäßig `C:\ProgramData\UniversalAutomation\Repository`
{% endhint %}

Wenn Sie Änderungen über die Admin-Konsole, per Git-Sync oder mithilfe von Deployments vornehmen, sollten Sie das automatische Neuladen deaktivieren. Dies erhöht die Leistung und verringert zugleich das Risiko unerwarteter Änderungen an Ihrer bereitgestellten Konfiguration.

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

### Nicht-integrierte Umgebungen bevorzugen

{% hint style="info" %}
Dies bezieht sich nicht auf den Schalterparameter `-Integrated` der PSU-Cmdlets und gilt nur für Umgebungen.
{% endhint %}

Die integrierte Umgebung ist zwar schnell und einfach zu verwenden, führt jedoch alle Ihre PowerShell-Operationen innerhalb des PowerShell Universal-Dienstes aus. Probleme mit einem einzelnen Skript oder Endpunkt können die Stabilität des Systems beeinträchtigen.

Bei der Verwendung nicht-integrierter Umgebungen wird ein externer PowerShell-Prozess gestartet. Für APIs und Dashboards kann dieser Prozess langlebig sein, kann aber neu gestartet werden, ohne den Rest des Systems zu beeinträchtigen. Bei Jobs und Terminals wird für jede Instanz des Jobs und Terminals ein neuer Prozess gestartet. Wenn Jobs und Terminals beendet werden, wird der Prozess beendet, und alle von diesem Prozess belegten Ressourcen werden vom System zurückgewonnen.

Zusätzlich kann beim Laden von Modulen in die integrierte Umgebung der Prozessraum mit verschiedenen Versionen von gängigen DLLs verunreinigt werden, die PSU möglicherweise selbst verwendet. Dies kann zu Assembly-Bindungsproblemen führen, die dazu führen können, dass die importierten Module nicht wie erwartet funktionieren.

Die Umgebungen PowerShell 7 und Windows PowerShell 5.1 bieten die größte Kompatibilität mit Modulen, da sie die ausführbare Programmdatei `Universal.Agent` nutzen, die das Laden von Assemblys steuern kann – im Gegensatz zu `pwsh.exe` oder `powershell.exe`.

### Problematische Module isolieren

Komplexe PowerShell-Module können Probleme mit PowerShell Universal verursachen. Bestimmte Module sind nicht dafür ausgelegt, in einem langlebigen Prozess wie PowerShell Universal gehostet zu werden. Sie sollten diese Module in vorübergehenden Operationen wie Jobs verwenden.

Zum Beispiel kann dbatools Datenbankverbindungen leaken, wenn es direkt in der integrierten Umgebung von PowerShell Universal verwendet wird. Um dies zu vermeiden, können Sie einen externen Prozess starten, indem Sie einen PowerShell Universal-Job in einer nicht-integrierten Umgebung ausführen. Das Skript wird ausgeführt, der Prozess wird beendet, und die Datenbankverbindung wird automatisch zurückgewonnen.

Nachfolgend finden Sie eine Liste einiger Module, mit denen wir Probleme festgestellt haben.

* VMware PowerCLI – Das Verbindungsmanagement ist auf den Prozess begrenzt
* Az – Das Verbindungsmanagement ist auf den Prozess begrenzt

### Benutzerdefinierte Module nutzen

Das Erstellen benutzerdefinierter Module stellt sicher, dass Sie dieselbe Funktionalität in der gesamten PowerShell Universal-Plattform verwenden können, ohne Code zu duplizieren. Sie können dieselben Funktionen in APIs, Skripten und Dashboards verwenden, ohne die Logik duplizieren zu müssen.

Die Reduzierung der Skriptmenge an all diesen Stellen kann Ihnen helfen, Probleme besser zu testen und zu isolieren, die durch die Integration mit der Plattform oder durch das Modul selbst verursacht werden.

Erwägen Sie außerdem, Funktionen zu erstellen, die komplexe Dashboard-Komponenten umschließen. Dies reduziert die Gesamtkomplexität des Dashboard-Skripts und macht es leicht zu debuggen und zu lesen.

### Eine Cache-Lebensdauer festlegen

Wenn Sie `Set-PSUCache` verwenden, stellen Sie sicher, dass Sie eine Art Lebensdauer für den Cache festlegen. Dies ist besonders wichtig, wenn Sie Daten haben, die nicht ständig verwendet werden und groß sind. Daten, die ohne Lebensdauer in den Cache gelegt werden, werden nie an das System zurückgegeben.

Sie können zum Beispiel die gleitende Ablauffrist verwenden, um Cache-Daten nach einer Stunde ablaufen zu lassen, wenn sie eine Zeit lang nicht verwendet werden.

```powershell
Set-PSUCache -Key 'Data' -Value (Get-Date) -SlidingExpiration (New-Timespan -Hours 1)
```

### Größe des persistenten Caches begrenzen oder partitionieren

Der persistente Cache speichert Daten in der PSU-Datenbank. Die Daten werden mit der [PSSerializer-Klasse](https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.psserializer?view=powershellsdk-7.4.0) serialisiert, die Teil des PowerShell SDK ist. Dieses Datenformat ist dasselbe, das von PowerShell Remoting verwendet wird. Da es ein XML-Format ist, sind diese Daten deutlich größer als eine binäre Speicherung. Das Speichern vieler Objekte in einem einzelnen zwischengespeicherten Element führt zu schlechter Deserialisierungsleistung, sobald die Daten bestimmte Grenzen erreichen.

Dies kann den PowerShell Universal-Server negativ beeinflussen, da er jedes Mal, wenn die Daten aus dem Cache gelesen werden, eine große Zeichenkette abrufen und dann deserialisieren muss.

Erwägen Sie, kleinere Teilmengen der Objekte auszuwählen, die Sie speichern möchten. Wählen Sie zum Beispiel nur die Eigenschaften aus, die Sie benötigen, anstatt des gesamten Objekts.

```powershell
$Data = Get-ADUser -Properties CN,Enabled 
Set-PSUCache -Key Users -Value $Data
```

Erwägen Sie, Daten in kleineren Partitionen zu speichern. Wenn möglich, segmentieren Sie die Daten in kleinere Blöcke, um das Abrufen eines großen Wertes aus der Datenbank zu vermeiden.

```powershell
$OU1 = Get-ADUser -SearchBase "OU=OU1,DC=PSU" -Properties CN,Enabled 
Set-PSUCache -Key Users_OU1 -Value $OU1
$OU2 = Get-ADUser -SearchBase "OU=OU2,DC=PSU" -Properties CN,Enabled 
Set-PSUCache -Key Users_OU2 -Value $OU2
```

### Protokollebene in der Produktion reduzieren

Die Standard-Protokollebenen für PowerShell Universal sind ausführlich. Um die Leistung des Systems zu verbessern, können Sie die Protokollebenen reduzieren. Dies muss an zwei Stellen erfolgen.

Zunächst sollten Sie die Einstellung für die System-Protokollebene reduzieren. Diese finden Sie in `appsettings.json`. Erwägen Sie, die Ebene von Verbose auf Warning oder Error zu ändern.

```json
{
    "SystemLogLevel": "Error"
}
```

Zweitens können Sie die Protokollierungsziele anpassen, um Ebenen zu ändern oder die protokollierten Funktionen zu reduzieren.

```powershell
New-PSULoggingTarget -Type "File" -Properties @{
    path = "C:\ProgramData\PowerShellUniversal\log.txt"
} -Level 'Error'

New-PSULoggingTarget -Type "Database" -Properties @{
} -Level 'Error'
```

## APIs

### Rückgabe hochkomplexer Objekte vermeiden

Standardmäßig serialisieren API-Endpunkte zurückgegebene Objekte mit `ConvertTo-Json` zu JSON. Obwohl die Plattform die Tiefe des JSON einschränkt, können hochkomplexe Objekte dazu führen, dass das Cmdlet außer Kontrolle gerät und viel CPU verbraucht. PowerShell Universal versucht, diese Verarbeitung abzubrechen, wenn sie erkannt wird, aber sie verursacht dennoch Probleme mit Ihrer API-Umgebung.

Stellen Sie sicher, dass Sie die Komplexität der Objekte verstehen, die Sie zurückgeben. Wenn Objekte zu komplex sind, erwägen Sie die Verwendung von `Select-Object`, um eine Teilmenge der zurückgegebenen Daten auszuwählen. Sie können `ConvertTo-Json` auch selbst aufrufen, um den Parameter `-Depth` zu steuern.

Ein Beispiel dafür wäre die Rückgabe von Process-Objekten mit `Get-Process`. Aufgrund der Komplexität des Process-Typs verursacht dies Probleme bei der Serialisierung. Wählen Sie stattdessen nur eine Teilmenge der erforderlichen Eigenschaften aus.

```powershell
Get-Process | Select-Object Name,Id
```

### Langlaufende Prozesse in APIs vermeiden

Der HTTP-Thread-Pool ist in seiner Größe begrenzt. Langlaufende Prozesse in APIs können dazu führen, dass der Pool erschöpft wird, was Probleme für den gesamten PowerShell Universal-Server verursachen kann. Wenn Sie planen, eine API zu haben, die mehr als ein paar Sekunden benötigt, erwägen Sie, dass die API einen Job startet. Sie können dann eine zweite API erstellen, um den Status der von der ersten API zurückgegebenen Jobs zu prüfen. So wird sichergestellt, dass die Operation weiterverarbeitet wird, der HTTP-Thread-Pool aber die verfügbare Verbindung zurückgewinnt.

Zum Beispiel könnten Sie die folgenden APIs haben. Der erste Endpunkt startet einen Job und gibt die Job-ID zurück. Der zweite Endpunkt ruft die Pipeline-Ausgabe für den angegebenen Job ab.

```powershell
New-PSUEndpoint -Url '/createReport' -Method POST -Endpoint {
    (Invoke-PSUScript -Name CreateReport.ps1 -Integrated)
}

New-PSUEndpoint -Url '/createReport/:id' -Method GET -Endpoint {
     Get-PSUJob -Id $Id -Integrated | Get-PSUJobPipelineOutput -Integrated
}
```

Um diese Endpunkte aufzurufen, könnten wir Folgendes mit `Invoke-RestMethod` tun.

```powershell
$Id = Invoke-RestMethod http://localhost:5000/createReport -Method POST
Start-Sleep 5
Invoke-RestMethod http://localhost:5000/createReport/$Id -Method GET
```

## Automatisierung

### Unnötige Job-Ausgaben reduzieren

Das Speichern von Job-Ausgaben ist zwar für Auditing-Zwecke nützlich, aber das Speichern aller Job-Ausgaben kann dazu führen, dass Ihr Speicher stark anwächst, was wiederum die Leistung Ihres PowerShell Universal-Systems verlangsamt. Einige Schritte, die Sie unternehmen können, um die Job-Ausgabe im Zaum zu halten, sind folgende.

#### Pipeline-Ausgabe verwerfen

Wenn Sie die Pipeline-Ausgabe nicht verwenden möchten, können Sie PowerShell Universal anweisen, sie zu verwerfen. Dies reduziert die Menge der gespeicherten Daten und erhöht auch die Leistung Ihrer Jobs, da das System nicht alle Ausgaben zur Speicherung serialisieren muss. Ihre Ausgabestreams werden dennoch im Job-Protokoll angezeigt.

#### Streams nutzen

Die Verwendung von Debug-, Warning- und Error-Streams kann helfen, zu reduzieren, was standardmäßig im Job angezeigt wird. Durch das Festlegen der Action Preference pro Stream können Sie bestimmte Streams für den regulären Betrieb deaktivieren, sie aber aktivieren, wenn der Job Probleme aufweist.

Wenn Sie zum Beispiel `Write-Debug` in Ihrem gesamten Skript verwenden, können Sie dies über die Variable `$DebugActionPreference` deaktivieren, indem Sie sie auf `SilentlyContinue` setzen. Sollte der Job Probleme aufweisen, könnten Sie sie auf `Continue` setzen, um die Ausgabe im Protokoll anzuzeigen.

#### Out-Null nutzen

`Out-Null` kann potenzielle Pipeline-Ausgaben erfassen und verwerfen. Wenn Sie nicht alle Pipeline-Ausgaben verwerfen möchten, können Sie einen Teil davon mit `Out-Null` verwerfen. Dies verbessert die Leistung und reduziert die Größe Ihrer Job-Daten.

### Unwichtige Jobs aggressiv aufräumen

Einige Jobs, wie ein Trigger, der für Benachrichtigungen verwendet wird, werden möglicherweise nahezu nie überprüft. Erwägen Sie, den Job-Verlauf in diesem Fall sehr niedrig einzustellen.

## Apps

### Funktionen in Apps verwenden

Beim Erstellen komplexer Abschnitte einer App wird empfohlen, diese in eine Funktion einzuschließen, um diesen komplexen Abschnitt besser zu organisieren und zu isolieren. Stark verschachtelte Dashboards sind schwer zu debuggen und machen es leicht, Syntaxfehler einzuführen, die die gesamte App beeinträchtigen.

Wir empfehlen außerdem, Module zum Speichern Ihrer Funktionen zu verwenden, um die Größe und Komplexität Ihres Kern-App-Skripts weiter zu reduzieren. Zusätzlich können Module dann über Apps hinweg geteilt werden.

Ein Beispiel wäre, die Logik einer Tabelle in eine Funktion einzuschließen und die Funktion dann innerhalb der App zu verwenden.

```powershell
function New-ProcessTable {
    $Data = Get-Process
    $Columns = @( 
        New-UDTableColumn -Title 'Name' -Property 'Name'
        New-UDTableColumn -Title 'Id' -Property 'Id'
    )
    New-UDTable -Data $Data -Columns $Columns -ShowSearch
}

New-UDApp -Content {
    New-ProcessTable
}
```

### Nutzung von Jobs in Erwägung ziehen

Jobs sind nützlich, da sie einen externen Prozess starten und zum Auditieren von Interaktionen mit der App verwendet werden können. Da Apps langlebig sind, können bestimmte Operationen und Module unter Last Speicher- oder andere Ressourcenprobleme verursachen. Das Starten von Jobs stellt sicher, dass die Umgebung nach jeder Ausführung zurückgewonnen wird.

Jobs sind sinnvoll für Operationen, die Änderungen vornehmen (z. B. das Erstellen einer VM oder eines Benutzers), aber ihre Leistungsmerkmale funktionieren nicht für jedes Szenario.

Ein Beispiel wäre der Aufruf eines Jobs aus einem Formular.

```powershell
New-UDForm -Content {
   New-UDTextbox -Id 'UserName' -Label 'UserName'
} -OnSubmit {
   Invoke-PSUScript -Name 'CreateUser.ps1' -UserName $EventData.UserName -Environment PS7 -Integrated -Wait
   Show-UDToast "User $($EventData.UserName) was created!"
}
```

### App-Neustarts planen

Wenn Sie Probleme mit App-Ressourcen haben, können Sie Apps mit einem geplanten Job neu starten, der außerhalb der Geschäftszeiten ausgeführt wird. Sie können die Cmdlets `Get-PSUApp`, `Stop-PSUApp` und `Start-PSUApp` verwenden, um die einzelnen Apps neu zu starten. Diese Technik ist nur gültig, wenn Apps in nicht-integrierten Umgebungen ausgeführt werden.

### Beachten Sie die Leistung von -Render bei New-UDTable

Eine Funktion von `New-UDTable` und `New-UDTableColumn` ist die Möglichkeit, Spalten so zu rendern, dass sie jede Komponente enthalten, die Sie basierend auf der Datenzeile anzeigen möchten, die Sie der Tabelle bereitstellen. Dies ist üblicherweise nützlich, um das Aussehen und Verhalten anzupassen oder Aktionen für die Daten der Zeile bereitzustellen. Rendering kann zu einem Leistungsproblem werden, wenn es falsch verwendet wird. Das gleichzeitige Rendern vieler Zeilen oder die Verwendung des Render-ScriptBlocks zum Ausführen langlaufender Prozesse verursacht Probleme.

#### Zu viele Zeilen rendern

Wenn Sie den Parameter `-Data` von `New-UDTable` verwenden, wird der ScriptBlock `-Render` für jedes Element aufgerufen, das Sie an den Data-Parameter übergeben. Wenn Sie hunderte oder tausende Elemente haben, führt dies zu längeren Seitenladezeiten.

Erwägen Sie die Verwendung von `-LoadData`, um jeweils nur eine Seite von Daten zu laden und anzuzeigen. Dabei wird `-Render` nur für die angezeigten Elemente und nicht für den gesamten Datensatz aufgerufen.

#### Langlaufende Renders

Aufgrund der Implementierungsdetails von `-Render` wird nicht empfohlen, langlaufende Render-Operationen zu verwenden. Wenn Sie erwarten, dass Ihr `-Render` mehr als ein paar Millisekunden benötigt, erwägen Sie die Verwendung von `New-UDDynamic`, um das Rendern zurück auf den Server zu verlagern und ein Lade-Skeleton anzuzeigen. Der Server kann die Render-Operation in diesem Fall effizient über den Runspace-Pool planen.

Ein Beispiel dafür wird unten gezeigt.

```powershell
$Data = @(
    @{Dessert = 'Frozen yoghurt'; Calories = 1; Fat = 6.0; Carbs = 24; Protein = 4.0 }
    @{Dessert = 'Ice cream sandwich'; Calories = 159; Fat = 6.0; Carbs = 24; Protein = 4.0 }
    @{Dessert = 'Eclair'; Calories = 159; Fat = 6.0; Carbs = 24; Protein = 4.0 }
    @{Dessert = 'Cupcake'; Calories = 159; Fat = 6.0; Carbs = 24; Protein = 4.0 }
    @{Dessert = 'Gingerbread'; Calories = 200; Fat = 6.0; Carbs = 24; Protein = 4.0 }
) 

$Columns = @(
    New-UDTableColumn -Property Dessert -Title Dessert -Render { 
        New-UDDynamic -Content {
            Start-Sleep (Get-Random -Min 1 -Max 5)
            New-UDButton -Text "Click for Dessert!" -OnClick { Show-UDToast -Message $EventData.Dessert } -Variant 'text'
        } -LoadingComponent {
            New-UDSkeleton
        }
    }
    New-UDTableColumn -Property Calories -Title Calories 
    New-UDTableColumn -Property Fat -Title Fat 
    New-UDTableColumn -Property Carbs -Title Carbs 
    New-UDTableColumn -Property Protein -Title Protein 
)
```

Das Ergebnis ist eine Tabelle, die sofort geladen wird, aber in den langsam zu rendernden Spalten Lade-Skeletons anzeigt.

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

## Portal

### Aufrufe von Drittanbieter-Cmdlets in Widgets vermeiden

Vermeiden Sie es, wenn möglich, Drittanbieter-Cmdlets direkt in Widgets aufzurufen. Jedes Widget hat seinen eigenen Runspace, aber alle Widgets laufen im Prozess des PowerShell Universal-Servers. Das direkte Aufrufen von Cmdlets in Widgets führt dazu, dass .NET-Assemblys in den Server geladen werden. Dies kann zu Konflikten mit anderen Assembly-Ladevorgängen führen. Außerdem wird Speicher von Befehlen, die im Runspace aufgerufen werden, möglicherweise nicht zurückgewonnen.

Die Verwendung von `Invoke-PSUScript` und das Ausführen eines Skripts in einer externen Umgebung stellt sicher, dass alle Assembly-Ladevorgänge auf einen separaten Prozess beschränkt sind und der gesamte Speicher nach dem Beenden des Prozesses zurückgewonnen wird.

Für eine gute Benutzererfahrung ist es möglicherweise nicht immer sinnvoll, für jede Interaktion auf einer Seite einen Job zu starten. Erwägen Sie die Verwendung der PSUCache-Cmdlets, um Daten im Cache zu setzen und daraus abzurufen, um die Seitenladezeiten zu verbessern.

Nicht alle Module verursachen Probleme, daher ist diese Technik möglicherweise nicht immer erforderlich. Bei Skriptmodulen ist es sehr unwahrscheinlich, dass sie Probleme beim Laden von Assemblys verursachen.

## Infrastruktur und Hosting

### Dedizierter PowerShell Universal-Server

Erwägen Sie einen dedizierten PowerShell Universal-Server für das Hosting der Plattform. Vermeiden Sie die Installation neben anderen Plattformen, die zu Ressourcenkonflikten mit der Anwendung führen können. PowerShell Universal nutzt Standard-PowerShell-Funktionen wie Module, Ausführungsrichtlinien und Remoting-Konfiguration, und andere Plattformen konfigurieren diese Einstellungen möglicherweise so, dass PSU damit nicht gut funktioniert.

### MS SQL oder PostgreSQL für die Produktion verwenden

Vermeiden Sie die Verwendung von SQLite für Produktions-Anwendungsfälle. Es bietet nicht die Möglichkeit zu skalieren, wenn die Arbeitslasten zunehmen. Es verhindert, dass mehrere PSU-Server denselben Datenspeicher verwenden. Es skaliert nicht, wenn Größen von über 2 GB erreicht werden.

Die Migration von einer SQLite-Datenbank zu einer SQL-Datenbank kann fehleranfällig und zeitaufwendig sein. Wenn Sie eine Bereitstellung für den Produktionseinsatz erwägen, empfehlen wir, mit einem zentralisierten SQL-Server zu beginnen.

### Geplante Datenbank-Backups durchführen

Wir empfehlen, die Datenbank in regelmäßigen Abständen zu sichern. Während Konfigurationsdaten hauptsächlich im Repository gespeichert werden, enthält die Datenbank Ressourcen wie App-Tokens, lokale Identitäten, Auftragsverlauf und mehr. Regelmäßige Backups helfen außerdem bei der Wiederherstellung nach fehlgeschlagenen Schema-Upgrades und bieten die Möglichkeit, auf frühere Schema-Versionen zurückzusetzen, ohne ein Schema-Downgrade durchführen zu müssen.

### Datenbank-Cluster für Redundanz

Wir empfehlen, wenn möglich einen Datenbank-Failover-Cluster zu verwenden. Dies ermöglicht eine schnelle Wiederherstellung und begrenzt die Ausfallzeit des PowerShell Universal-Servers, falls einer der SQL-Server offline gehen sollte.

### Lastverteilung

Erwägen Sie den Einsatz eines Load Balancers vor Ihren PowerShell Universal-Instanzen. Benutzer werden an den am wenigsten belasteten Server geleitet oder von Offline-Servern per Failover umgeleitet. Dies bietet außerdem eine bessere Möglichkeit, Upgrades der PowerShell Universal-Anwendung zu staffeln.

PowerShell Universal unterstützt Load Balancer wie F5.

### HTTPS verwenden

[HTTPS ](/powershell-universal/de/config/hosting.md#configuring-https)bietet nicht nur Schutz vor Angreifern, die das Netzwerk abhören, sondern auch eine bessere Leistung bei der Verwendung der PowerShell Universal-Cmdlets. Diese nutzen bei der Kommunikation mit der Plattform Funktionen von HTTPS und greifen auf ältere Kommunikationstechnologien zurück, wenn diese nicht verfügbar sind.

### Log Shipping

Systemprotokolldateien werden in den Ordner `%ProgramData%\PowerShellUniversal\Logs` geschrieben und nach 30 Tagen gelöscht. Standardmäßig wird jeden Tag eine neue Protokolldatei geschrieben. Erwägen Sie, Protokolle aus diesem Verzeichnis an Ihr SIEM zu übertragen, wenn Sie Protokolle länger als 30 Tage aufbewahren möchten.

Sie können auch [Logging-Ziele](/powershell-universal/de/entwicklung/logging.md#targets) konfigurieren, um Protokollmeldungen direkt an ein SIEM zu senden.


---

# 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/best-practices.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.
