mexx
Goto Top

Windows Server remote per Powershell verwalten und Scripts ausführen

Hallo Powershell Freunde,

im Folgenden möchte ich euch zeigen, wie Ihr eure Windows Server Landschaft mit Hilfe von Powershell Scripten und Befehlen remote verwalten könnt. Am Ende dieser Anleitung seid Ihr in der Lage, Befehle und komplexe Powershell Scripte auf den Servern ausführen zu lassen, als würden Sie lokal laufen. Ein Server, der zentral alle Powershell Scripte auf allen anderen Servern ausführt, ermöglicht Monitoring inkl. Reaktion, geplannte Tasks zentral laufen zu lassen und regelmäßige Administrationsaufgaben von einer Quelle aus auf allen Servern durchzuführen.

Schritt 1: Ausgangsbasis schaffen
Um eure Systeme in die technische Lage einer Remoteverwaltung per Powershell zu versetzten, bietet Microsoft ein Installationspaket, welches das Windows Remote Management (WinRM) 2.0, Windows PowerShell 2.0 und den Background Intelligent Transfer Service (BITS) 4.0 beinhaltet, an. WinRM 2.0 ist die Basis für eine Remoteverwaltung aktueller Microsoft Server-Betriebssysteme. WinRM muss sowohl auf dem Client, als auch auf dem Server gestartet, aktiviert und in der Firewall freigeschaltet sein. Bei PowerShell handelt es sich um die aktuelle Befehlszeilenshell von Microsoft ähnlich der bekannten CMD.

Der Download und eine Erklärung zu dem Paket findet Ihr hier: http://support.microsoft.com/kb/968929/de


Schritt 2: Konfiguration
Nach dem Download und der Installation sind ein paar wenige Konfigurationen notwendig, die den Verbindungsaufbau zu den zu steuernden Server erlauben. Öffnet dafür die Powershell in dem Ihr unter Start -> Ausführen "Powershell" eintragt und mit "OK" bestätigt. In der sich öffnenden Powershell führt Ihr zunächst den Befehl...
Enable-PSRemoting -force 
...aus.

Das Cmdlet "Enable-PSRemoting" konfiguriert den Computer so, dass er Windows PowerShell Remotebefehle empfangen kann, die mit Hilfe der Technologie der WS-Verwaltung gesendet werden. Dieser Befehl muss nur einmal auf jedem Computer ausgeführt werden, der Befehle empfängt. Er muss nicht auf Computern ausgeführt werden, von denen Befehle nur gesendet werden.

Wenn der Befehl erfolgreich durch geführt wurde, solltet Ihr eines der beiden dargstellten Meldungen sehen.
7ef1b1b1fcc76dcf9647be7931c22913

Um den Server das Ausführen von Powershell Scripten zu gestatten, ist der Befehl...
Set-ExecutionPolicy remotesigned 
...notwendig.

Wenn der Befehl erfolgreich ausgeführt wurde, solltet Ihr folgendes Bild sehen.
ed6a095749ec5b1621dd9ced0884892e

Bestätigt die Erlaubnis des Script Ausführens mit "J".


Schritt 3: der erste Verbindungsaufbau

Um den Erfolg der im Schritt 1 und Schritt 2 aufgeführten Schritte sicher zu stellen, startet bitte eine Powershell auf euren lokalen PC und führt folgenden Befehl aus.
$SESSION = New-PSsession -ComputerName SERVERNAME -credential DOMAIN/USERNAME
Mit dem Befehl "New-PSSession" wird eine Windows PowerShell-Sitzung, oder auch PSSession, auf einem lokalen Computer oder einem Remotecomputer erstellt. Wenn Ihr eine PSSession erstellt, wird von Windows PowerShell eine dauerhafte Verbindung mit dem Remotecomputer hergestellt. Mit den Befehl "Get-PSSession" erhaltet Ihr eine Liste aller erstellten Powershell Remote Sitzungen. Eine PSSession erhält neben den Namen eine ID, welche man beim Verweden der Session benötigt. In meinen Beispiel weiße ich der Variable $SESSION gleich die PSSession zu, um die Instanz anzusprechen. Um die PSSession zu nutzen, ist folgender Befehl notwendig.
Enter-PSSession $SESSION
Wenn der Befehl erfolgreich ausgeführt wurde, trägt eure Powershellconsole den Namen das verbundenen Servers in der Eingabezeile. Achtet zukünftig immer darauf, in welcher Session Ihr euch befindet! In dieser Sitzung sind nun alle Befehle möglich, die euch die Powershell bietet. Ein einfacher Test wäre folgender Befehl zum Auslesen der Systemvariable %COMPUTERNAME%
(Get-ChildItem env:Computername).Value
Wenn der Befehl erfolgreich ausgeführt wurde, sollte als Ergebnismenge der Name des Servers erscheinen.
Verlasst nun die PSSession mit den Befehl...
Exit
Um eine PSSession entgültig zu schließen, genügt das beendet des Powershellfensters oder der Befehl...
Remove-PSSession $SESSION

