Skip to the main content.

ScriptRunner Blog

PowerShell-Remoting zur Fehlerbehebung einsetzen

Inhalt

Post Featured Image

Dieser Artikel wird Sie nicht durch die Einrichtung von PowerShell (PS)-Remoting führen, da dies bereits in einem früheren Beitrag zum Thema „Erste Schritte mit PowerShell-Remoting“ erläutert wurde.

Stattdessen zeige ich Ihnen, wie Sie eine Fehlerbehebung per Fernzugriff durchführen können, z. B. wenn das Problem darin besteht, dass eine GUI-basierte Anmeldung, z. B. über mstsc, oder die physische oder virtuelle Konsole hängen bleibt/langsam läuft.

Stellen Sie sicher, dass Sie PS-Remoting auf den Rechnern eingerichtet haben, die Sie voraussichtlich reparieren müssen, und testen Sie es, bevor die Probleme auftreten, da es dann vielleicht schon zu spät ist.

Self-Remoting PowerShell-Cmdlets

Eine Reihe von Cmdlets akzeptieren das -Computername-Argument und können daher auf einer oder mehreren Remote-Maschinen ausgeführt werden (abhängig davon, ob sie einen String- oder String-Array-Typ für dieses Argument akzeptieren – siehe Screenshot unten).

Anstatt uns mühsam durch Handbücher zu kämpfen, können wir PowerShell verwenden, um abzufragen, welche Cmdlets ein -Computername-Argument akzeptieren:

Get-Command | Where { $_.Parameters -and $_.Parameters.ContainsKey('ComputerName') } | select Name,@{n='Array';e={$_.Parameters['ComputerName'].ParameterType.IsArray}},source

Screenshot: PowerShell-Ausgabe aller Cmdlets, die das Argument -computername akzeptieren.

Liste aller Cmdlets, die ein -computername-Argument akzeptieren

Die oben gezeigten Cmdlets benötigen in der Regel kein PS-Remoting, um zu funktionieren, müssen aber typischerweise über offene Firewall-Ports verfügen (das Deaktivieren der Windows-Firewall auf intern zugänglichen Servern ist nicht zu empfehlen!).

Da, wo ein Array übergeben werden kann, arbeiten einige bis zu einem gewissen Grad parallel, was bedeutet, dass die Ergebnisse schneller zurückkommen können, als wenn jeder Computer separat abgefragt wird. In PowerShell v7.1 verwenden nur 20 Cmdlets den Parameter -Computername, und die meisten davon haben mit Remoting zu tun.

Event Logs

Ein Befehl, der selbst remoted werden kann und den ich häufig verwende, ist Get-WinEvent, da die Hinweise/Antworten auf ein Problem oft in einem Ereignisprotokoll enthalten sind. Im Gegensatz zu früher, als es nur vier Ereignisprotokolle gab, haben wir heute in der Regel mehr als 300, und die manuelle Überprüfung dieser Protokolle ist sowohl mühsam als auch zeitaufwändig.

An dieser Stelle können wir PowerShell verwenden, um die Ereignisprotokolle von einem problematischen Computer abzurufen und sie entweder manuell durchzusehen oder nach bestimmten Begriffen zu suchen.

Hier ist zum Beispiel ein Einzeiler, der alle Ereignisse anzeigt, die innerhalb eines angegebenen Zeitbereichs heute (ergänzen Sie die tt/mm/jjjjj oder mm/tt/jjjjj zu den Zeit-Strings, um an einem anderen Tag zu suchen) auf dem angegebenen Computer „fred“ aufgetreten sind:

Get-WinEvent -ListLog * -ComputerName fred | Where-Object { $_.RecordCount } | ForEach-Object{ Get-WinEvent -ComputerName fred -EA SilentlyContinue -FilterHashtable @{logname=$_.logname;starttime='07:45:15';endtime='07:47:15'}} | Select-Object * -ExcludeProperty ?Id,Version,Qualifiers,Level,Task,OpCode,Keywords,Bookmark,*Ids,Properties | sort TimeCreated

Wenn Sie die Ergebnisse in eine csv-Datei (via Export-CSV, alias epcsv) oder eine Gitteransicht (via Out-Gridview, alias ogv) geben, ist es sehr einfach, anschließend nach bestimmten Suchbegriffen zu suchen/filtern.

Screenshot: Gefilterte Ereignisprotokolle in der Gitteransicht

