PowerShell Remoting Deep Dive: PSSessions, JEA und Constrained Endpoints
WinRM-Authentifizierung, persistente PSSessions, Just Enough Administration, Double-Hop-Problem und Fan-Out auf hunderte Server.
Warum PowerShell Remoting mehr ist als “Enter-PSSession und fertig”
Jeder, der ein paar Jahre Windows-Administration macht, kennt Enter-PSSession -ComputerName server01. Das ist die Einstiegsdroge. Der eigentliche Wert von PowerShell Remoting zeigt sich aber erst, wenn du anfaengst, es strukturiert einzusetzen: persistente Sessions fuer stateful Workflows, JEA fuer delegierte Admin-Rechte ohne vollen Domain-Admin, und Fan-Out-Patterns, die 200 Server in Sekunden statt Stunden abfragen.
In einem Schweizer KMU mit vielleicht 15-80 Servern triffst du frueher als gedacht auf die Grenzen des naiven Ansatzes: RDP auf jeden Server einzeln ist bei einem Patch-Rollout oder einer forensischen Abfrage schlicht nicht skalierbar. Und sobald du Externen (Dienstleister, Auszubildende, 2nd-Level-Support) eingeschraenkten Zugriff geben willst, reicht “ist halt in der Lokale-Admins-Gruppe” als Sicherheitskonzept nicht mehr – dafuer gibt es JEA.
Dieser Artikel geht in die Tiefe: WinRM-Transport und Authentifizierung, der Unterschied zwischen Invoke-Command und persistenten Sessions, JEA-Rollen mit Constrained Endpoints, das notorische Double-Hop-Problem und wie du sauber auf 100+ Server parallelisierst.
WinRM: Der Transport unter der Haube
PowerShell Remoting läuft über WS-Management (WinRM), einen SOAP-basierten Webservice. Wichtig zu verstehen: WinRM ist der Transportmechanismus, PowerShell Remoting ist ein Client darauf. Das bedeutet auch: WinRM-Probleme (Firewall, Zertifikate, Authentifizierung) sind von PowerShell-spezifischen Problemen (Ausführungsrichtlinien, Modul-Pfade) zu trennen.
Ports und Listener
WinRM nutzt standardmässig:
| Protokoll | Port | Verschlüsselung | Einsatz |
|---|---|---|---|
| HTTP | 5985 | WinRM-eigene Verschlüsselung (Kerberos/NTLM-Envelope) | Domain-intern, Standard |
| HTTPS | 5986 | TLS-Zertifikat | Über Domain-Grenzen, Compliance-Vorgaben |
| Alte Ports (2.0) | 80/443 | - | Nur Legacy, nicht mehr Standard seit WinRM 2.0 |
WinRM aktivieren und konfigurieren
Auf dem Zielserver (meistens per GPO im grösseren Umfeld):
# Schnellstart - aktiviert WinRM, erstellt Listener, Firewallregel
Enable-PSRemoting -Force
# Manuell und granularer:
winrm quickconfig -quiet
Set-Item WSMan:\localhost\Service\Auth\Kerberos -Value $true
Set-Item WSMan:\localhost\Service\Auth\Negotiate -Value $true
Set-Item WSMan:\localhost\Service\AllowUnencrypted -Value $false
# Listener-Übersicht prüfen
winrm enumerate winrm/config/listener
Für den produktiven Einsatz in einer Domäne ist GPO-basierte Aktivierung der richtige Weg – “Allow remote server management through WinRM” unter Computer Configuration > Administrative Templates > Windows Components > Windows Remote Management (WinRM) > WinRM Service.
# TrustedHosts nur nötig für Workgroup/Nicht-Domain-Szenarien (NTLM-Fallback)
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "192.168.10.50,server-standalone" -Force
Authentifizierung: Kerberos, NTLM, CredSSP, Basic, Certificate
WinRM unterstützt mehrere Auth-Mechanismen, die du über WSMan:\localhost\Client\Auth\* respektive ...\Service\Auth\* steuerst:
| Mechanismus | Delegation möglich? | Einsatzzweck | Sicherheitsrisiko |
|---|---|---|---|
| Kerberos | Nein (Standard), Ja mit Constrained/Resource-Based Delegation | Domain-Standard, mutual auth | Niedrig, SPN-basiert |
| Negotiate (Kerberos/NTLM-Fallback) | Wie Kerberos, sonst nein | Default bei Domain-Join | Niedrig bis mittel |
| CredSSP | Ja, voll (unbeschränkt) | Double-Hop-Workaround | Hoch – Klartext-Credentials landen im Speicher des Zielservers |
| Basic | Nein | Nur mit HTTPS, Legacy/Non-Domain | Hoch ohne TLS |
| Certificate | Nein (zertifikatbasiert) | Automatisierung ohne Passwort | Niedrig, aber PKI-Aufwand |
Kerberos ist der Standardfall in jeder AD-Umgebung und sollte es auch bleiben. Das Problem: Kerberos delegiert standardmässig keine Credentials an eine dritte Station weiter (Stichwort Double-Hop, siehe unten). CredSSP löst das, aber um den Preis, dass dein Passwort (bzw. der TGT) im Klartext-äquivalenten Zustand auf dem Zwischenserver liegt – ein kompromittierter Zwischenserver kann damit deine Domain-Identität kapern.
# CredSSP aktivieren (Client-Seite)
Enable-WSManCredSSP -Role Client -DelegateComputer "*.contoso.local"
# CredSSP aktivieren (Server-Seite, auf dem Zwischenserver)
Enable-WSManCredSSP -Role Server
# Nutzung
Invoke-Command -ComputerName fileserver01 -Authentication Credssp -Credential (Get-Credential) -ScriptBlock {
Get-ChildItem \\dc01\netlogon
}
Persistente PSSessions vs. Invoke-Command
Das ist die Kernentscheidung, die viele Admins nie bewusst treffen: Willst du zustandslos (jeder Aufruf startet frisch) oder zustandsbehaftet (Variablen, importierte Module, offene Verbindungen bleiben über mehrere Befehle erhalten) arbeiten?
Invoke-Command ohne Session: zustandslos, einfach, teuer bei Wiederholung
# Jeder Aufruf baut Verbindung auf, führt aus, baut ab
Invoke-Command -ComputerName srv-app01 -ScriptBlock { Get-Service -Name Spooler }
Invoke-Command -ComputerName srv-app01 -ScriptBlock { Restart-Service -Name Spooler }
Jeder Befehl hier eröffnet einen komplett neuen WinRM-Kanal, authentifiziert neu und baut danach wieder ab. Bei einem einzelnen Befehl gegen einen Server ist das kein Problem. Bei 20 aufeinanderfolgenden Befehlen gegen denselben Server oder wenn du zwischen den Aufrufen Zustand (z. B. eine importierte Modul-Session, eine offene Datenbankverbindung, eine $variable) brauchst, ist das ineffizient und funktioniert schlicht nicht.
PSSession: persistent, stateful, wiederverwendbar
# Session einmal aufbauen
$session = New-PSSession -ComputerName srv-app01 -Credential (Get-Credential)
# Mehrere Befehle über dieselbe Verbindung, Zustand bleibt erhalten
Invoke-Command -Session $session -ScriptBlock { $svc = Get-Service -Name Spooler }
Invoke-Command -Session $session -ScriptBlock { $svc.Status } # Variable existiert noch!
Invoke-Command -Session $session -ScriptBlock { Import-Module ActiveDirectory }
Invoke-Command -Session $session -ScriptBlock { Get-ADUser -Identity jdoe } # Modul bleibt geladen
# Aufräumen nicht vergessen
Remove-PSSession -Session $session
Der grosse Vorteil: Nur ein Verbindungsaufbau, danach läuft alles über den bestehenden Kanal. Das spart bei wiederholten Interaktionen spürbar Zeit und ermöglicht echte interaktive Workflows über Enter-PSSession -Session $session.
PSSessionOption: Timeouts und Verhalten feinjustieren
$opt = New-PSSessionOption -IdleTimeout (60*60*1000) -OpenTimeout 30000 -MaxConnectionRetryCount 3
$session = New-PSSession -ComputerName srv-app01 -SessionOption $opt
Entscheidungshilfe: Wann was?
| Szenario | Empfehlung |
|---|---|
| Einmaliger Befehl gegen 1-N Server | Invoke-Command -ComputerName (ohne Session) |
| Mehrere zusammenhängende Befehle, Modul-Import nötig | Persistente PSSession |
| Interaktive Fehlersuche auf einem Server | Enter-PSSession |
| Lang laufender Job, der Verbindungsabbrüche überleben soll | PSSession + Disconnect-PSSession/Connect-PSSession |
| Wiederkehrende Automatisierung (Scheduled Task, CI/CD) | Invoke-Command mit -ComputerName-Array, keine Session-Verwaltung nötig |
| Delegierter Zugriff für Nicht-Admins | JEA-Endpoint (siehe unten) |
Just Enough Administration (JEA): Delegierte Rechte statt “voller Admin oder nichts”
Das klassische Problem in jedem KMU: Der 2nd-Level-Support-Mitarbeiter oder der externe Dienstleister soll den Spooler-Dienst neu starten oder DNS-Cache leeren können – aber sicher nicht Domain-Admin sein. Ohne JEA landest du meistens bei “ist halt lokaler Admin auf dem Server”, was faktisch uneingeschränkten Zugriff bedeutet.
JEA (Just Enough Administration) löst das, indem es einen PowerShell-Endpoint definiert, der:
- Nur bestimmte Cmdlets/Funktionen/Skripte erlaubt (Whitelisting, nicht Blacklisting)
- Über ein Virtual Account oder ein Group Managed Service Account (gMSA) mit erhöhten Rechten läuft, während der angemeldete Benutzer selbst nur Standardrechte hat
- Jede Aktion protokolliert (Transkription standardmässig aktiv)
Baustein 1: Role Capability File (.psrc)
Definiert, was ein Benutzer in einer bestimmten Rolle darf:
New-PSRoleCapabilityFile -Path .\DnsOperator.psrc
Der generierte Grundriss wird angepasst:
# DnsOperator.psrc (Auszug)
@{
Author = 'IT-Team'
Description = 'Erlaubt DNS-Cache-Operationen ohne volle DNS-Admin-Rechte'
VisibleCmdlets = @(
'Get-DnsServerCache',
'Clear-DnsServerCache',
'Get-DnsServerZone',
@{
Name = 'Restart-Service'
Parameters = @{ Name = 'Name'; ValidateSet = 'DNS' }
}
)
VisibleFunctions = 'Get-DiagnosticReport'
VisibleExternalCommands = 'ipconfig.exe'
ModulesToImport = 'DnsServer'
}
Wichtig: VisibleCmdlets mit Parameter-Constraints (ValidateSet, ValidatePattern) ist der Kern von “Just Enough” – du gibst nicht einfach Restart-Service frei, sondern nur Restart-Service -Name DNS, nichts anderes.
Baustein 2: Session Configuration File
Verbindet Rollen (AD-Gruppen) mit Role Capabilities:
New-PSSessionConfigurationFile -Path .\DnsEndpoint.pssc -SessionType RestrictedRemoteServer -RunAsVirtualAccount
# DnsEndpoint.pssc (Auszug, nach Anpassung)
@{
SchemaVersion = '2.0.0.0'
SessionType = 'RestrictedRemoteServer'
RunAsVirtualAccount = $true
TranscriptDirectory = 'C:\ProgramData\JEA\Transcripts'
RoleDefinitions = @{
'CONTOSO\DNS-Operatoren' = @{ RoleCapabilities = 'DnsOperator' }
'CONTOSO\Helpdesk-Tier1' = @{ RoleCapabilities = 'HelpdeskBasic' }
}
}
Baustein 3: Endpoint registrieren
# Role Capability Files müssen im Modul-Pfad unter RoleCapabilities/ liegen
New-Item -Path "C:\Program Files\WindowsPowerShell\Modules\JeaDns\RoleCapabilities" -ItemType Directory -Force
Copy-Item .\DnsOperator.psrc "C:\Program Files\WindowsPowerShell\Modules\JeaDns\RoleCapabilities\"
Register-PSSessionConfiguration -Path .\DnsEndpoint.pssc -Name "JEA-DnsOps" -Force
# Test
Test-PSSessionConfigurationFile -Path .\DnsEndpoint.pssc
Endpoint nutzen
$dnsSession = New-PSSession -ComputerName dns01.contoso.local -ConfigurationName "JEA-DnsOps"
Invoke-Command -Session $dnsSession -ScriptBlock { Get-Command } # zeigt NUR erlaubte Befehle
Der Helpdesk-Mitarbeiter, der Mitglied von CONTOSO\DNS-Operatoren ist, kann sich mit seinem eigenen (unprivilegierten) AD-Konto verbinden – die eigentliche Ausführung läuft dank RunAsVirtualAccount mit einem temporären, automatisch verwalteten Konto, das lokale Admin-Rechte nur für die Dauer der Session hat und danach spurlos verschwindet.
Transkripte und Audit
JEA schreibt standardmässig ein vollständiges Transkript jeder Session (jeder Ein- und Ausgabe) nach TranscriptDirectory. Für Schweizer KMU mit Compliance-Anforderungen (revisionssicheres Nachvollziehen, wer wann was auf Produktivsystemen gemacht hat) ist das oft der eigentliche Business-Case für JEA – nicht nur die Rechtebeschränkung, sondern die lückenlose Nachvollziehbarkeit.
# Transkript-Beispielinhalt prüfen
Get-ChildItem C:\ProgramData\JEA\Transcripts | Sort-Object LastWriteTime -Descending | Select-Object -First 1 | Get-Content
Constrained Endpoints jenseits von JEA
JEA ist der “volle” Ansatz mit Rollen und Virtual Accounts. Für einfachere Fälle reicht manchmal ein simpler Constrained Endpoint ohne die volle JEA-Maschinerie – z. B. wenn du nur ein einzelnes Skript remote ausführbar machen willst, unabhängig davon, wer sich verbindet:
# Minimaler eingeschränkter Endpoint: nur ein bestimmtes Skript ausführbar
$sessionConfig = @{
SessionType = 'RestrictedRemoteServer'
LanguageMode = 'NoLanguage'
VisibleCmdlets = 'Invoke-BackupJob'
}
New-PSSessionConfigurationFile -Path .\BackupOnly.pssc @sessionConfig
Register-PSSessionConfiguration -Name "BackupTrigger" -Path .\BackupOnly.pssc
LanguageMode 'NoLanguage' unterbindet jegliche PowerShell-Sprachkonstrukte (keine Variablen-Zuweisung, keine Schleifen, keine Skriptblöcke im eigentlichen Sinn) – nur direkte Cmdlet-Aufrufe sind möglich. Das ist restriktiver als JEAs RestrictedRemoteServer mit NoLanguage als Standard, aber ohne Rollenverwaltung und Virtual Accounts eben auch einfacher aufzusetzen für Ein-Zweck-Endpoints.
Das Double-Hop-Problem lösen
Das Szenario, das garantiert jedem irgendwann passiert: Du verbindest dich per PSSession auf Server A, willst von dort auf eine Freigabe von Server B zugreifen (oder eine AD-Abfrage machen, die einen Domain Controller kontaktiert) – und bekommst “Access Denied”, obwohl dein Konto überall Rechte hätte.
Warum das passiert
Kerberos delegiert deine Anmeldeinformationen standardmässig nicht über einen zweiten “Hop” hinweg. Wenn du dich bei Server A anmeldest, bekommt Server A ein Kerberos-Ticket, das ihm erlaubt, deine Identität dir gegenüber zu bestätigen – aber es enthält nicht dein TGT (Ticket Granting Ticket), mit dem Server A sich seinerseits als du gegenüber Server B ausweisen könnte. Server A kann also nicht “in deinem Namen” bei Server B anklopfen.
Client (du) --Kerberos--> Server A --???--> Server B
(kein TGT-Weiterreichen möglich)
Lösung 1: CredSSP (schnell, aber mit Sicherheits-Trade-off)
# Auf Client und Server A aktivieren (siehe oben)
Enable-WSManCredSSP -Role Client -DelegateComputer "servera.contoso.local"
# auf Server A:
Enable-WSManCredSSP -Role Server
Invoke-Command -ComputerName servera -Authentication Credssp -Credential $cred -ScriptBlock {
Get-ChildItem \\serverb\freigabe
}
CredSSP reicht dein volles Credential an Server A weiter, der es dann für den zweiten Hop nutzen kann. Nachteil: Falls Server A kompromittiert ist, kann ein Angreifer dein Credential im Klartext-äquivalenten Zustand abgreifen.
Lösung 2: Kerberos Constrained Delegation (KCD) / Resource-Based KCD (empfohlen)
Sicherer, weil kein Credential übertragen wird – stattdessen erlaubst du auf AD-Ebene explizit, dass Server A sich gegenüber Server B als der jeweilige Benutzer ausgeben darf (nur für definierte Dienste, nicht generell):
# Resource-Based Constrained Delegation (ab Windows Server 2012):
# Konfiguriert auf dem Zielobjekt (Server B), nicht auf Server A
$serverA = Get-ADComputer -Identity "ServerA"
Set-ADComputer -Identity "ServerB" -PrincipalsAllowedToDelegateToAccount $serverA
Damit erlaubt Server B explizit, dass Server A stellvertretend für authentifizierte Benutzer Dienste auf Server B in Anspruch nehmen darf – die Konfiguration liegt auf der Ressourcen-Seite (Server B), nicht global in der Domäne, und braucht dafür keine Domain-Admin-Rechte auf Domänenebene, nur Schreibrechte auf das Zielobjekt.
Lösung 3: JEA mit CIM-Sessions statt direktem Double-Hop
Wenn der zweite Hop nur Datenabfragen sind (kein Dateizugriff), kannst du oft CimSession statt PSSession für den zweiten Hop nutzen – CIM/WMI über WinRM braucht keine Delegation, weil es anders authentifiziert:
Invoke-Command -ComputerName servera -ScriptBlock {
$cim = New-CimSession -ComputerName serverb
Get-CimInstance -CimSession $cim -ClassName Win32_LogicalDisk
}
Entscheidungsbaum Double-Hop
Brauchst du den zweiten Hop wirklich, oder reicht eine direkte
Verbindung Client -> Server B?
├─ Direkte Verbindung möglich -> mach das, kein Double-Hop-Problem
└─ Zweiter Hop zwingend nötig
├─ Dateifreigabe/AD-Schreibzugriff nötig
│ ├─ Hohe Sicherheitsanforderung -> Resource-Based Kerberos
│ │ Constrained Delegation
│ └─ Schneller Fix, akzeptables Risiko, isoliertes Netz
│ -> CredSSP (zeitlich befristet aktivieren!)
└─ Nur Lesezugriff auf CIM/WMI-Daten -> CimSession (kein
Delegation-Problem)
Fan-Out: Parallelisierung auf 100+ Server
Sobald du regelmässig gegen eine grössere Serverflotte arbeitest (Patch-Compliance-Check, Zertifikats-Ablaufdaten sammeln, Dienst-Status prüfen), wird sequentielle Abfrage zum Flaschenhals.
Invoke-Command: eingebautes Fan-Out mit ThrottleLimit
Invoke-Command gegen ein Array von Computernamen ist von Haus aus parallel, begrenzt durch -ThrottleLimit (Standard: 32 gleichzeitige Verbindungen):
$server = Get-Content .\alle-server.txt # 150 Servernamen, eine Zeile pro Server
$ergebnisse = Invoke-Command -ComputerName $server -ThrottleLimit 64 -ScriptBlock {
[PSCustomObject]@{
Server = $env:COMPUTERNAME
SpoolerStatus = (Get-Service -Name Spooler -ErrorAction SilentlyContinue).Status
FreierSpeicher = (Get-Volume -DriveLetter C).SizeRemaining / 1GB
}
} -ErrorAction SilentlyContinue -ErrorVariable fehler
$ergebnisse | Format-Table Server, SpoolerStatus, FreierSpeicher -AutoSize
# Nicht erreichbare Server separat auswerten - NICHT verschlucken!
$fehler | ForEach-Object { "$($_.TargetObject): $($_.Exception.Message)" }
ThrottleLimit richtig dimensionieren
Der Standardwert 32 ist ein Kompromiss. Für sehr grosse Flotten (200+) lohnt es sich, in Batches zu arbeiten statt den Wert nur hochzudrehen – zu hohe Parallelität überlastet oft nicht die Zielserver, sondern deine eigene Managementstation (Netzwerkkarte, offene Handles, RAM für Rückgabe-Objekte):
$batches = $server | ForEach-Object -Begin { $i = 0 } -Process {
[PSCustomObject]@{ Batch = [math]::Floor($i / 50); Server = $_ }
$i++
} | Group-Object Batch
foreach ($batch in $batches) {
Invoke-Command -ComputerName $batch.Group.Server -ThrottleLimit 50 -ScriptBlock {
Get-HotFix | Where-Object { $_.InstalledOn -gt (Get-Date).AddDays(-30) }
}
Start-Sleep -Seconds 2 # kurze Pause zwischen Batches
}
PSSession-Array für wiederholte Abfragen gegen dieselbe Flotte
Wenn du mehrfach hintereinander gegen dieselben 100 Server arbeitest (z. B. Health-Check-Skript, das alle 15 Minuten läuft, aber innerhalb eines Laufs mehrere Datenpunkte sammelt), lohnt sich ein persistentes Session-Array:
$sessions = New-PSSession -ComputerName $server -ThrottleLimit 64
# Mehrere Abfragen über dieselben offenen Verbindungen
$cpu = Invoke-Command -Session $sessions -ScriptBlock { Get-CimInstance Win32_Processor | Measure-Object -Property LoadPercentage -Average }
$disk = Invoke-Command -Session $sessions -ScriptBlock { Get-Volume -DriveLetter C }
Remove-PSSession -Session $sessions
Alternative: ForEach-Object -Parallel für clientseitige Parallelität
Ab PowerShell 7 gibt es ForEach-Object -Parallel, das lokal Runspaces parallelisiert. Das ist konzeptionell anders als Invoke-Command-Fan-Out (dort läuft die Parallelität serverseitig über WinRM-Verbindungen) – nützlich, wenn du z. B. pro Server eine eigene Verbindung mit individuellen Parametern aufbauen willst:
$server | ForEach-Object -Parallel {
$s = $_
Invoke-Command -ComputerName $s -ScriptBlock {
Test-NetConnection -ComputerName "dc01.contoso.local" -Port 389
}
} -ThrottleLimit 20
Vergleichstabelle: Fan-Out-Methoden
| Methode | Parallelität | Wiederverwendbar | Overhead | Ideal für |
|---|---|---|---|---|
Invoke-Command -ComputerName @(...) | Serverseitig, bis -ThrottleLimit | Nein, pro Aufruf neu | Niedrig für einmalige Abfrage | One-Shot-Abfragen, Scheduled Tasks |
New-PSSession Array + Invoke-Command -Session | Serverseitig, offene Kanäle | Ja | Höher initial, danach niedrig | Mehrere Abfragen im selben Lauf |
ForEach-Object -Parallel (PS 7+) | Client-Runspaces | Nein per Design | Mittel | Individuelle Logik pro Ziel |
| JEA-Endpoint + Fan-Out | Wie oben, zusätzlich rechtebeschränkt | Ja | Etwas höher (Rollenauflösung) | Delegierte Massenoperationen |
Praxisfall: Alle drei Konzepte kombiniert
Ein typisches Szenario in einem Schweizer KMU mit ca. 60 Servern: Der externe Backup-Dienstleister soll täglich den Backup-Status von allen Servern abfragen können, aber sonst keinerlei Zugriff haben.
- JEA-Endpoint
JEA-BackupCheckmit Role Capability, die nurGet-WBSummary,Get-Service -Name "Backup*"und ein eigenesGet-BackupHealthReport-Skript erlaubt - RunAsVirtualAccount, damit der externe Dienstleister-Account selbst keine lokalen Adminrechte braucht
- Fan-Out via Invoke-Command mit
-ConfigurationName "JEA-BackupCheck"gegen alle 60 Server gleichzeitig - Transkript-Auswertung wöchentlich, um sicherzustellen, dass der Endpoint nicht für andere Zwecke missbraucht wird
$dienstleisterCred = Get-Credential -Message "Backup-Dienstleister-Konto"
Invoke-Command -ComputerName $alleServer -ConfigurationName "JEA-BackupCheck" `
-Credential $dienstleisterCred -ThrottleLimit 40 -ScriptBlock {
Get-BackupHealthReport
} -ErrorVariable fehler | Export-Csv -Path "C:\Reports\backup-status.csv" -NoTypeInformation
Das ist der Punkt, an dem PowerShell Remoting vom Werkzeug für den eigenen Alltag zur belastbaren Delegations- und Automatisierungs-Infrastruktur wird.
Troubleshooting-Kurzreferenz
| Fehlermeldung/Symptom | Wahrscheinliche Ursache | Erster Check |
|---|---|---|
| ”Access is denied” bei zweitem Hop | Double-Hop, keine Delegation | klist auf Server A prüfen, ob TGT vorhanden |
| ”WinRM cannot process the request” | WinRM-Dienst nicht gestartet/Firewall | Test-WSMan -ComputerName ziel |
| ”The client cannot connect… TrustedHosts” | Kein Domain-Trust, NTLM nötig | WSMan:\localhost\Client\TrustedHosts prüfen |
| JEA-Session zeigt fast keine Cmdlets | Korrekt, wenn RestrictedRemoteServer – kein Fehler | Get-Command in der Session listet erlaubte Befehle |
| CredSSP-Verbindung schlägt fehl trotz Aktivierung | Encryption-Oracle-Patch-Level-Mismatch | Windows-Updates auf beiden Seiten prüfen |
| Fan-Out bricht bei ca. 32 Servern ab | ThrottleLimit-Default erreicht | -ThrottleLimit explizit erhöhen |
Weiterlernen
- Overview of Just Enough Administration (JEA) – Microsoft Learn
- Making the second hop in PowerShell Remoting – Microsoft Learn
- PowerShell Remoting FAQ – Microsoft Learn
- about_Remote – Microsoft Learn
- JEA GitHub-Repository mit Beispielen
- Optimize performance using parallel execution – Microsoft Learn
Videos
Kommentare
Frage, Verbesserungsvorschlag oder eigene Erfahrung zu diesem Artikel? Schreib einen Kommentar. Neue Beiträge erscheinen nach kurzer Moderation.
- Lade Kommentare …