Schritt 4: Der Weg zum Remotescript

Im Schritt 3 habe ich euch erklärt, wie Ihr per Powershell eine Powershell Remote Sitzung (PSSession) auf Server aufbaut und mit einfachen Befehlen füttert. Leider hat diese Methode einen Nachteil. Ergebnismengen durchgeführten Befehle stehen nur in der aktuellen Sitzung zur Verfügung oder anders ausgedrückt, jede PSSession ist für sich allein gestellt.

Ein Beispiel: Ihr öffnet eine PSSession und verbindet euch. In der PSSession führt Ihr den Befehl...
$SERVER_PROCESS_LIST = Get-Process
...aus. Die Variable trägt nun die Datenmenge aus der Funktion Get-Process, welche Ihr mit...
$SERVER_PROCESS_LIST
einsehen könnt. Wenn der Befehl erfolgreich durchgeführt wurde, seht Ihr eine Liste der aktiven Prozesse des Servers. Verlasst nun die PSSession mit den Befehl...
Exit
Genau hier, stossen wir nun an die Schwachstelle dieser Methode. Die Ergebnissmenge ist nur in der aktiven PSSession vorhanden. Führt Ihr die Ausgabe der Variable $SERVER_PROCESS_LIST erneut aus, seht Ihr kein Ergebnis. Die bis hier hin beschriebene Methode ermöglicht euch Einmalergebnise auszulesen oder Befehle auszuführen, die das Verhalten des Servers beeinflussen. Das allein ist ein schlagkräftiges Verwaltungsinstrument. Wenn Ihr aber, wie in meinen Beispiel die Prozessliste des Server auch in der lokalen Session behalten wollt, benötigt Ihr den Befehl "Invoke-Command". Der Befehl ermöglicht euch das Ausführen eines Befehls in einer Sitzung ohne die Sitzung explizit betreten zu müssen.

Für diesen Vorgang ist dennoch eine verbundene PSSession zum Server notwendig. Führt dazu den aus Schritt 3 bekannten Befehl...
$SESSION = New-PSsession -ComputerName SERVERNAME -credential DOMAIN/USERNAME
...zum Erstellen einer PSSession aus.

Mit folgenden Befehlsbeispiel könnt Ihr die Processliste des Servers in der PSSession ausführen und die Datenmenge der Variable $SERVER_PROCESS_LIST speichern.
$SERVER_PROCESS_LIST = Invoke-Command -session $SESSION -scriptblock {Get-Process}
Der Befehl Invoke-Command verbindet sich im Hintergrund mit der erzeugten PSSession, führt den Befehl aus, weißt die Ergebnismenge der Variable $SERVER_PROCESS_LIST zu und verläßt die PSSession wieder.

Schritt 5: Das erste Remotescript
Einen einzelnen Befehl an einen Server per Powershell Remote zu schicken, der diesen Befehl ausführt, als würde er lokal auf den Server laufen, ist ohne Frage ein sehr mächtiges Instrument, aber die Möglichkeit ein Script mit einer komplexen Abfolge von Befehlen inklusive Reaktion auf die ermittelten Informationen auf einen oder mehreren Servern laufen zu lassen, ist der heilige Gral der Remoteverwaltung.

Ein Einsatzbeispiel:
Auf einen oder mehrere Windows Server läuft ein Lizenzdienst oder ein Process, welcher die unangenehme Eigenschaft besitzt nach einer unbestimmten Zeit einzufrieren und damit wichtige Funktionen der Infrastruktur lahm zu legen. Um das Problem in den Griff zu bekommen, brauchen wir nur zwei Dinge. Ein Script, welches den Dienst überwacht und bei einen Fehlverhalten reagiert und dieses Script soll per PSSession laufen.