Ereignisprotokolle in der Gitteransicht

Eine häufiger Fallstrick für das Remoting von Get-WinEvent ist, wenn auf der Remote-Firewall die Regel „Remote Event Log Management“ nicht aktiviert ist oder das zur Abfrage der Ereignisprotokolle verwendete Konto keine ausreichende Berechtigung hat.


Artikel: Ereignisbehandlung mit PowerShell - Teil 1, von Sunny JamwalEreignisbehandlung mit PowerShell

Lesen Sie unsere zweiteilige Blog-Serie, um mehr über die Behandlung und Überwachung von Ereignissen mit PowerShell und .NET oder WMI zu erfahren.

Lesen Sie Teil 1 der Serie >


 

 

Remoting individueller PowerShell-Cmdlets

Wenn ein Cmdlet/eine Funktion nicht über intrinsisches Remoting verfügt, kann es/sie mit PowerShell über das Cmdlet Invoke-Command ferngesteuert werden, vorausgesetzt, PS-Remoting wurde erfolgreich konfiguriert und ein Konto mit ausreichenden Berechtigungen ist verfügbar (standardmäßig können nur Administratoren PS-Remoting verwenden, aber Mitglieder der integrierten lokalen Gruppe „Remote Management Users“ sind ebenfalls zulässig).

Führen Sie Invoke-Command entweder als Anwender mit PS-Remoting-Rechten aus oder übergeben Sie ein Credential-Objekt, (das einfach interaktiv über Get-Credential erstellt werden kann,) über den -credential-Parameter. Eines der grundlegenden Prinzipien von PowerShell besteht darin, Objekte in der Pipeline zu halten, damit sie anschließend von weiteren Cmdlets/Funktionen/Scripten verarbeitet werden können, und Invoke-Command berücksichtigt dies, sodass von Remote-Computern zurückgegebene Objekte auf dem lokalen Computer verarbeitet werden können, auf dem das Script/Cmdlet ausgeführt wird.

Hier ist ein Beispiel, bei dem wir die Prozesse von einem Remote-Computer abrufen und sehen, welche die meiste CPU verbraucht haben, was ein guter Indikator für die Ursache von Leistungsproblemen sein kann – insbesondere, wenn Sie sich bei einem Computer anmelden, bei dem Probleme aufgetreten sind, nur um festzustellen, dass zum Zeitpunkt der Überprüfung der CPU-Verbrauch niedrig ist.

Screenshot: Gefilterte Ereignisprotokolle in der Gitteransicht

Liste der Computer, sortiert nach ihrer CPU-Auslastung

Beachten Sie, dass wir alle Prozesse vom Remote-Computer abgerufen haben, aber die zehn größten Verbraucher auf dem Computer, auf dem wir Invoke-Command ausgeführt haben, sortiert und ausgewählt haben.

Je nach Vorgang kann es am besten sein, am Remote-Ende zu filtern, um die Menge der zu übertragenden und zu verarbeitenden Daten zu reduzieren – eine der goldenen Regeln für die beste PowerShell-Leistung lautet „so weit links wie möglich filtern“.

Beachten Sie auch, dass der Parameter HideComputerName verwendet wurde, um die Ergebnisse zu entrümpeln, obwohl dies im Allgemeinen nicht ratsam ist, wenn Invoke-Command ein Array von Computernamen übergeben wird, damit es auf mehreren Computern gleichzeitig arbeitet, da es sonst schwierig sein kann zu wissen, welches Ergebnis von welchem Computer stammt (falls relevant).

Remote-Sitzungen

Wenn Sie Invoke-Command mit dem -ComputerName-Parameter verwenden, wird für jeden Aufruf eine neue Remote-Sitzung aufgebaut und wieder abgebaut. Wenn Sie also viele Remote-Transaktionen mit denselben Computern durchführen, wird dies ineffizient und benötigt mehr Zeit und Ressourcen, als wenn Sie eine einzelne Sitzung aufbauen, diese für jeden Remote-Befehl verwenden und sie schließlich einmal abbauen, wenn alles abgeschlossen ist.

PowerShell ermöglicht dies in Form von Remote-Sitzungen, die die obige Verwendung, nicht-interaktiv, unterstützen. Sie können aber auch interaktiv verwendet werden, wie in den alten (unsicheren) Tagen von Unix, als Sie mit Telnet auf einen Computer zugreifen konnten, um ihn mit reinen Befehlszeilen- (nicht GUI-) Tools zu konfigurieren, und in jüngerer Zeit (und viel sicherer), um Ähnliches über eine SSH-Verbindung mit Tools wie PuTTY zu tun.