In meinen Beispiel verwende ich den Druckerdienst. Den folgenden Code könnten Ihr 1:1 in eine PS1 kopieren.
$Process = Get-Service "Spooler"  
$PROCESS_NAME = $Process.DisplayName
$Servername = (Get-ChildItem env:Computername).Value

$StopFound = "false"  
$StartTime = Get-Date
while (1 -eq 1) 
 {

  if (((Get-Service $PROCESS_NAME).Status) -ne "Running")  
   {  
    Start-Sleep -Seconds 10             
    if ($StopFound -eq "false")  
     {
      $StopFound = "true"  
      $StopTime = Get-Date      
     }
    
        
    $FreezeTime = (New-TimeSpan $StopTime (Get-Date))
    Write-Host -Foreground Red $PROCESS_NAME auf $Servername": no responding for" $FreezeTime.Seconds "secounds"      
    if ($StopFound -eq "true")  
     {     
      if ([int]$FreezeTime.Seconds -ge 3)
       {
        Write-Host -Foreground Red $PROCESS_NAME auf $Servername": killing"  
        $LastStartTime = Get-Date
        Write-Host -Foreground Green $PROCESS_NAME auf $Servername": restarting"  
        $Process.Start()
        $StartTime = Get-Date        
        Start-Sleep -Seconds 20
        $StopFound = "false"  
        $RestartTime = Get-Date -f "dd-MM-yy HH:mm"          
       }
     }
   } else
   {
    Start-Sleep -Seconds 1
    $RunDate = Get-Date
    Write-Host -Foreground Green $PROCESS_NAME auf $Servername": responding since" (New-TimeSpan $StartTime $RunDate).Days "days" (New-TimeSpan $StartTime $RunDate).Hours "hours" (New-TimeSpan $StartTime $RunDate).Minutes "minutes"  
    $StopFound = "false"      
   }
 }

Speichert die Datei als WatchSpooler.ps1 ab. Nun greifen wir auf das Wissen aus den vorhergegangenen Schritten zurück.

Sitzungsaufbau
$SESSION = New-PSsession -ComputerName SERVERNAME -credential DOMAIN/USERNAME
Script ausführen
Invoke-Command -Session $SESSION -Filepath "WatchSpooler.ps1"  
Nun wird jede Sekunde der Status des Druckerdienstes auf den Server beobachtet und im Falle eines Einfrierens beendet und neu gestartet.

Schritt 5: mehrere Server verwalten
Um nun ein Script oder einen Befehl auf mehreren Servern durchführen zu können, benötigen wie eine PSSession pro Server. Der Befehl Invoke-Command, kann mit den Parameter -Session mehrere PSSessions betreuen. Hier ein Beispiel.

Sitzungsaufbau zu zwei Servern

New-PSsession -ComputerName SERVERNAME1 -credential DOMAIN/USERNAME
New-PSsession -ComputerName SERVERNAME2 -credential DOMAIN/USERNAME

Script oder Befehl auf beiden Servern ausführen
Invoke-Command -Session (Get-PSSession) -Filepath "WatchSpooler.ps1"  

Ergebnis:
31397a3108b41e5011b7e8bf9a52f350

Nun seid Ihr in der Lage, jede Form der Abfragen oder Befehlsfolgen von einen Server aus, auf anderen Servern laufen zu lassen. Bei Fragen, Wünschen oder Anregungen, zögert nicht mich zu kontaktieren.

Viel Erfolg!

Content-Key: 175304

Url: https://administrator.de/contentid/175304

Printed on: April 18, 2024 at 13:04 o'clock

Member: colinardo
colinardo Nov 05, 2011 at 14:01:47 (UTC)
Goto Top
Schöner Artikel !

Hinzuzufügen wäre noch folgendes:

Für den Fall das sich die Rechner nicht in einer Domäne befinden, muss auf dem Client der zu verwaltende Server in die "TrustedHosts"-Liste eingetragen werden - ansonsten schlägt die Verbindung zum Server fehl. Dies kann mit folgendem Befehl in der Powershell (in einer normalen Shell dürfen die einfachen Anführungszeichen nicht verwendet werden) erledigt werden:
winrm set winrm/config/client '@{TrustedHosts="SERVERNAME"}'   

Grüße Uwe