Zur nicht-interaktiven Verwendung stellen wir die Remote-Verbindung einmalig mit New-PSSession her und weisen Sie einer Variablen zu, welche wir wiederum an nachfolgende Invoke-Command-Aufrufe und schließlich an Remove-Session übergeben können, um sie abzubauen.

Screenshot: Nicht-interaktiver Einsatz von PowerShell-Remotesitzungen über New-PSSession

Nicht-interaktives Verwenden von PowerShell-Remotesitzungen über New-PSSession

Um eine Remote-Sitzung interaktiv einzurichten und zu verwenden, verwenden wir Enter-PSSession wie folgt:
Interaktives Verwenden von PowerShell-Remote-Sitzungen über Enter-PSSession

Interaktives Verwenden von PowerShell-Remote-Sitzungen über Enter-PSSession

Beachten Sie, wie sich die Eingabeaufforderung ändert und der Computername in eckigen Klammern gesetzt wird, als Hinweis darauf, dass Sie sich jetzt auf einem anderen Computer befinden, und um zu vermeiden, dass Sie versehentlich etwas Falsches auf dem falschen Computer tun.

Die Commandline-Historie wird auf dem lokalen Rechner gespeichert, sodass selbst dann, wenn der Remote-Rechner kein dauerhaftes Benutzerprofil hat und Sie ihn neu starten, die zuvor verwendeten Befehle verfügbar sind (die Sie ganz nebenbei erwähnt mit Strg r/s durchsuchen können, statt sie mit dem Cursor zu durchlaufen), wenn Sie sich das nächste Mal per Remote-Sitzung darauf zugreifen. Außerdem haben Sie so eine Aufzeichnung dessen, was getan wurde (vorausgesetzt, Sie haben lokal ein dauerhaftes Benutzerprofil).

Wenn Sie einen Befehl ausführen, der eine Benutzeroberfläche hat, wie z. B. Notepad, wird dieser einfach stehen bleiben, ohne ein Fenster anzuzeigen. Wir können aber auch einen remote SysInternals Process Monitor, headless starten, indem wir Start-Process verwenden, um den Prozess effektiv im Hintergrund laufen zu lassen.

Auf diese Weise können wir die Aufzeichnung stoppen, wenn das Ereignis, das wir beheben wollen, z. B. eine langsame Windows 10-Anmeldung, abgeschlossen ist, oder wir können den /runtime-Parameter an procmon übergeben und angeben, wie lange er in Sekunden laufen soll. Eine typische Befehlszeile, um procmon headless in einer bereits aufgebauten Remote-Sitzung auszuführen, lautet:

Start-Process -FilePath c:\temp\Procmon.exe -ArgumentList ‘/accepteula /backingfile c:\temp\logon.pml /nofilter /quiet’

Screenshot: Process monitor usage

Wenn wir erfasst haben, was wir brauchen, rufen wir procmon wieder auf, nur dieses Mal mit dem /terminate-Parameter, um den Trace zu stoppen, und die über das /backingfile-Argument erzeugte(n) .pml-Datei(en) kann/können jetzt untersucht werden, wenn Sie eine GUI-Sitzung haben. Beachten Sie, dass der Zugriff auf Netzwerkfreigaben aus einer Remote-Sitzung heraus standardmäßig nicht funktioniert, obwohl es möglich ist, diese Fähigkeit zu aktivieren.

Fazit

Ich hoffe, Sie haben durch diesen Artikel eine Vorstellung davon bekommen, was mit PowerShell auf Remote-Systemen erreicht werden kann, und einige Szenarien kennengelernt, in denen die Verwendung von PowerShell schneller/einfacher sein kann als die Einrichtung einer vollständigen Remote-Sitzung.

Wenn Sie mehr über die Fehlerbehebung mit PowerShell erfahren möchten, lesen Sie unbedingt meinen anderen Artikel über Meine Top 10 PowerShell-Befehle zur Fehlerbehebung bei Windows-Problemen.

Weiterführende Links

Zusammenhängende Posts

5 min read

Microsoft Exchange mit PowerShell managen

2 min read

VMUG Webcast: VMware Management meistern mit PowerCLI

Über den Autor: