Behandelte Themen unter "Powershell Remote"


     0. Einführung ins Remoting mit dem WS-Management-Protokoll
         Beispiel 1: Anzeige aller konzeptionellen Hilfen über Remoting
         Beispiel 2: Alle cmdlets auflisten, deren Name Session enthalten

  1. Voraussetzungen
    1.1 Lokaler- und RemoteComputer sind nicht in einer Domäne
    1.2 Konfiguration des remoteComputers
         1.2.1 Lokale Konfiguration mit cmdlets
                  Beispiel 1a: Set-WsManQuickConfig
                  Beispiel 1b: Meldung bei fehlendem SSL-Zertifikat
                  Beispiel 2a: Enable-PsRemoting
                  Beispiel 2b: Disable-PsRemoting
                  Beispiel 3: Konfiguration des Listeners für eine bestimmte IP-Adresse
                  Beispiel 4: Abfrage der Listenerkonfiguration aus der Powershell heraus
         1.2.2 Konfiguration über GPO
                  Beispiel 1: Abfrage der Listenerkonfiguration aus der Powershell heraus
  1. RemoteSession ohne SSL
    2.1 new-pssession <Clientname>
          Beispiel 1: Ablauf einer Remotesession
          Beispiel 2: Beenden aller Remotessions zu $computer

     3.  RemoteSession mit SSL-Verschlüsselung
          3.1 Kurzbeschreibung SSL
          3.2 Voraussetzungen für SSL bereitstellen
                3.2.1 Microsoft CA bereitstellen (CA-Server)
                3.2.2 Zertifikatsvorlage kopieren und anpassen (optional) (CA-Server)
                3.2.3 Zertifikat beantragen (RemoteRechner)
                3.2.4 Untersuchen des erstellten Zertifikats
                3.2.5 Listener konfigurieren (RemoteRechner)
                         Beispiel 1: SSL-Listener für alle IPs auf Port 5986 setzen
                         Beispiel 2: SSL-Listener für eine IP auf Port 5986 setzen
                         Beispiel 3: weitere Konfigurationsmöglichkeiten des winrm
                3.2.6 new-pssession <Clientname> -usesslPowershell Remote

     4.  PowershellRemote in allen Variationen
          4.1 Alternative zu WS-MAN/ WinRM
               Beispiel 1: Abrufen aller Processe von einem RemoteComputer
               Beispiel 2: Abrufen aller Processe von einem RemoteComputer mittels WMI
               Beispiel 3: Sicherheitsloch in psexec
          4.2 Sitzungskonfiguration/ Sessionconfiguration
               Beispiel 1: Anzeige der cmdlets zur Verwaltung einer Session Configuration
               Beispiel 2: Abfragen der vorhandenen Sessionkonfigurationen auf dem lokalen Computer
               4.2.1 Erstellen und Verwenden einer neuen Sessionkonfiguration
                       Beispiel 1: Erstellen einer neuen Sessionkonfiguration, die ein Startupskript enthält
               4.2.2 Sitzungskonfigurationen auslesen
                       Beispiel 1: Abfrage der vorhandenen Sessionkonfigurationen auf dem lokalen Computer mit dem WS-Verwaltungsanbieter
                       Beispiel 2: Detaillierte Information einer Sessionconfiguration mit get-pssessionconfiguration abfragen
                       Beispiel 3: Abfrage der vorhandenen Sessionkonfigurationen auf einem RemoteComputer mit dem WS-Verwaltungsanbieter
               4.2.3 Einschränken der verfügbaren cmdlets
                       Beispiel 1: verfügbare cmdlets mittels SessionConfiguration beschränken (AD-Userverwaltung)
               4.2.4 Sicherheitsbeschreibung einer Sitzungskonfiguration
                       4.2.4.1 Security Descriptor Definition Language (SDDL)
                                 Beispiel 1a: Analyse eines SDDL-Strings (Grundstruktur)
                                 Beispiel 1b: Analyse eines SDDL-Strings (ACE)
                                 Beispiel 1c: Anzeige der Berechtigungen mit der GUI
                       4.2.4.2 SessionConfiguration für bestimmte User verfügbar machen
                                  zusammenfassendes Beispiel zur SessionConfiguration
          4.3 Remotesessions mit dem cmdlet "invoke-command"
                4.3.1 Remoting mit temporärer Verbindung
                        Beispiel 1: schneller Überblick über die Laufwerke C und D auf verschiedenen Rechnern mittels Scriptblock
                        Beispiel 2: Überblick über die Laufwerke auf  verschiedenen Rechnern mittels lokalem Skript
               4.3.2 Remoting mit dauerhafter Verbindung
                        Beispiel 1: Abfrage eines Dienstes auf einem Remote Rechner
          4.4 interactive Sessions
               4.4.1 temporäre interaktive Session
                       Beispiel 1: Ablauf einer temporären, interactiven Session
                       Beispiel 2: Beenden einer temporären, interactiven Session
                       Beispiel 3: Das cmdlet "get-history"
               4.4.2 permanente interaktive Session
                       Beispiel 1: Aufbau und Anzeige mehrerer Remotesessions
                       Beispiel 2: Betreten und Verlassen einer Remotesession
                       Beispiel 3: Beenden aller Sessions zu Computer dc1
         4.5 implizite Sessions
              4.5.1 Import-PSSession
                      Beispiel 1: Import der Sharepoint-cmdlets in eine lokale Session
                      Beispiel 2: Import der ActiveDirectory-cmdlets in eine lokale Session
                      Beispiel 3: Import eines Modules aus dem Powershellpack des Windows7 ResourceKits
              4.5.2 Export-PSSession
                      Beispiel 1: Import eines Modules aus dem Powershellpack des Windows7 ResourceKits

     5. Troubleshooting
         5.1 Problem mit dem WinRM-Dienst
               Beispiel 1: Schnelltest am RemoteRechner, ob Remoting enabled ist.
               Beispiel 2: Fehlermeldung am lokalen Rechner, wenn der WinRM-Port nicht offen oder kein passender Listener konfiguriert ist
               Beispiel 3: Anzeige der WinRM-Konfiguration
               Beispiel 4: Abfrage der Listenerkonfiguration
         5.2 Problem mit der Firewall
         5.3 Problem mit dem SSL-Zertifikat
         5.4 Problem mit der Sessionkonfiguration (Zugriff verweigert)
         5.5 Prüfen des WS-Man
               Beispiel 1: cmdlet Test-WsMan
         5.6 Module psdiagnostics
               Beispiel 1: Functionen des Moduls psdiagnostics anzeigen

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

0 Einführung ins Remoting mit dem WS-Management-Protokoll

Dieses Kapitel beschäftigt sich mit dem Powershell-Remoting basierend auf dem herstellerunabhängigen WebServices-Management-Protokoll (WSMan). Microsoft implementiert das WS-Management-Protokoll mit WinRM 2.0 

"WinRM ist die Microsoft-Implementierung von WS-Management-Protokolls eine standardmäßige SOAP (Simple Object Access Protocol)-basierte, firewallfreundlichen-Protokoll, die Hardware und Betriebssystemen verschiedener Hersteller ermöglicht, zusammenzuarbeiten. Die Spezifikation WS-Management-Protokoll bietet ein gängiges Verfahren für Systeme auf Access und Exchange-Verwaltungsinformationen über eine IT-Infrastruktur."
aus:  Microsoft Hilfe und Support: Windows Management-Frameworks

Die Powershell selbst versteht unter "Remote" hauptsächlich das auf WS-Man/ WinRM basierende Remoting, wie man in den konzeptionellen Hilfen erkennen kann. Dennoch gibt es neben WS-Man/ WinRM noch Alternativen wie WMI oder cmdlets mit dem Positionsparameter "computername", Befehle auf Remotemaschinen auszuführen. Auf diese werde ich im Kapitel 4.1 Alternativen zu WS-MAN näher eingehen.

Remoting mittels dem WS-Managementprotokoll bietet Vorteile, an die mit anderen Methoden kaum zu denken ist:
- die Verbindung läuft über einen einzigen Port 5985 oder 5986 (Firewallfreundlich!)
- volle Proxyunterstützung , siehe  Technet: New-WSManSessionOption
- die Verbindung kann zusätzlich mit einem SSL-Zertifikat abgesichert werden
- Befehle können asynchron als Hintergrundaufträge ausgeführt werden (invoke-command ... -asJob)
- mittels Sessionkonfiguration kann bestimmt werden, welche Benutzer eine Remoteverbindung mit dem Computer herstellen können
- mittels Sessionkonfiguration kann bestimmt werden, welche Benutzer welche Befehle ausführen können.
- der WinRM Server und Client können lokal oder zentral über GPOs konfiguriert werden
- mittels "implizit Sessions" können cmdlets eine Remoterechners auf einem lokalen Rechner so genutzt  werden, als ob diese lokal installiert wären


Beispiel 1: Anzeige aller konzeptionellen Hilfen über Remoting

get-help about_remote

#Ausgabe

Name                              Category  Synopsis
----                              --------  --------
about_remote                      HelpFile  Describes how to run remote commands in Windows PowerShell.
about_remote_FAQ                  HelpFile  Contains questions and answers about running remote commands
about_remote_jobs                 HelpFile  Describes how to run background jobs on remote computers.
about_remote_output               HelpFile  Describes how to interpret and format the output of remote commands.
about_remote_requirements         HelpFile  Describes the system requirements and configuration requirements for
about_remote_troubleshooting      HelpFile  Describes how to troubleshoot remote operations in Windows PowerShell.


Beispiel 2: Alle cmdlets auflisten, deren Name Session enthalten

Diese cmdlets sind geeignet, eine WS-Man Remotesession in irgendeiner Form zu erstellen, beenden, abzufragen oder zu konfigurieren 

get-help session

#Ausgabe

Name                              Category  Synopsis
----                              --------  --------
New-WSManSessionOption            Cmdlet    Erstellt eine Hashtabelle für die WS-Verwaltungssitzungsoptio
Register-PSSessionConfiguration   Cmdlet    Erstellt und registriert eine neue Sitzungskonfiguration.
Unregister-PSSessionConfiguration Cmdlet    Löscht eine registrierte Sitzungskonfiguration vom Computer.
Get-PSSessionConfiguration        Cmdlet    Ruft die registrierten Sitzungskonfigurationen auf dem Comput
Set-PSSessionConfiguration        Cmdlet    Ändert die Eigenschaften einer registrierten Sitzungskonfigur
Enable-PSSessionConfiguration     Cmdlet    Aktiviert die Sitzungskonfigurationen auf dem lokalen Compute
Disable-PSSessionConfiguration    Cmdlet    Verweigert den Zugriff auf die Sitzungskonfigurationen auf de
New-PSSession                     Cmdlet    Erstellt eine dauerhafte Verbindung mit einem lokalen Compute
Get-PSSession                     Cmdlet    Ruft die Windows PowerShell-Sitzungen (PSSessions) in der akt
Remove-PSSession                  Cmdlet    Schließt eine oder mehrere Windows PowerShell-Sitzungen (PSSe
Enter-PSSession                   Cmdlet    Startet eine interaktive Sitzung mit einem Remotecomputer.
Exit-PSSession                    Cmdlet    Beendet eine interaktive Sitzung mit einem Remotecomputer.
New-PSSessionOption               Cmdlet    Erstellt ein Objekt, das erweiterte Optionen für eine PSSessi
Export-PSSession                  Cmdlet    Importiert Befehle aus einer anderen Sitzung und speichert si
Import-PSSession                  Cmdlet    Importiert Befehle aus einer anderen Sitzung in die aktuelle
Disconnect-TerminalSession        Cmdlet    PSCX Cmdlet: Disconnects a specific remote desktop session on
Get-TerminalSession               Cmdlet    PSCX Cmdlet: Gets information on terminal services sessions.
Stop-TerminalSession              Cmdlet    PSCX Cmdlet: Logs off a specific remote desktop session on a
about_pssessions                  HelpFile  Beschreibt Windows PowerShell-Sitzungen (PSSessions) und
about_pssession_details           HelpFile  Stellt ausführliche Informationen über Windows PowerShell-
about_Session_Configurations      HelpFile  Beschreibt Sitzungskonfigurationen, die bestimmen, welche

Anmerkung:
Die drei Terminalserver-cmdlets (PSCX-Cmdlet) in dieser Ausgabe stammen aus den  CommunityExtensions. Weitere Terminal-cmdlets gibt es unter  MSDN: Terminal Services PowerShell Module
Mit  QUser.exe lassen sich ganz ohne Zusatzmodule Informationen zur aktuellen TSSession gewinnen. 

1 Voraussetzungen

Setzt man Windows 7 und Windows2008R2 Server ein, so sind installationsseitig alle Voraussetzungen erfüllt, Powershellskripte remote ausführen zu können.

Für Betriebssysteme ab WindowsXP (SP3)  und Windows2003 (SP2) bis einschliesslich WindowsVista und Windows2008Server können die Installationskomponenten kostenlos bei Microsoft im „Windows Management-Framework Core (WinRM 2.0 und Windows PowerShell 2.0) „ unter  Microsoft Hilfe und Support: Windows Management-Frameworks (Windows PowerShell 2.0 WinRM 2.0 und BITS 4.0) heruntergeladen werden.

Zwingende Voraussetzungen für Remoting sind auf dem lokalen und auf dem RemoteComputer:

 - Windows PowerShell 2.0 oder höher
 - The Microsoft .NET Framework 2.0 oder höher
 - Windows Remote Management (WinRM) 2.0
 - Der RemoteComputer muss netztechnisch über die WSMan-Ports 5985 oder 5986 (SSL) erreichbar sein
  -Für eine SSL-Verbindung muss auf dem RemoteComputer ein geeignetes Zertifikat liegen (siehe Kapitel 3)

folgende Punkte erfordern bei Nichterfüllung zusätzliche Schritte:
  - Der ausführende User muss die Rechte eines lokalen Administrators auf der Remotemaschine besitzen, oder er muss Username und Passwort eines solchen Administratoraccounts dem Script mitgeben können
  - Die Verbindung zum Remotesystem erfolgt über den Namen, nicht über die IP-Adresse
  - Lokales und RemoteSystem befinden sich in derselben Domäne

Sind diese Punkte nicht gegeben, findet man entweder in der OnlineHilfe unter

get-help about_Remote_Troubleshooting

oder besser - da aktueller - in der  Technet: about_Remote_Troubleshooting Hinweise, welche Schritte dann unternommen werden müssen.
Im Kapitel 1.1 zeige ich kurz, was zu tun ist, falls Lokaler- und RemoteComputer sich nicht in einer Domäne befinden.

Ansonsten gehe ich den weiter darauf folgenden Kapiteln davon aus, daß diese Punkte nicht gesondert konfiguriert werden müssen.

 

1.1 Lokaler- und RemoteComputer sind nicht in einer Domäne

Befinden sich Lokaler- und RemoteComputer in derselben Domäne, so braucht der lokale Computer keine weiteren Einstellungen. Andernfalls muss der Remotecomputer auf dem lokalen Computer in die Trusted Hosts aufgenommen werden, was mit

cd WsMan:
cd Localhost\Client
Set-Item -Path TrustedHosts -Value "Server1,Server2,Server3" -Force

leicht zu erledigen ist. Kontrollieren lässt sich der Erfolg

WSMan:\localhost\Client> dir

#Ausgabe:
   WSManConfig: Microsoft.WSMan.Management\WSMan::localhost\Client

Name                      Value
----                      -----
NetworkDelayms            5000
URLPrefix                 wsman
AllowUnencrypted          false
Auth
DefaultPorts
TrustedHosts              Server1,Server2,Server3

Die Trustedhosts können natürlich auch per GPO gesetzt werden.

"Computerkonfiguration -> Richtlinien -> Administrative Vorlagen: vom lokalen Computer abgerufene Richtliniendefinitionen -> Windows Komponenten -> Windows-Remoteverwaltung (WinRM) -> WinRMClient -> Vertrauenswürdige Hosts"



1.2 Konfiguration des remoteComputers

Auf dem Remotecomputer, das ist derjenige der die Remotebefehle empfängt, muss das Remoting aktiviert werden. Dies kann durch das lokale Ausführen bestimmter cmdlets siehe  "1.2.1 Lokale Konfiguration mit cmdlets" oder zentral durch Group Policies "1.2.2 Konfiguration über GPOs" geschehen.

 

1.2.1 Lokale Konfiguration mit cmdlets

Die Möglichkeiten den WinRM-Dienst zu konfigurieren sind ausgesprochen umfangreich. Ich beschränke mich hier auf die Konfiguration der Listener und der Sessionconfiguration und belasse den Rest auf Default.
Mehr Informationen findet ihr unter:

 Technet: about_Remote_Requirements

 Technet: New-WSManSessionOption (unbedingt zumindest überfliegen, um die möglichen Optionen zu kennen!) 


Beispiel 1a: Set-WsManQuickConfig

Hier benutze ich das cmdlet Set-WsManQuickConifg einmal ohne und einmal mit dem Parameter -usessl, was einige weitere Voraussetzungen erforderlich macht. (siehe "Kapitel 3 RemoteSession mit SSL-Verschlüsselung" ). Sind diese zusätzlichen Voraussetzungen nicht gegeben oder nicht erforderlich, dann lasst -usessl einfach erstmal weg.

Set-WsManQuickConfig
Set-WsManQuickConfig -usessl

#Ausgabe beide Befehle quasi identisch

WinRM-Schnellkonfiguration
Die Ausführung des Befehls "Set-WSManQuickConfig" hat erhebliche Auswirkungen auf die Sicherheit, da mit diesem die
Remoteverwaltung über den WinRM-Dienst auf diesem Computer ermöglicht wird.
Mit diesem Befehl werden folgende Aktionen ausgeführt:
 1. Überprüfen, ob der WinRM-Dienst ausgeführt wird. Wenn der WinRM-Dienst nicht ausgeführt wird, wird der Dienst
gestartet.
 2. Festlegen des Starttyps für den WinRM-Dienst auf automatisch.
 3. Erstellen eines Listeners zum Akzeptieren von Anforderungen an beliebigen IP-Adressen. Standardmäßig wird für den
Transport HTTP verwendet.
 4. Aktivieren einer Firewallausnahme für den WS-Verwaltungsverkehr.
Möchten Sie die Remoteverwaltung über den WinRM-Dienst auf diesem Computer aktivieren?
[J] Ja  [N] Nein  [H] Anhalten  [?] Hilfe (Standard ist "J"): j
WinRM ist bereits zum Empfangen von Anforderungen auf diesem Computer konfiguriert.
WinRM wurde für die Remoteverwaltung aktualisiert.
Auf HTTPS://* wurde ein WinRM-Listener erstellt, um die WS-Verwaltungsanforderungen an eine beliebige IP-Adresse auf di
esem Computer zu akzeptieren.
Die CertificateThumbprint-Einstellung für den Dienst wurde konfiguriert.

- Das cmdlet "Set-WSManQuickConfig" konfiguriert den WinRm-Dienst so, daß dieser Remoteverbindungen auf allen IPs des Rechners akzeptiert. Welche Konfigurationsänderungen dieses cmdlet genau vornimmt, ist in der OnlineHilfe oder unter  Technet: Set-WSManQuickConfig beschrieben. In Beispiel 3 zeige ich, wie man den Listener auf eine bestimmte IP-Adresse bindet.
- Set-WSMANQuickConfig muss in einer Powershellsession ausgeführt werden, die mit "als Administrator ausführen" gestartet wurde (rechte Maustaste auf die PS-Verknüpfung)


Beispiel 1b: Meldung bei fehlendem SSL-Zertifikat

set-WsManQuickConfig -usessl

Set-WsManQuickConfig : Es kann kein WinRM-Listener für HTTPS erstellt werden, da der Computer kein geeignetes Zertifikat besitzt. Zur Verwendung für SSL muss ein Zertifikat einen mit dem Hostnamen identischen, allgemeinen Namen (CN) besitzen und für die Serverauthentifizierung geeignet sein. Außerdem darf das Zertifikat nicht abgelaufen, gesperrt oder selbstsigniert sein.

Wenn "set-wsmanconfig -usessl" diese Fehlermeldung liefert, so müssen zuerst weitere Voraussetzungen wie im  Kapitel 3 SSL-Verschlüsselung weiter unten geschaffen werden.


Beispiel 2a: Enable-PSRemoting
Sehr ähnlich zu "Set-WsManQuickConfig" arbeitet das cmdlet "Enable-PSRemoting", allerdings ohne die Möglichkeit einen HTTPS-Listener einrichten zu können.

Enable-PSRemoting ruft zum einen "Set-WsManQuickConfig" auf und setzt damit dessen Einstellungen auf dem RemoteRechner, zum Anderen konfiguriert es bei Bedarf die Sitzungskonfiguration über Berechtigungen für den Remotezugriff durch Aufruf des cmdlets "PsSessionConfiguration -name *". Dieser "Bedarf" ist dann vorhanden, wenn vorher das cmdlet "Disable-PsRemoting" ausgeführt wurde.

enable-psremoting

#Ausgabe
#der erste Teil kommt von "WsMan-QucikConfig"
#der zweite Teil von "PsSessionConfiguration -name *"

WinRM-Schnellkonfiguration
Der Befehl "Set-WSManQuickConfig" zum Aktivieren dieses Computers für die Remoteverwaltung über den WinRM-Diens
ausgeführt.
 Dies umfasst die folgenden Schritte:
    1. Starten des WinRM-Diensts (bzw. Neustart bei bereits gestartetem Dienst)
    2. Festlegen des automatischen Starts für den WinRM-Dienst
    3. Erstellen einespss Listeners zum Akzeptieren von Anforderungen für eine beliebige IP-Adresse
    4. Aktivieren der Firewallausnahme für WS-Verwaltungsdatenverkehr (nur HTTP).

Möchten Sie den Vorgang fortsetzen?
[J] Ja  [A] Ja, alle  [N] Nein  [K] Nein, keine  [H] Anhalten  [?] Hilfe (Standard ist "J"): j
WinRM ist bereits zum Empfangen von Anforderungen auf diesem Computer konfiguriert.
WinRM ist bereits für die Remoteverwaltung auf diesem Computer eingerichtet.

Bestätigung
Möchten Sie diese Aktion wirklich ausführen?
Ausführen des Vorgangs "Set-PSSessionConfiguration" für das Ziel "Name: microsoft.powershell SDDL:
O:NSG:BAD:P(A;;GA;;;BA)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD). Damit lassen Sie die Remoteausführung von Windows PowerShell-Befehlen auf diesem Computer für ausgewählte Benutzer zu.".
[J] Ja  [A] Ja, alle  [N] Nein  [K] Nein, keine  [H] Anhalten  [?] Hilfe (Standard ist "J"):

Die Rückfragen lassen sich mit dem Positionsparameter -force unterdrücken


Beispiel 2b: Disable-PSRemoting

Dieses cmdlet macht nicht alle Konfigurationen von "Enable-PsRemoting" rückgängig, sondern nur die Berechtigung der Sessionkonfigurationen von "PsSessionConfiguration -name *" (siehe Beispiel 2a).
Dadurch wird sofort die Möglichkeit einer Remoteverbindung über WinRM unterbunden. (Fehlermeldung: Zugriff verweigert)

disable-psremoting -force

WARNUNG: Durch Deaktivieren der Sitzungskonfigurationen werden nicht alle Änderungen rückgängig gemacht, die vom Cmdlet  "Enable-PSRemoting" oder "Enable-PSSessionConfiguration" vorgenommen wurden. Möglicherweise müssen Sie die Änderungen
manuell rückgängig machen, indem Sie die folgenden Schritte ausführen:
    1. Beenden und deaktivieren Sie den WinRM-Dienst.
    2. Löschen Sie den Listener, der Anforderungen auf beliebigen IP-Adressen akzeptiert.
    3. Deaktivieren Sie die Firewallausnahmen für die WS-Verwaltungskommunikation.
    4. Setzen Sie den Wert von LocalAccountTokenFilterPolicy auf 0 zurück. Dadurch wird der Remotezugriff auf Mitglieder der Gruppe "Administratoren" auf dem Computer eingeschränkt.

Auch hier unterbindet der Positionsparameter -force weitere Rückfragen.


Beispiel 3: Konfiguration des Listeners für eine bestimmte IP-Adresse

Die folgenden Befehle können in der Commandlineshell oder in der Powershell ausgeführt werden

winrm create winrm/config/Listener?Address=IP:192.168.2.1+Transport=HTTP
winrm create winrm/config/Listener?Address=IP:192.168.2.1+Transport=HTTPS

#Ausgabe

ResourceCreated
    Address = schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
    ReferenceParameters
        ResourceURI = schemas.microsoft.com/wbem/wsman/1/config/listener
        SelectorSet
            Selector: Address = IP:192.168.2.1, Transport = HTTP

ResourceCreated
    Address = schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
    ReferenceParameters
        ResourceURI = schemas.microsoft.com/wbem/wsman/1/config/listener
        SelectorSet
            Selector: Address = IP:192.168.2.1, Transport = HTTPS

- Die Konfiguration mit dem winrm-Tool, das kein PS-cmdlet ist, können Listener genauer konfiguriert werden, als mit den cmdlets Set-WSManQuckconfig oder Enable-PSRemoting.
- In der Registry kann man sich den lokal konfigurierten Listener direkt ansehen (nicht den per GPO konfigurierten!):

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WSMAN\Listener\


Anmerkungen zu den Registryeinträgen:

--- *+HTTP bedeutet, daß der Listener auf jeder IP des Rechners nach Remoteanfragen auf dem HTTP-Port 5985 "lauscht"

--- *+HTTPS bedeutet, daß der Listener auf jeder IP des Rechners nach Remoteanfragen auf dem HTTPS-Port 5986 "lauscht". Auf diesem Rechner wurde neben "set-wsmanconfig" somit auch  "set-wsmanquickconfig -usessl" erfolgreich durchgeführt

--- IP:192.168.2.1+HTTP(S) bedeutet, daß der Listener nur für die IP 192.168.2.1 konfiguriert wurde

--- die Listener können durch Entfernen der Schlüssel unterhalb des Listenerschlüssels gelöscht werden. Der Listenerschlüssel selbst muss aber erhalten bleiben, sonst können später keine neuen Listener hinzugefügt werden.
Weiter sollten der Fingerabdruck des Zertifikats (credssp_thumbprint) unter dem Key "Service" entfernt werden.


Beispiel 4: Abfrage der Listenerkonfiguration aus der Powershell heraus

Mit diesem Befehl werden sowohl per cmdlets, wie auch per GPOs kofigurierte Listener angezeigt.

winrm enumerate winrm/config/listener

#Ausgabe

Listener      #Anmerkung: wie man sieht, sieht man nichts. Vergleich mit GPO-Konfiguration!
    Address = *
    Transport = HTTP
    Port = 5985
    Hostname
    Enabled = true
    URLPrefix = wsman
    CertificateThumbprint
    ListeningOn = 192.168.129.127, 127.0.0.1, ::1, 2002:2c6:817f::2c6:817f, fe80::200:5efe:192.168.129.127%12

Listener       #Anmerkung: wie man sieht, sieht man nichts. Vergleich mit GPO-Konfiguration!        
    Address = *
    Transport = HTTPS
    Port = 5986
    Hostname = Dom1Win7.Dom1.intern
    Enabled = true
    URLPrefix = wsman
    CertificateThumbprint = 46 17 1c 53 ea a7 b7 a7  f6 de d7 e2 bc e9 fd 2f85 2c 4c 12
    ListeningOn = 192.168.129.127, 127.0.0.1, ::1, 2002:2c6:817f::2c6:817f, fe80::200:5efe:192.168.129.127%12

Zu Beachten ist, daß bei lokal konfigurierten Listenern in der ersten Zeile "Listener" keine weiteren Angaben erfolgen. Bei einem GPO-konfiguriertem Listener gibt es keine Angaben

1.2.2 Konfiguration über GPOs

Die Konfigurationsmöglichkeiten des WinRM-Dienstes über Gruppenrichtlinien sind vergleichsweise dürftig. Besonders auffällig finde ich das Fehlen der Konfiguration von HTTS-Listenern.

Im Gruppenrichtlinieneditor findet man unter:
"Computerkonfiguration -> Richtlinien -> Administative Vorlagen -> Windows-Komponenten -> Windows-Remoteverwaltung (WinRM) -> WinRM-Dienst" die Settings für den WinRM-Service


Diese GPO-Settings habe ich aktiviert:

- Automatische Konfiguration von Listenern zulassen -> HTTP Port 5985
- Kompatibilitäts-HTTP-Listener aktivieren -> HTTP Port 80
- Kompatibilitäts-HTTPS-Listener aktivieren -> HTTPS Port 443

was zu folgender Listenerkonfiguration führt:
(Beachtet das "Source=" neben Listener)

Beispiel 1: Abfrage der Listenerkonfiguration aus der Powershell heraus

winrm enumerate winrm/config/listener

Listener [Source="GPO"]
    Address = *
    Transport = HTTP
    Port = 5985
    Hostname
    Enabled = true
    URLPrefix = wsman
    CertificateThumbprint
    ListeningOn = 4.11.129.127, 127.0.0.1, ::1, 2002:2c6:817f::2c6:817f, fe80::200:5efe:4.11.129.127%12

Listener [Source="Compatibility"]
    Address = *
    Transport = HTTP
    Port = 80
    Hostname
    Enabled = true
    URLPrefix = wsman
    CertificateThumbprint
    ListeningOn = 4.11.129.127, 127.0.0.1, ::1, 2002:2c6:817f::2c6:817f, fe80::200:5efe:4.11.129.127%12

Listener [Source="Compatibility"]
    Address = *
    Transport = HTTPS
    Port = 443
    Hostname = Dom1Win7.Dom1.intern
    Enabled = true
    URLPrefix = wsman
    CertificateThumbprint = 46 17 1c 53 ea a7 b7 a7  f6 de d7 e2 bc e9 fd 2f85 2c 4c 12
    ListeningOn = 4.11.129.127, 127.0.0.1, ::1, 2002:2c6:817f::2c6:817f, fe80::200:5efe:4.11.129.127%12

- Zu Beachten ist, daß bei lokal konfigurierten Listenern in der ersten Zeile "Listener" keine weiteren Angaben erfolgen. Bei GPO-konfiguriertem Listener gibt es hier Angaben
- Ich vermisse die Möglicheit einen HTTPS-Listener über eine GPO auf Port 5986 zu konfigurieren, wie das lokal (siehe Kapitel 1.2.1 Beispiel 1) möglich ist.

2 RemoteSession ohne SSL

Nachdem die Voraussetzungen aus Kapitel 1 und Kapitel 1.1 geprüft oder gegebenfalls nachgezogen wurden und das Remoting aus dem Zielcomputer, wie in Kapitel 1.2 beschrieben, aktiviert wurde, kann es jetzt mit dem Remoting via Powershell endlich losgehen:

2.1 new-pssession <Clientname>

Starten oder Neuerstellen kann man eine RemoteSession mit den beiden cmdlets "New-PSSession" (permanent) oder "EnterPSSession" (temporär).
Genauer gehe ich auf interaktive Sessions im Kapitel 4.4 ein. Dort versuche ich auch die Unterschiede zwischen dauerhaften und temporären Sessions herauszuarbeiten. Eine etwas andere Art von Remoting sind "implizite Session", die ich hier noch auslasse und auf die ich in Kapitel 4.5 detaillierter eingehen werde.

Beispiel 1: Ablauf einer interaktiven Remotesession ohne SSL

#Einrichten einer neuen permanenten Session auf DC1
$Computer="DC1"
new-pssession $computer

 Id Name            ComputerName    State    ConfigurationName     Availability
 -- ----            ------------    -----    -----------------     ------------
  4 Session4        dc1             Opened   Microsoft.PowerShell     Available

#Beitreten zur Session 4
enter-pssession 4

#Arbeiten am RemoteComputer
[dc1]: PS C:\Users\TestUser.DOM1\Documents> hostname
DC1

#Verlassen der Session 4 (nicht Beenden!)
[dc1]: PS C:\Users\Testuser.DOM1\Documents> exit-pssession

#Einrichten einer weiteren Session
new-pssession $computer

 Id Name            ComputerName    State    ConfigurationName     Availability
 -- ----            ------------    -----    -----------------     ------------
  5 Session5        dc1             Opened   Microsoft.PowerShell     Available

#Auslisten aller Remotessions
get-pssession

 Id Name            ComputerName    State    ConfigurationName     Availability
 -- ----            ------------    -----    -----------------     ------------
  4 Session4        dc1             Opened   Microsoft.PowerShell     Available
  5 Session5        dc1             Opened   Microsoft.PowerShell     Available

Anmerkung: Mit enter-pssession <computername> kann man in einem Schritt eine neue Session einrichten und dieser beitreten. Allerdings ist diese Session dann temporär und wird mit exit-pssession unwiederbringlich beendet.Powershell Remote

Beispiel 2: Beenden aller permanenten Remotessions zu $computer

remove-pssession $computer

Es können nur bis zu fünf RemoteSessions auf einem ZielComputer ausgeführt werden. Wenn folgende Meldung beim Aufruf von "new-pssession" erscheint:

"The WS-Management service cannot process the request. This user is allowed a maximum number of 5 concurrent shells, which has been exceeded. Close existing shells or raise the quota for this user."

dann muss man entweder den "remove-pssession" Befehl benutzen um Sessions zu beenden, oder auf dem Remoterechner nach Prozessen des Namens "wsmprovhost"  beispielsweise mit dem Taskmanager suchen und schliessen.

3 RemoteSession mit SSL-Verschlüsselung

Ein zusätzliches Plus an Sicherheit beim Remoting kann man erreichen, indem der WinRM die Verbindung zum Remoterechner mit einer zertifikatsbasierten SSL-Verbindung absichert.

Um den Powershellbefehl

new-pssession dc1 -usessl

erfolgreich ausführen zu können, bedarf es aber noch ein paar Voraussetzungen.
Anhand meiner einfachen Testumgebung, bestehend aus einem Windows2008R2-Server mit den Rollen "ActiveDirectory-Domänendienste" und "Activedirectory-Zertifikatsdienste" und einem Windows7 Client will ich die notwendigen Schritte darstellen.

3.1 Kurzbeschreibung SSL

Über das Protokoll Secure Sockets Layer (SSL) finden sich zahlreiche Informationen im Netz und in der Literatur.
Trotzdem möchte ich kurz und nicht so sehr technisch auf die Funktionsweise von SSL eingehen.
Da ich kein Zertifikatscrack bin, konzentriere ich mich mehr auf das prinzipielle Verständnis als auf die tiefe Technik.

SSL kann Anwendungsprotokolle auf OSI-Schicht 6 wie HTTP, SMTS oder das hier interessierende  WS-Management Protocol mit einem symmetrischen Schlüssel vrschlüsseln. Zu Beginn jeder SSL-Verbindung wird der SSL-Schlüssel neu ausgehandelt und nach Beendigung verworfen. Besteht die SSL-Verbindung, wird dieser "Symmetrische SSL-Schlüssel" vom Client und vom Server zum Ver- und Entschlüsseln der Verbindung benutzt.

Da symmetrische Verfahren mathematisch einfachere Algorithmen nutzen als asymmetrische Verfahren, können damit auch grössere Datenmengen performant verschlüsselt werden. Verbreitete SSL-Zertifikate benützen heute den  SHA1RSA Signaturalgorithmus bei einer Schlüssellänge von 2048 Bits.

Wie kommen beide Seiten an den symmetrischen Schlüssel?
Dazu benötigt nur(!) der Server, also der Rechner auf den wir zugreifen wollen, ein sogenanntes SSL-Zertifikat (nicht geheim) und ein damit mathematisch-verknüpftes Schlüsselpaar bestehend aus einem privaten (geheimen) und öffentlichen (nicht geheimen) Schlüssel. Zertifikat und Schlüsselpaar erhält der Server beispielsweise mithilfe einer Microsoft CA,  MSDN: Makecert oder eines anderen kommerziellen Keycenters das Zertifikate auch von Anbietern wie Verisign anbietet.
Im SSL-Zertifikat sind sicherheitstechnisch nur unkritische Informationen enthalten, wie unter anderem
- ausstellende CA,
- Signatur der CA,
- Gültigkeit  (von ... bis ...)
- Rechnername (FQDN)
- öffentlicher Schlüssel

Dieses Zertifikat schickt der Server an den anfordernden Clients. Mit Client ist hier genaugenommen der Clientteil des WinRM-Services gemeint, bei SSL-gesicherten Webseiten wäre es der Browser.
Der Client prüft die Gültigkeit des Zertifikats:
 a) anhand der CA-Signatur im Zertifikat. Dazu müssen im Zertifikatsspeicher des Clients das öffentliche Zertifikat der ausgebenden CA, sowie eventuell auch aller darüberliegenden CAs bis hoch zur RootCA (=Zertifikatskette) als vertrauenswürdige Stammzertifizierungsstellen enthalten sein. Die Authentizität des Servers garantiert die ausgebende CA
  b) anhand einer Sperrliste (Certificate Revocation List  oder moderner OCSP), ob das Zertifikat gesperrt wurde. Ist die Seriennummer des Zertifikats auf dieser Liste enthalten, oder kann der Client diese Sperrliste nicht erreichen, akzeptiert er das Zertifikat nicht.
 c) anhand der Daten im Zertifikat, ob das aktuelle Datum in der Gültigkeitsdauer liegt.Zertifikate können so ausgestellt werden, daß sie erst ab einem zukünftigem Datum gültig werden.
 d) anhand des Vergleichs des DNS-Namens und des Namens im Zertifikat (Details -> Antragsstellername)

Fallen a),b),c) und d) positiv aus, so generiert der Client erstens einen sogenannten "pre-master-secret" und zweitens den symmetrischen Schlüssel für die SSL-Verbindung.
Den "pre-master-secret" verschlüsselt der Client mit dem PublicKey des Servers, den er aus dem überprüften Zertifikat entnommen hat und sendet dieses Paket zurück an den Server. Der Server öffnet das Paket mit seinem PrivateKey und generiert aus dem "pre-master-secret" nach dem gleichen Algorithmus wie der Client denselben SSL-Schlüssel.

Meine Literaturquelle ist das PKI-Werk von Brian Komar "Windows Server 2008 - PKI and Certificate Security" aus dem MS-Press Verlag, welches im Kapitel 19 das Unterkapitel "How SSL Works" enthält.

3.2.2 Zertifikatsvorlage kopieren und anpassen (optional) (CA-Server)

Um eine SSL-Verbindung erstellen zu können, benötigen wir ein Zertifikat des Remoterechners, welches den CommonName wie "CN=Dom1Win7.Dom1.Intern" enthält. Von Haus aus passend sind beispielsweise die Templates "Computer" oder "Domänencontroller". Wenn kein Enterpriseserver als CA zur Verfügung steht, müssen wir diese Zertifikatsvorlagen benutzen.
Ist hingegen ein EnterpriseServer als CA verfügbar, so können wir exisitierende Templates nach unseren Vorstellungen anpassen. Am besten kopiert man sich ein einigermassen passendes Template, modifiziert die gewünschten Eigenschaften und speichert das Template unter einem passenden Namen.

Das Erstellen eines Zertifikatstemplates zur Codesignatur habe ich in
PSSkripte signieren: 2.3 Zertifikatstemplate erstellen schon beschrieben. Das Vorgehen für ein Computerzertifikat ist identisch, nur daß nicht die Vorlage "Codesignatur", sondern "Computer" oder "Domänencontroller" verwendet wird.

 

-Unter "Antragsstellername" -Format des Antragstellernamens muss "Allgemeiner Name" eingetragen werden.
-Unter "Sicherheit" muss dem Computerkonto das Recht gegeben werden, ein Zertifikat basierend auf der eben erstellten Vorlage anzufordern

 

Jetzt muss die Vorlage als "Auszustellende Vorlage" markiert werden



3.2.3 Zertifikat beantragen (RemoteRechner)

Detaillierter beschrieben habe ich diesen Vorgang im Kapitel 2.5 PSSkripte signieren

In der MMC mit dem SnapIn "Zertifikate (Lokaler Computer)" unter "Eigene Zertifikate" -> "Zertifikate" werden alle Computerzertifikate des Zertifikatstores aufgelistet.

 

3.2.4 Untersuchen des erstellten Zertifikats

Das Zertifikat kann man mit Doppelklick öffnen und die Eigenschaften untersuchen.
- Der Name des Antragstellers muss auf den korrekten CommonName des Rechners lauten. Dies ist der Grund, weshalb bei einer SSL-Verbindung keine IP-Adressen oder Kurznamen erlaubt sind, sondern nur Verbindungen mit dem CN-Namen akzeptiert werden.
- Der Fingerabdruck des Zertifikats kann später helfen, das ausgewählte Zertifikat in der Registry zu identifizieren



3.2.5 Listener konfigurieren (RemoteRechner)

Sind die Vorbereitungen soweit abgeschlossen, lassen sich ein oder mehr Listener des WinRM mit einfachen Powershellbefehlen konfigurieren:


Beispiel 1: SSL-Listener für alle IPs auf Port 5986 setzen

set-wsmanquickconfig -usessl -force

#Ausgabe (abhängig, was schon konfiguriert wurde)
WinRM ist bereits zum Empfangen von Anforderungen auf diesem Computer konfiguriert.
WinRM wurde für die Remoteverwaltung aktualisiert.
Auf HTTPS://* wurde ein WinRM-Listener erstellt, um die WS-Verwaltungsanforderungen an eine beliebige IP-Adresse auf di
esem Computer zu akzeptieren.
Die CertificateThumbprint-Einstellung für den Dienst wurde konfiguriert.

 

Beispiel 2: SSL-Listener für eine IP auf Port 5986 setzen

C:\Powershell\MyScripts> winrm create winrm/config/Listener?Address=IP:192.168.178.2+Transport=HTTPS

#Ausgabe
ResourceCreated
    Address = schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous
    ReferenceParameters
        ResourceURI = schemas.microsoft.com/wbem/wsman/1/config/listener
        SelectorSet
            Selector: Address = IP:192.168.178.2, Transport = HTTPS

 Der Registrykey "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WSMAN\Listener" sollte sich, wie in Kapitel 1.2 beschrieben, verändert haben.


Beispiel 3: weitere Konfigurationsmöglichkeiten des winrm

get-help winrm
New-WSManSessionOption


Der WinRM Dienst ist jetzt bereit, eine SSL-gesicherte Remoteverbindung auf Port 5986 zu akzeptieren, sofern keine Firewall den Zugriff auf den WinRM Dienst verhindert.

3.2.6 new-pssession <Clientname> -usessl

Sind alle Voraussetzungen geschaffen, so kann nun von einem lokalen Client eine SSL-gesicherte Powershellsitzung erstellt werden:

Beispiel 1: Einrichten, Benutzen und Beenden einer SSL-RemoteSession

#Einrichten
new-pssession dom1win7.dom1.intern

 Id Name            ComputerName    State    ConfigurationName     Availability
 -- ----            ------------    -----    -----------------     ------------
  1 Session1        dom1win7.dom... Opened   Microsoft.PowerShell     Available

 

#Benutzen
enter-pssession 1
[dom1win7.dom1.intern]: PS C:\Users\test1.DOM1\Documents> hostname

Dom1Win7

 

#Beenden
[dom1win7.dom1.intern]: PS C:\Users\test1.DOM1\Documents> exit-pssession

#Entfernen
remove-pssession dom1win7

Bis auf den Parameter -usessl besteht kein Unterschied im Handling zum Arbeiten ohne SSL, wie in Kapitel 2 beschrieben.

 

4 PowershellRemote in allen Variationen

In der Powershell kann man auf mehrere Arten Remoteverbindungen zwischen Rechnern aufbauen und nutzen. In diesem Kapitel stelle ich einige Varianten davon vor.

4.1 Alternativen zu WS-MAN/ WinRM

Wie in der Kapitel 0 Einleitung schon kurz ausgeführt, versteht Microsoft unter PowershellRemoting in erster Linie den Einsatz von WinRM mit den zugehörigen Powershellbefehlen.
Neben der Möglichkeit über den WSMAN eine Remoteverbindung aufzubauen, gibt es aber noch weitere Möglichkeiten:


a) cmdlets mit dem -computername Parameter

Laut  about_remote besitzen folgende cmdlets den Parameter "Computername"

        Clear-EventLog    Limit-EventLog
Get-Counter New-EventLog
Get-EventLog Remove-EventLog
Get-HotFix Restart-Computer
Get-Process Show-EventLog
Get-Service Show-Service
Get-WinEvent Stop-Computer
Get-WmiObject Write-EventLog

Beispiel 1: Abrufen aller Processe von einem RemoteComputer

Get-Process -computername dc1.dom1.intern 

Diese cmdlets können ohne weitere Vorbereitung alleine durch die Benutzung des Positionsparameters -computername remote benutzt werden. Die Kommunikation erfolgt über den Port 445 (microsoft-ds). 



b) get-wmiobject -computername

WMI habe ich in  diesem Kapitel bereits ausführlich behandelt.  


Beispiel 2: Abrufen aller Processe von einem RemoteComputer mittels WMI

get-wmiobject win32_service -computername 192.168.178.6

WMI besitzt den Positionsparameter -computername nativ und kann damit ebenfalls nativ remote eingesetzt werden. Die Kommunikation wird über Port 135 aufgebaut und läuft anschliessend über Highports.

 

c) interaktive Session mit psexec von Sysinternals aufbauen

Weit verbreitet ist das kostenlose  psexec-Tool. Der große Vorteil dieses Tools ist, dass man ohne Konfiguration des Zielrechners eine interaktive CommanlineSession zu diesem aufbauen kann. Für Powershell-Remoting muss hingegen zumindest ein Listener konfiguriert werden.

Beispiel 3: Sicherheitsloch in psexec
Bei aller Bewunderung für den Programmierer Mark Russinovich steckt in diesem Tool ein ordentliches Sicherheitsleck (psexec Version 1.98)

Verbindet man sich in der Windows Commandshell damit auf einen anderen Rechner

c:\temp>psexec \\192.168.129.126 cmd.exe -u dom1\karlnapf DemoPW123

PsExec v1.98 - Execute processes remotely
Copyright (C) 2001-2010 Mark Russinovich
Sysinternals - www.sysinternals.com


Microsoft Windows [Version 6.1.7600]
Copyright (c) 2009 Microsoft Corporation. Alle Rechte vorbehalten.

C:\Windows\system32>


und snifft mit  Wireshark den Verbindungsaufbau mit, so sieht man die unverschlüsselte Kommunikation und die    unverschlüsselten Credentials.
Die Erklärung zu Option "-p Specifies optional password for user name. If you omit this you will be prompted to enter a hidden password." täuscht nur eine nicht vorhandene Sicherheit vor. Eine SSL-Option, sowie einen deutlichen Hinweis würde ich erwarten.

Die Kommunikation erfolgt über den Port 445 (microsoft-ds).

Zumindest ist eine unverschlüsselte Übertragung von Credentials im Jahr 2011 nicht mehr zeitgemäss. 

 

4.2 Sitzungskonfiguration / Sessionconfiguration

KURZBESCHREIBUNG
Beschreibt Sitzungskonfigurationen, die bestimmen, welche Benutzer eine Remoteverbindung mit dem Computer herstellen und welche Befehle diese Benutzer ausführen können.

aus: Technet: about_Session_Configurations

Neben dieser konzeptionellen Hilfe gibt es noch folgende cmdlets, um Sessions zu konfigurieren

Beispiel 1: Anzeige der cmdlets zur Verwaltung einer SessionConfiguration

get-help pssessionconfiguration

Name                              Category  Synopsis
----                              --------  --------
Register-PSSessionConfiguration   Cmdlet    Erstellt und registriert eine neue Sitzungskonfiguration.
Unregister-PSSessionConfiguration Cmdlet    Löscht eine registrierte Sitzungskonfiguration vom Compute
Get-PSSessionConfiguration        Cmdlet    Ruft die registrierten Sitzungskonfigurationen auf dem Com
Set-PSSessionConfiguration        Cmdlet    Ändert die Eigenschaften einer registrierten Sitzungskonfi
Enable-PSSessionConfiguration     Cmdlet    Aktiviert die Sitzungskonfigurationen auf dem lokalen Comp
Disable-PSSessionConfiguration    Cmdlet    Verweigert den Zugriff auf die Sitzungskonfigurationen auf

 

Beispiel 2: Abfragen der vorhandenen SessionConfigurations auf dem lokalen Computer mit get-pssessionconfiguration

Technet:  get-pssessionconfiguration

get-pssessionconfiguration | format-list -property name, permission

#Ausgaebe auf 32 Bit OS
Name       : Microsoft.PowerShell
Permission : Jeder AccessDenied

#Ausgabe auf 64 Bit OS
Name       : microsoft.powershell
Permission : VORDEFINIERT\Administratoren AccessAllowed

Name       : Microsoft.PowerShell32
Permission : VORDEFINIERT\Administratoren AccessAllowed

- Die Sitzungskonfiguration "microsoft.powershell" und "Microsoft.PowerShell32" werden integrierte Sessioncinfigurations genannt. Diese werden von Powershell default verwendet, wenn die cmdlets  (New-PSSession, Enter-PSSession, Invoke-Command ) zum Aufbau einer Session ohne den Positionsparameter "-Configurationname" aufgerufen werden.
Auf 64-Bit Betriebssystemen existiert je eine Konfiguration für 32-Bit (Microsoft.PowerShell32) und eine Konfiguration für 64-bit (microsoft.powershell), auf 32-Bit Systemen existiert nur die microsoft.powershell

- auf die integrierte Sitzungskonfiguration können nur Mitglieder der Gruppe "Administratoren" zugreifen. Das bedeutet, nicht-Administratoren können keine Powershellsession Remote eröffnen.

- Genauer auf die Abragemöglichekeiten vorhandener Sessionconfigurationen gehe ich im Kapitel 4.2.2 Sitzungskonfigurationen auslesen ein. Unter anderem zeige ich dort, wie man Sessionconfigurationen remote abfragen kann und wie und wo sie gespeichert sind.

 

4.2.1 Erstellen und Verwenden einer neuen SessionConfiguration

Beispiel 1: Erstellen einer neuen Sessionconfiguration mit einem Startupscript

In ein Startupscript kann man all die Dinge hineinstecken, die man für lokale User in lokalen Profilen (siehe Profile/ Aliase ->  Kapitel 1.3 Beispiele für Profile) bereitstellt, wie Aliase und Funktionen. Ebenso können hier auch Snap-ins und Module bereitgestellt werden, so dass diese nicht jedesmal extra nachgeladen werden brauchen, wie das in den Beispielen von   Kapitel 4.5.1 Import-PSSession für implizite Sessions geschieht.

Ich habe dieses Beispiel, das die Funktionsweise einer SessionConfiguration verdeutlichen soll, der Übersicht halber in einzelne Schritte untergeteilt, :

Vorbereitungsschritt 0) Anlage des Startupscripts c:\scripts\test1.ps1 
Um das Beispiel funktionsfähig zu sehen, legt bitte vorher unter C:\scripts\ das PS-StartupScript test1.ps1 mit diesem Inhalt ab.

write-host "hellgrüner Hintergrund ist MegaIN!"
$win = (Get-Host).UI.RawUI
$win.BackgroundColor = "green"


Schritt 1) Neuregistrierug der SessionConfiguration "Config-Session1"

Register-PSSessionConfiguration -Name "Config-Session1" -StartupScript C:\scripts\test1.ps1 -force

#Ausgabe 1)

   WSManConfig: Microsoft.WSMan.Management\WSMan::localhost\Plugin

Name                      Type                 Keys
----                      ----                 ----
Config-Session1           Container            {Name=Config-Session1}

Anmerkung zu 1)
 Technet: Register-PSSessionConfiguration
Die erstellte Sessionconfiguration bleibt auch nach einem Reboot solange erhalten, bis sie mit dem cmdlet "Unregister-PSSessionConfiguration" wieder entfernt wird. (siehe den letzten Teil 4a dieses Beispiels)


Schritt 2) Abfrage aller SessionConfigurations auf dem lokalen Rechner 

get-pssessionconfiguration

#Ausgabe 2)

Name                      PSVersion  StartupScript        Permission
----                      ---------  -------------        ----------
Config-Session1           2.0        C:\scripts\test1.ps1
microsoft.powershell      2.0                             VORDEFINIERT\Administratoren Acc...
Microsoft.PowerShell32    2.0                             VORDEFINIERT\Administratoren Acc...

Anmerkung zu Schritt 2)
 Technet: get-pssessionconfiguration
"Config-Session1" ist neu dazugekommen. Die beiden Microsoft.Powershell-ConfigurationSessions sind die integrierten (=default) Configurations (siehe Beispiel 2 in Kapitel 4.2)


Schritt 3) Betreten einer Session. Dies kann auf dem lokalen, oder auch von einem RemoteRechner -dann mit dem Positionsparameter computername" aus geschehen

enter-pssession -computername dom1win7 -configurationname config-session1

#Ausgabe 3)
hellgrüner Hintergrund ist MegaIN!
hostname
Dom1Win7
[dom1win7]: PS C:\Users\KarlNapf.DOM1\Documents>
exit-pssession

Anmerkung zu Schritt 3)
Die Ausgabe erfolgt aufgrund des Startupscript in 0) auf giftgrünem Hintergrund, der auch nach dem Verlassen der Session mit exit-pssession bestehen bleibt.
(Leider kann ich in diesem CMS keine Farben darstellen).


Schritt 4a) Entfernen der Sessionconfiguraion

Unregister-PSSessionConfiguration -Name "Config-Session1" -force

Anmerkung zu Schritt 4a)
 Technet: Unregister-PSSessionConfigruation
Mit diesem Befehl wird "Config-Session1" wieder entfernt. Der Positionsparameter "-force" unterbindet zwei Sicherheitsabfragen, die sonst extra bestätigt werden müssen.


Schritt 4b) Disablen der Sessionconfiguraion

Disable-PSSessionConfiguration -Name "Config-Session1" -force

Anmerkung zu Schritt 4b)
 Technet: Disable-PSSessionConfiguration
Statt eine SessionConfiguration wieder komplett zu entfernen, kann man die Sessionconfiguration auch nur disablen. Dadurch wird ihr Securitydescriptor so verändert, daß sie nicht mehr in einer Session geladen, aber noch verändert, angesehen und wieder reaktiviert werden kann.


4.2.2 Sitzungskonfigurationen auslesen

 Technet: about_Session_Configurations

Im einleitenden Kapitel 4.2 Sitzungskonfiguration / Sessionconfiguration habe ich im Beispiel 2 gezeigt, wie die vorhandene lokale Sessionconfiguration mit dem cmdlet "get-pssessionconfiguration" angezeigt werden kann.
In diesem Kapitel gehe ich, wie dort angekündigt, genauer auf die Abfrage von Sessionconfigurationen ein. 


Beispiel 1: Abfrage der vorhandenen Sessionkonfigurationen auf dem lokalen Computer mit dem WS-Verwaltungsanbieter
(aus dem eben genannten Technet Artikel "about_Session_Configurations". Dort sind auch noch weitere Details beschrieben)

dir wsman:\localhost\plugin\*

#Ausgabe
   WSManConfig: Microsoft.WSMan.Management\WSMan::localhost\Plugin

Name                      Type                 Keys
----                      ----                 ----
Config-Session1           Container            {Name=Config-Session1}
Config-Session2           Container            {Name=Config-Session2}
Config-Session3           Container            {Name=Config-Session3}
Event Forwarding Plugin   Container            {Name=Event Forwarding Plugin}
microsoft.powershell      Container            {Name=microsoft.powershell}
Microsoft.PowerShell32    Container            {Name=Microsoft.PowerShell32}
WMI Provider              Container            {Name=WMI Provider}


Die SessionConfigurations sind in der Registry unter
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\WSMAN\Plugin\ gespeichert.

Ansehen kann man eine Sessionkonfiguration direkt, wenn man den RegistryWert ConfigXML nach notepad kopiert, die Datei mit der Endung *.xml abspeichert und in einem Webbrowser anzeigen lässt. In den nächsten beiden Bildern ist dieser Vorgang dargestellt.


Beispiel 2: Detaillierte Information einer Sessionconfiguration mit get-pssessionconfiguration abfragen

Die xml-Informationen lassen sich natürlich auch per Skript abfragen, wie unter Beispiel 3 unter  Technet: get-pssessionconfiguration beschrieben ist

Get-PSSessionConfiguration -name microsoft.powershell | format-list -property *
#Ausgabe gekürzt
...
Uri : schemas.microsoft.com/powershell/microsoft.powershell
SecurityDescriptorSddl : O:NSG:BAD:P(A;;GA;;;BA)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)
ExactMatch : False
...

 

Beispiel 3: Abfrage der vorhandenen Sessionkonfigurationen auf einem RemoteComputer mit dem WS-Verwaltungsanbieter

dir wsman:\dc1.dom1.intern\plugin\*

#Ausgabe

   WSManConfig: Microsoft.WSMan.Management\WSMan::dc1.dom1.intern\Plugin

Name                      Type                 Keys
----                      ----                 ----
Event Forwarding Plugin   Container            {Name=Event Forwarding Plugin}
microsoft.powershell      Container            {Name=microsoft.powershell}
Microsoft.PowerShell32    Container            {Name=Microsoft.PowerShell32}
microsoft.ServerManager   Container            {Name=microsoft.ServerManager}
SEL Plugin                Container            {Name=SEL Plugin}
WMI Provider              Container            {Name=WMI Provider}

 Vergleiche auch das Beispiel in  Technet: about_Session_Configurations unter der Überschrft "Anzeigen von Sitzungskonfigurationen auf einem Remotecomputer".

 

4.2.3 Einschränken der verfügbaren cmdlets

Eine weitere faszinierende Möglichkeit des Powershellremotings liegt darin, durch Sessionconfigurations nur einen vordefinierte Satz an cmdlets bereitzustellen.
Damit kann man Hilfsrollen die Möglichkeit einräumen, nur bestimmte Aktionen mittels Powershell auf einem Remoterechner ausführen zu dürfen.
Die Rechte auf Sessionconfigurations können dann weiter auf bestimmte User oder Gruppen beschränkt werden. Im nächsten Kapitel 4.2.4 ist beschrieben, wie man den Securitydescriptor konfigurieren kann. Hier in 4.2.3 gehts erstmal darum, die erlaubten cmdlets festzulegen.


Beispiel 1: die verfügbaren cmdlets mit einer SessionConfiguration so beschränken, dass Accounts angesehen, aktiviert und deaktiviert werden können.

Vorbereitungsschritt 0: Anlage des Startupscripts c:\scripts\Config-DC1.ps1 
Zur Vorbereitung legt bitte auf einem Domaincontroller das Skript c:\scripts\Config-DC1.ps1 an

import-module activedirectory

$RequiredCommands = @(
"Get-Command",
"Get-FormatData",
"Out-Default",
"Select-Object",
"out-file",
"Measure-Object",
"Exit-PSSession",

"Enable-ADAccount",
"Disable-ADAccount",
"Get-ADUser"
"Format-List"
)
$ExecutionContext.SessionState.Applications.Clear()
$ExecutionContext.SessionState.Scripts.Clear()
Get-Command -CommandType Cmdlet, alias, function | ?{$RequiredCommands -notcontains $_.Name} | %{$_.Visibility="Private"}
$ExecutionContext.SessionState.LanguageMode="RestrictedLanguage"

- Nähere Erklärungen zu den Grundlagen gibt es unter diesem Link:  PowerShell 2.0 remoting guide: Part 10 – Restricting available commands using custom session configuration
- Ich habe das Startupskript nur um die ActiveDirectory cmdlets erweitert, um eine praktische Anwendung zu demonstrieren können.
- Name und Pfad des StartupScripts sind natürlich beliebig


Schritt 1: Einmalige Registrierug der SessionConfiguration "Config-DC1" auf dem Domaincontroller DC1

Register-PSSessionConfiguration -Name "Config-DC1" -StartupScript C:\scripts\Config-DC1.ps1 -force

   WSManConfig: Microsoft.WSMan.Management\WSMan::localhost\Plugin

Name                      Type                 Keys
----                      ----                 ----
Config-DC1                Container            {Name=Config-DC1}

eine detailliertere Anleitung zum Registrieren und Unregistrieren habe ich in Kapitel 4.2.1 Beispiel 1 erstellt.


Schritt 2: Betreten einer Session mit einer Sessionconfiguration. Dies kann testweise auf dem lokalen, oder von einem RemoteRechner aus geschehen

enter-pssession -configurationname config-dc1 -computername dc1
[dc1]: PS>get-command *

#Ausgabe der verfügbaren cmdlets

CommandType     Name                                                Definition
-----------     ----                                                ----------
Cmdlet          Disable-ADAccount                                   Disable-ADAccount [-Ident
Cmdlet          Enable-ADAccount                                    Enable-ADAccount [-Identi
Cmdlet          Exit-PSSession                                      Exit-PSSession [-Verbose]
Cmdlet          Format-List                                         Format-List [[-Property]
Cmdlet          Get-ADUser                                          Get-ADUser -Filter <Strin
Cmdlet          Get-Command                                         Get-Command [[-ArgumentLi
Cmdlet          Get-FormatData                                      Get-FormatData [[-TypeNam
Cmdlet          Measure-Object                                      Measure-Object [[-Propert
Cmdlet          Out-Default                                         Out-Default [-InputObject
Cmdlet          Out-File                                            Out-File [-FilePath] <Str
Cmdlet          Select-Object                                       Select-Object [[-Property

Wir sehen hier genau die cmdlets wieder, die wir im Startupscript in Schritt 0 definiert haben. Ausschliesslich diese cmdlets stehen in dieser Remotesession auch zur Verfügung


Schritt 3: ADUser bearbeiten und Verlassen der Session

[dc1]: PS>get-aduser Karl_Napf | select-object userprincipalname,enabled | format-list

#Ausgabe
userprincipalname : Karl_Napf@Dom1.intern
enabled           : True

[dc1]: PS>disable-adaccount Karl_Napf
[dc1]: PS>get-aduser Karl_Napf | select-object userprincipalname,enabled | format-list

#Ausgabe
userprincipalname : Karl_Napf@Dom1.intern
enabled           : False

[dc1]: PS>enable-adaccount Karl_Napf
[dc1]: PS>exit-pssession

 

4.2.4 Sicherheitsbeschreibung einer Sitzungskonfiguration

Richtig rund und interessant werden Sessionconfigurations, wenn wir normalen Anwendern den Aufruf der Powershell mit einem nur eingeschränkten Befehlssatz erlauben können. Im Ausgangszustand der Sessionconfiguration können nur Administratoren die RemoteSession eröffen.
In diesem Kapitel werde ich zeigen, wie wir die Berechtigungen so verändern können, dass nicht mehr nur ausschliesslich Administratoren, sondern normale Domänenaccounts bestimmte Aufgaben mit der Powershell remote erledigen können.

4.2.4.1 Security Descriptor Definition Language (SDDL)

 MSDN: Security Descriptor Definition Language

 MSDN: SID Strings

Der Zugriff auf die SessionConfigurationen wird über Berechtigungen gesteuert, oder  präziser ausgedrückt: über die "security descriptor definition language (SDDL)" in einem Registrykey. (siehe Kapitel 4.2.2 Standardsitzungskofiguration Beispiel 2)
Es ist nicht unbedingt notwendig die SDDL zu verstehen, um Berechtigungen zu setzen, da die Powershell mit "Set-PSSessionConfiguration -ShowSecurityDescriptorUI" auch die Möglichkeit bietet, Berechtigungen über eine GUI zu setzen.
Trotzdem will ich fürs Verständnis die SDDL kurz beschreiben und zumindest die Links zum Nachschlagen aufführen. Die prinzipielle Kenntnis über die Bedeutung der Begriffe " Owner", "Primary Group", "DACL", "ACE" und "SACL" setze ich bei euch, wenn ihr euch für die SDDL interessiert, einfach mal voraus. :-)


Beispiel 1a: Analyse eines SDDL-Strings
(Grundstruktur)

Am besten holen wir uns den Securitydescriptor der integrierten Sessionconfiguration "microsoft.powershell" und sehen diesen genauer an:

get-pssessionconfiguration  |  where{$_.name -eq 'microsoft.powershell'} | fl name,Securitydescriptorsddl

(vergleiche auch Kapitel 4.2.2 Beispiel 1)

In die Ausgabe unten habe ich ein paar Erklärungen farblich eingefügt:

-Die roten Kommentare zeigen die Struktur eines SDDL-Strings,  der aus den vier Hauptkomponenten owner (O:), primary group (G:), DACL (D:) und SACL (S:) besteht. Im Beispiel unten ohne SACL(S:)!
Genauer nachlesen kann man die Struktur im oberen Teil dieses Artikels  MSDN: Security Descriptor String Format

- Die blauen Kommentare erklären die beiden verwendeten Strings für den Owner (NS) und die Primary Group (BA).  MSDN: SID Strings

In diesem Beispiel sind die beiden ersten Komponenten "Owner" und "Primary Group" sind für die Sessionconfiguration nicht so wichtig. Mitnehmen kann man aus diesem Beispiel die etwas seltsame Schreibweise, bei der der Doppelpunkt ":" kein Trennzeichen darstellt und eine neue Komponente nicht einmal durch ein Space getrennt wird.

# Ausgabe mit Kommentaren


Beispiel 1b: Analyse eines SDDL-Strings (ACE)

Hier wirds für unsere Belange interessanter, da im hinteren Teil des SDDL-String -beginnend mit "S:P(" -die Berechtigung der Sessionconfiguration wiedergegeben wird. Am ACE-String erkennt das System, welche User eine bestimmte Sessionconfiguration benutzen dürfen und welche nicht.
Die Struktur des ACE String wird im MSDN-Artikel 1) so beschrieben: Jede einzelne ACE ist in runden Klammern eingeschlossen, die ACE-Felder sind durch Semicolons ";" getrennt und nach folgender Reihenfolge angeordnet:

ace_type;ace_flags;rights;object_guid;inherit_object_guid;account_sid 

Wir benutzen dieselbe Ausgabe wie im Beispiel 1a)

 

Die Bedeutung der ACE-Felder findet man in den Tabellen dieses Artikels  MSDN: ACE Strings wieder. Das letzte Feld "account_sid" findet man im Artikel  MSDN: SID String

Beispiel 1c: Anzeige der Berechtigungen mit einer GUI

wie schon weiter oben erwähnt, lassen sich die Berechtigungen einer Sessionconfiguration komfortabel über die GUI auslesen und verändern

Set-PSSessionConfiguration -ShowSecurityDescriptorUI -name microsoft.powershell -force

-force unterdrückt Rückfragen

Die Ausgabe desselben Beispiels wie in 1a) und 1b) sieht in der GUI recht unspektakulär so aus:




4.2.4.2 SessionConfiguration für bestimmte User verfügbar machen

Im Kapitel 4.2.3 Einschränken der verfügbaren cmdlets haben wir auf unserem DC bereits eine Sessionconfiguration mit dem Namen config-dc1 erstellt. Diese besitzt ein lokales Startupscript unter C:\scripts\test1.ps1, welches die Anzahl der verfügbaren cmdlets auf 11 einschränkt. Noch können aber nur Administratoren diese Configuration benutzen.
In diesem Kapitel werden wir die Berechtigung auf einen einfachen Domänenuser ausweiten, so daß dieser sich remote von einem Client auf den DC mit dieser Sessionconfiguration verbinden kann.  Dort hat er nur vordefinierten cmdlets zur Verfügung und kann einen bestimmten AD-Account aktivieren und deaktivieren.

zusammenfassendes Beispiel zur SessionConfiguration

In diesem abschliessenden Beispiel fügen wir die vorherigen Kapitel unter 4.2 Sitzungskonfigurationen zusammen.
Wir ermöglichen einem StandardDomänenBenutzer (Karl_Napf@dom1.intern) sich mit PSRemote mit einer auf einen Domänencontroller (DC1) zu verbinden. Dabei lädt der eine Sitzungskonfiguration (Config-DC1), die ihm einen eingeschränkten Satz con cmdlets zur Verfügung stellt, mit denen er einen andereren Domänenaccount (Heinz_Hinz@dom1.intern) aktiveren und deaktivieren kann.

Vorbereitungsschritt 1a: Kontrolle der angelegten Sessionconfiguration

Get-PSSessionConfiguration -name config-dc1 | format-list

#Ausgabe

Name                   : Config-DC1
Filename               : %windir%\system32\pwrshplugin.dll
SDKVersion             : 1
XmlRenderingType       : text
lang                   : de-DE
PSVersion              : 2.0
startupscript          : C:\scripts\test1.ps1
ResourceUri            : schemas.microsoft.com/powershell/Config-DC1
SupportsOptions        : true
Capability             : {Shell}
xmlns                  : schemas.microsoft.com/wbem/wsman/1/config/PluginConfiguration
Uri                    : schemas.microsoft.com/powershell/config-DC1
ExactMatch             : false
SecurityDescriptorSddl : O:NSG:BAD:P(A;;GA;;;BA)(A;;GR;;;BU)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)
Permission             : VORDEFINIERT\Administratoren AccessAllowed, VORDEFINIERT\Benutzer AccessAllowed

 
Vorbereitungsschritt 1b: Kontrolle des startupscripts c:\scripts\test1.ps1

#Dieses Startupscript stellt die sieben unbedingt notwendigen cmdlets für eine Remotesession bereit
.....
$ExecutionContext.SessionState.LanguageMode="RestrictedLanguage"

Das gesamte StartupSkript und die Registrierung der Sessionconfiguration seht ihr im Kapitel  4.2.3 Einschränken der verfügbaren cmdlets


Vorbereitungsschritt 2a: Erweitertern der Berechtigungen für die Sitzungskonfiguration "Session-DC1"

Set-PSSessionConfiguration -ShowSecurityDescriptorUI -name config-dc1 -force

führt zu folgenden GUI, in der man einen SecurityPrincipal einträgt. Ich füge in diesem Beispiel der Einfachheit halber meinen Testuser "Karl_Napf" hinzu. Im richtigen Leben wird man Sicherheitsgruppen benutzen.


Vorbereitungsschritt 2b: Kontrolle der Änderung am DC

Get-PSSessionConfiguration -name config-dc1 | format-list -property *

Name                   : Config-DC1
...
SecurityDescriptorSddl : O:NSG:BAD:P(A;;GA;;;BA)(A;;GR;;;BU)(A;;GXGR;;;S-1-5-21-3207648952-1170633684-1844968635-9004)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)
Permission             : VORDEFINIERT\Administratoren AccessAllowed, VORDEFINIERT\Benutzer AccessAllowed, DOM1\Karl_Napf AccessAllowed

Durch den Schritt 2a wurde dem Standardbenutzer "Karl_Napf" der Zugriff erlaubt.


Vorbereitungsschritt 3: Erweitern der Rechte auf einem AD-Konto für einen PS-User

Ich erlaube dem Domänenbenutzer "Karl_Napf" das Konto "Heinz-Hinz" zu aktivieren und zu deaktivieren.
In der MMC "Active Directory Benutzer und Computer" setzt bitte folgende Einstellungen auf eurem Testuser. (Nicht vergessen im Menü "Ansicht" die "erweiterten Features" zu aktivieren!
Dies ist selbstverständlich wieder ein einfaches theoretisches Beispiel, welches in die Praxis mit Gruppen und OrganizationalUnits übertragen werden würde.


Schritt 4: Verbinden vom Client zum Domaincontroller als Standardbenutzer

Ab jetzt werden wir sehen, ob die Vorbereitungen ordnungsgemäß durchgeführt wurden.
Die Verbindung erfolgt von einem Win7-Client zu einem W2k8R2-Domänencontroller (dc1), auf dem die Sessionconfiguration "config-dc1" registriert wurde.

enter-pssession -configurationname config-dc1 -computername dc1
[dc1]: PS>get-command

#Ausgabe

CommandType     Name                                Definition
-----------     ----                                ----------
Cmdlet          Disable-ADAccount                   Disable-ADAccount [-Identi
Cmdlet          Enable-ADAccount                    Enable-ADAccount [-Identit
Cmdlet          Exit-PSSession                      Exit-PSSession [-Verbose]
Cmdlet          Format-List                         Format-List [[-Property] <
Cmdlet          Get-ADUser                          Get-ADUser -Filter <String
Cmdlet          Get-Command                         Get-Command [[-ArgumentLis
Cmdlet          Get-FormatData                      Get-FormatData [[-TypeName
Cmdlet          Measure-Object                      Measure-Object [[-Property
Cmdlet          Out-Default                         Out-Default [-InputObject
Cmdlet          Out-File                            Out-File [-FilePath] <Stri
Cmdlet          Select-Object                       Select-Object [[-Property]

Die RemoteSession wird mit "enter pssession" eingerichtet und betreten. Default haben Nicht-Administratoren nicht das Recht eine Remotesession aufzurufen.
"get-command" zeigt die für Karl_Napf verfügbaren cmdlets an. Es werden auch keine Aliase akzeptiert, etwa "FL" für "Format-List".

Schritt 5: Anzeigen von Eigenschaften eines Users

[dc1]: PS>get-aduser heinz_hinz

#Ausgabe

[dc1]: PS>get-aduser heinz_hinz
DistinguishedName : CN=Heinz Hinz,OU=BenutzerA,OU=scripting,DC=Dom1,DC=intern
Enabled           : True
GivenName         : Heinz
Name              : Heinz Hinz
ObjectClass       : user
ObjectGUID        : b3868ce8-4f2f-4860-88d3-3b582094a6c3
SamAccountName    : Heinz_Hinz
SID               : S-1-5-21-3207648952-1170633684-1844968635-9006
Surname           : Hinz
UserPrincipalName : Heinz_Hinz@Dom1.intern

Die Defautl AD-Berechtigungen erlauben es jedem Domänenbenutzer (hier: Karl_Napf) diese Felder von jedem anderen Domänenbenutzer (hier: Heinz_Hinz) zu lesen.


Schritt 6: Deaktivieren und Aktivieren eines Domainusers

Da wir im Vorbereitungschritt 3 dem Domänenbenutzer Karl_Napf erlaubt haben, das Konto von Heinz_Hinz zu Aktivieren und zu Deaktivieren, kann KarL_Napf dies jetzt mit den beiden ADcmdlets "Disable-ADAccount" und "Ensable-ADAccount" durchführen.

[dc1]: PS>Disable-ADAccount heinz_hinz
[dc1]: PS>get-aduser heinz_hinz | format-list SamAccountname,Enabled

#Ausgabe

SamAccountname : Heinz_Hinz
enabled        : False

 

[dc1]: PS>Enable-ADAccount heinz_hinz
[dc1]: PS>get-aduser heinz_hinz | format-list SamAccountname,Enabled

#Ausgabe

SamAccountname : Heinz_Hinz
enabled        : True 

 

4.3 Remotesessions mit dem cmdlet "invoke-command"

 Technet: About_Remote -> Detailbeschreibung
 Technet: invoke-command

Wenn man sich die Links ansieht, erkennt man schon, daß wieder ein sehr mächtiges Werkzeug mit jeder Menge Parametern auf einen zukommt. Daher gebe ich zu Beginn einen kurzen Überblick, auf welche Features ich im Folgenden mit Beispielen näher eingehen möchte.

- temporäre Verbindungen
- dauerhafte Verbindungen
- Nachteile

Lohnenswert ist invoke-command, wenn man auf mehreren Rechnern nacheinander einzelne Befehle oder auch ganze Skripte ausführen möchte.
Will man hingegen auf einem Rechner arbeiten oder diesen näher untersuchen, so ist eine interactive RemoteSession, wie in Kapitel 4.4 beschrieben, besser geeignet.

Auf das Remote-Ausführen von Befehlen oder Skripten als BackgroundJobs werde ich unter "Prozesse - Dienste - Jobs" näher eingehen.


4.3.1 Remoting mit temporärer Verbindung

In den Beispielen dieses Kapitels wird eine temporäre Verbindung zum Remoterechner aufgebaut, die, sobald der invoke-command Befehl abgearbeitet ist, sofort wieder beendet wird. Die Ergebnisse auf dem Remoterechner sind danach verloren

Beispiel 1: schneller Überblick über die Laufwerke C und D auf verschiedenen Rechnern mittels Scriptblock

$drives=invoke-command -computername  (get-content machines.txt) -scriptblock  {get-psdrive c,d } -usessl
$drives 

write-host "`n" #eine Leerzeile für die Optik

$drives | foreach{
write-host $_.name  $_.free $_.used} #vergleiche "drives | get-member"

#Ausgabe

Name     Used (GB)     Free (GB) Provider  Root     CurrentLocation                 PSComputerName                          
----     ---------     --------- --------  ----     ---------------                 --------------                          
C        10,58         23,50               C:\      Users\administrator\Documents   dom2win701                              
D        ,00                               D:\                                      dom2win701                              
C        13,57         10,84               C:\      Users\Administrator\Documents   dom2dc01                                
D        1,33                              D:\                                      dom2dc01                                


C 25230536704 11363713024
D 0 2674688
C 11640881152 14570369024
D 0 1423409152

 

- In der Datei machine.txt sind meine beiden Testmaschinen "dom2dc01" und "dom2win701" aufgeführt.

- Sind die Voraussetzungen vorhanden, kann man optional  die Verbindungen über ein Zertifikat mit dem Positionsparameter -usessl absichern. (siehe  Kapitel 3)

- Der Skriptblock {get-psdrive c,d } wird auf jeden RemoteComputer in den Cache kopiert und dort ausgeführt.

- Man wünscht sich eventuell den Scriptblock komplett in eine Variable packen zu können. Dies ist -zumindest habe ich nichts anderes herausgefunden- nur sehr bescheiden mit dem CallOperator "&" zu verwirklichen.

- Prinzipiell kann man in einem Scriptblock beliebige und beliebig viele Powershellcommands unterbringen. Praktikabler ist es, ein Skript auf dem lokalen Rechner zu erstellen und dies mit invoke-command aufzufrufen, was ich im nächsten Beispiel zeigen werde.

- Vergleiche auch  Technet: Invoke-Command Beispiel 7


Beispiel 2:
Überblick über die Laufwerke auf  verschiedenen Rechnern mittels lokalem Skript

#Aufrufendes Skript oder Aufruf in der interactiven Powershell

$arrComputers="dom2dc1","dummyRechner","dom2win701" #Rechnerliste mit einem dummy

$Headline="`nDrive   Totalsize   Totalfreespace   Percentfree   Computername"
"$Headline"
"-"*$($Headline.length)

invoke-command -computername $arrComputers -filepath C:\test\getfreespace.ps1 -ErrorAction SilentlyContinue

#Skript auf C:\test\getfreespace.ps1

$drives=[system.io.driveinfo]::getdrives()

$drives | foreach {
  if ($_.totalsize -gt 0){
     $Drivename=$_.name
     $Totalsize=$($_.totalsize)/1GB
     $TotalFreeSpace=$($_.totalfreespace)/1GB
     $PercentFree=$($_.totalfreespace)/$($_.totalsize)
     $computername=get-content env:computername #Hostname
    
     $width_0=3
     $width_1=9
     $width_2=8
     $width_3=13
     $width_4=8+$computername.length
         "{0,$width_0} {1,$($width_1):0.00} GB {2,$($width_2):0.00} GB {3,$($width_3):0.0%} {4,$width_4}" -f $Drivename,$totalsize,$TotalFreeSpace,$PercentFree,$computername
  }else{
     $Drivename=$_.name
     $computername=get-content env:computername
      "{0} {1,55}" -f $Drivename,$computername
  }
}

#Ausgabe

Drive   Totalsize   Totalfreespace   Percentfree   Computername
----------------------------------------------------------------
A:\                                                DOM2DC01
C:\     24,41 GB    11,30 GB         46,3%         DOM2DC01
D:\                                                DOM2DC01
A:\                                                DOM2WIN701
C:\     34,08 GB    23,42 GB         68,7%         DOM2WIN701
D:\      0,00 GB     0,00 GB          0,0%         DOM2WIN701


- Das Skript C:\test\getfreespace.ps1 wird auf jeden RemoteComputer in den Cache kopiert und dort ausgeführt. 

- Die Computerliste ist im Array $arrcomputers definiert, die ich direkt im Invoke-command Befehl übergebe. Da die Liste auch nicht erreichbare Namen enthälten könnte, setze ich die PreferenceVariable "Erroraction" auf "SilentlyContinue", um Fehlermeldungen zu unterdrücken. Im Kapitel  "Variablen und Parameter" habe ich diese Variable näher beschrieben.

- vergleiche auch  Technet: Invoke-Command Beispiel 1


Beispiel 3:
Parametrisierung des Scriptblocks - SecurityEventlog remote abfragen

$Logname = "security"
$number= 5
$Events=invoke-command -computername dc1 -scriptblock {param($log, $num) get-eventlog -logname $log -newest $num} -ArgumentList $Logname, $number

#$Events[-1] | gm  #Damit können alle Abfragbaren Eigenschaften ermittelt werden

$$Events[-1].message  # $logs ist ein Array. Das Element $$Events[-1] ist das zuletzt geschriebene Event
$$Events[-1].timegenerated

#Ausgabe 

Ein Konto wurde abgemeldet.

Antragsteller:
    Sicherheits-ID:        S-1-5-21-3207648952-1170633684-1844968635-1106
    Kontoname:        DOM1WIN7$
    Kontodomäne:        DOM1
    Anmelde-ID:        0x35267d4

Anmeldetyp:            3

Dieses Ereignis wird generiert, wenn eine Anmeldesitzung zerstört wird. Es kann anhand des Wertes .....

Mittwoch, 19. Januar 2011 14:30:52

 

4.3.2 Remoting mit dauerhafter Verbindung

Im Gegensatz zu Kapitel 4.3.1, bei dem wir jeweils nur eine temporäre Verbindung mit "invoke-command -computername" zum Remote Computer aufgebaut haben, bauen wir in diesem Kapitel eine permanente Verbindung (=Session) mit dem cmdlet "new-pssession" auf.
Eine permanente Session kann zwei Vorteile bringen:

a) möchte man die Verbindung mehrfach nutzen, so braucht die notwendige Session nur einmal aufgebaut werden, was einen spürbaren Performancegewinn bringt
b) Die Variablen auf dem Remoterechner bleiben nach Abarbeiten des "invoke-command" erhalten und können abgefragt und ausserhalb der Session weiterverarbeitet werden. (siehe das folgende Beispiel 1)


Beispiel 1: Abfrage eines Dienstes auf einem Remote Rechner

remove-pssession -computername dom2win701 -EA 0

$s = new-pssession -computername dom2win701
Invoke-Command -Session $s -ScriptBlock {$dhcp = get-service dhcp}
$DHCPStatus=Invoke-Command -Session $s -Scriptblock {$dhcp}
$DHCPStatus | select status

#Ausgabe
Status                                                                                                                                                                    
------                                                                                                                                                                    
Running   

Anmerkungen:

- Die erste Zeile "remove-pssession -computername dom2win701 -EA 0" setze ich, um vor der Ausführung alle eventuell bestehenden Sessions mit dom2win701 zu beenden. "-EA 0" entspricht der Errorvariablen "SilentlyContinue", die Fehlermeldungen unterdrückt, wenn keine Session besteht.

- mit "$s = new-pssession -computername dom2win701" wird eine neue Session etabliert und der Variablen $s zugewiesen

- würde statt "-Session $s" der Positionsparameter "-computername dom2win701" verwendet, bekäme die Variable $DHCPStatus keinen Wert zugewiesen

 

4.4. interactive Sessions

Man kann sich eine interactive remote Session auch komplett auf den lokalen Rechner holen. Dies ist vergleichbar mit Tools wie Telnet, psexec oder rcmd, die man früher benutzte. Die Powershell bietet mit ihren Möglichekeiten soviele Vorteile (siehe Kapitel 0), daß man sich langsam von diesen altgedienten Tools, sofern noch im Einsatz, verabschieden sollte.

Auch bei einer interactiven Verbindung sollte man den Unterschied zwischen einer temporären- und einer dauerhaften Verbindung kennen:
Eine einmal mit "new-psssession" aufgebaute dauerhafte Verbindung kann ich so oft betreten mit "enter-pssession" und verlassen mit "exit-pssession" wie ich möchte, die gespeicherten Variablen gehen nicht verloren.
Eine permanente Verbindungen sollte ordnungsgemäss mit "remove-pssession" beendet werden, da ein Remoterechner nur bis zu fünf dauerhafte Remoteverbindungen akzeptiert.

Bei einer temporären Verbindung (Aufbau und Beitritt nur mit "enter-pssession") sind nach dem Verlassen mit "exit-pssession" unwiederbringlich alle gespeicherten Variablen verloren. Dafür muss man sich nicht um das Beenden von Sessions mit "remove-pssession" kümmern.

 

4.4.1 temporäre interaktive Session

Eine temporäre, interaktive Session wird mit dem cmdlet "enter-pssession" gestartet und mit "exit-pssession" vollständig beendet.
Zwischen diesen beiden Befehlen kann man in der Session arbeiten, als säße man direkt vor an der Console des RemoteComputers.


Beispiel 1: Ablauf einer temporären, interactiven Session

Die Session wird mit enter-pssession -computername <name> gestartet. Sobald die Session remote läuft, erscheint der Name der Remoterechners, hier "dom2dc01", im Prompt

PS C:\> enter-pssession -computername dom2dc01                  #lokal
[dom2dc01]: PS C:\Users\Administrator\Documents> cd hkcu:  #ab hier remote
[dom2dc01]: PS HKCU:\> dir

    Hive: HKEY_CURRENT_USER

SKC  VC Name                           Property
---  -- ----                           --------
  2   0 AppEvents                      {}
  2  37 Console                        {ColorTable00, ColorTable01, ...}
 ...                          #gekürzt
  0   1 SessionInformation             {ProgramCount}
  1   9 Volatile Environment           {LOGONSERVER, USERDNSDOMAIN, USERDOMAIN, USERNAME...}

 

Beispiel 2: Beenden einer temporären, interactiven Session

Dieses Beispiel zeigt, daß mit "get-history" die letzten verwendeten Befehle einmal in der Remotesession und einmal in der lokalen Session an. Man sieht hier, daß die Sessions wirklich getrennt verwaltet werden.

[dom2dc01]: PS HKCU:\> get-history

  Id CommandLine
  -- -----------
   1 dir
   2 .\GetFreespace.ps1
 ...                      #gekürzt
  15 get-help about_preference_variables

[dom2dc01]: PS HKCU:\> exit-pssession

PS C:\> get-history

  Id CommandLine
  -- -----------
   1 enter-pssession -computername dom2dc01
...                            #gekürzt
   8 enter-pssession -computername dom2dc01

PS C:\> enter-pssession -computername dom2dc01
[dom2dc01]: PS C:\Users\Administrator\Documents> get-history
[dom2dc01]: PS C:\Users\Administrator\Documents>



Beispiel 3: Das cmdlet "get-history"

Das cmdlet "Get-History (Alias ghy)" speichert default die 64 letzten Befehle, zeigt aber nur die letzten 32 an. Alle 64 gespeicherten Commands bekommt man mit

Get-History 64 -count 64

 Technet: get-history

 

4.4.2 permanente interaktive Session

Eine permanente Session wird mit folgenden cmdlets verwaltet:

  •   new-pssession - Aufbau der Session
  •   enter-pssession - Betreten der Session
  •   exit-pssession - Verlassen der Session
  •   remove-pssession - Schliessen/ Beenden der Session
  •   get-pssession - Auflisten vorhandener Sessions

 
Beispiel 1: Aufbau und Anzeige mehrerer Remotesessions

new-pssession -computername dc1
new-pssession -computername dc1

get-pssession | fl State,Computername,InstanceID,ID,Name

State        : Opened
ComputerName : dc1
InstanceId   : 29a68db8-c0c5-4ffc-a11d-639db8ec4931
Id           : 7
Name         : Session7

State        : Opened
ComputerName : dc1
InstanceId   : af76680c-7842-44d5-8937-036cbc8a5b6a
Id           : 6
Name         : Session6

Mit
- enter-pssession -id 7
- enter-pssession -instanceid 29a68db8-c0c5-4ffc-a11d-639db8ec4931
- enter-pssession -name Session6
kann man jetzt dieser permanenten Remotession beitreten

Beispiel 2: Betreten und Verlassen einer Remotesession

PS C:\Powershell\MyScripts>enter-pssession -id 6
[dc1]: PS C:\Users\KarlNapf.DOM1\Documents> $b=hostname
[dc1]: PS C:\Users\KarlNapf.DOM1\Documents> exit-pssession
PS C:\Powershell\MyScripts>

Wir betreten hier die Session mit der ID 7, weisen dort der Variable $b den Rechnernamen (=hostname) zu und verlassen die Session wieder. Betreten wir später wieder dieselbe Session, so ist dort nachwievor die Variable $b noch vorhanden.


Beispiel 3: Beenden aller Sessions zu Computer dc1

remove-pssession -computername dc1

 

4.5 implizite RemoteSessions

Implizite Remotesessions sind wieder etwas, wo man einerseits über die genialen Ideen der Powershelldesigner staunt und sich andererseits über die Einfachheit der Umsetzung freut.

Mit einer impliziten Session bekommt man die cmdlets, die ein Remoterechner zur Verfügung hat, ohne Installation auf seiner lokalen Maschine zur Verfügung gestellt und kann damit lokal arbeiten. Öffnet man zum Beispiel die Powershell V2.0 auf einer Windows7 Maschine, so hat man ohne vorherigen Import des activedirectory-Moduls (siehe ActiveDirectory -> 2 Powershell und ActiveDirectory unter W2K8R2, Win7, W2K3) keinen Zugriff auf die AD-cmdlets.
Anstelle eines Modulimports kann man eine implizite Session zu einem Domaincontroller unter Windows2008-R2, auf dem das activedirectory-Modul default installiert ist, aufbauen und damit, ohne den Windows7 Client zu verändern, die AD-cmdlets des DCs nutzen.
Mit einer implizit Session kann man sogar in einer Windows2003/ XP Session, die cmdlets des Activedirectory-Modules verfügbar machen. In dem im Kapitel 4.5.2 aufgeführten Artikel von Don Jones wird dies beschrieben.

Mit Implicit Remoting lassen sich also Erweiterungen, die auf anderen Rechnern installiert sind, importieren. Beispiele sind Erweiterungen für Sharepoint,  HyperV von codeplex, dem  MSDN: Windows7 Ressource Kit Powershell Pack (siehe auch:  Lee Holmes: Introducing the Windows 7 Resource Kit PowerShell Pack) und andere. 

Wichtig für das Verständnis finde ich diesen beiden Punkte:
- Die Remote-cmdlets werden auf dem RemoteComputer ausgeführt, auch wenn sie wie lokale cmdlets benutzt werden können!
 - Umgekehrt zum Remoting über invoke-command oder über interactive Sessions wird bei Implicit RemoteSessions der lokale Rechner mit cmdlets des RermoteRechner gesteuert.


4.5.1 Import-PSSession

 Technet: Import-PSSession

Dieses Kapitel "4.5.1 Import-PSSession" und das nächste Kapitel "4.5.2 Export-PSSession" hören sich so an, als ob das eine cmdlet das Gegenteil des anderen wäre. Dem ist aber nicht so, sondern beide cmdlets führen eine unterschiedliche Umsetzung einer "Impliziten Session" durch.
Mit Import-Session werden temporär cmdlets vom RemoteComputer in die lokale Session importiert. Export-Session exportiert cmdlets des RemoteComputers zuerst in ein Module, welches im Filesystem gespeichert wird und das anschliessend über Import-Module in lokale Sessions importiert werden kann.


Beispiel 1: Import der Sharepoint-cmdlets in eine lokale Session

Das Beispiel zeigt, wie man die cmdlets aus einem SnapIn von einem Remoteserver verfügbar machen kann. Detaillierte Erklärungen zu den Befehlen folgen unter Beispiel 2.

$MySession = New-PSSession -ComputerName SharepointServer
Invoke-Command -Session $MySession -ScriptBlock {Add-PSSnapin Microsoft.SharePoint.PowerShell}          
Import-PSSession -Session $MySession -Prefix MyRemote

 
Beispiel 2: Import der ActiveDirectory-cmdlets in eine lokale Session

Dieses Beispiel zeigt den Import eines Modules

$MySession=new-pssession -computername dc1
invoke-command -session $MySession -scriptblock {import-module ActiveDirectory}
Import-Pssession -Session $MySession -module ActiveDirectory -Prefix MyRemote -Commandtype All

get-command New-MyRemote*
get-help Set-MyRemoteADUser

#Ausgabe von get-command New-MyRemote*

CommandType     Name                                                Definition
-----------     ----                                                ----------
Function        New-MyRemoteADComputer                                ...
Function        New-MyRemoteADFineGrainedPasswordPolicy               ...
Function        New-MyRemoteADGroup                                   ...
Function        New-MyRemoteADObject                                  ...
Function        New-MyRemoteeADOrganizationalUnit                      ...
Function        New-MyRemoteADServiceAccount                          ...
Function        New-MyRemoteADUser                                    ...


#Ausgabe von get-help Set-MyRemoteADUser (gekürzt)

NAME
    Set-ADUser

ÜBERSICHT
    Ändert einen Active Directory-Benutzer.

SYNTAX
    Set-ADUser [-Identity] <ADUser> [-AccountExpirationDate <System.Nullable[System.DateTime]>] [-AccountNotDelegated <
    System.Nullable[bool]>] [-Add <hashtable>] [-AllowReversiblePasswordEncryption <System.Nullable[bool]>] [-CannotCha

1) zu einem RemoteDomaincontroller mit new-pssession eine permanente Remotesession aufgebaut. 
2) In die Session auf dem Remoterechner wird das ActiveDirectory-Module dazugeladen, welches auf einem DC standardmässig installiert ist.
3) die RemoteSession wird auf den lokalen Rechner importiert

folgende Parameter sind bei 3) bei "import-pssession" interessant

-Session $MySession: gibt die zu importierende Session an

-Module -module: beschränkt die importierten cmdlets auf diese Module. Die Angabe ist sinnvoll, da sonst der Aufbau der impliziten Session unnötig lange dauert.

-Prefix Remote: Mit diesem Parameter können Sie potenzielle Namenskonflikte aufgrund unterschiedlicher Befehle mit identischem Namen in der Sitzung vermeiden. Wenn Sie beispielsweise das Präfix "Remote" angeben und anschließend das Cmdlet "Get-Date" importieren, wird da s Cmdlet in der Sitzung als Get-RemoteDate bezeichnet, und es wird nicht mit dem ursprünglichen Cmdlet "Get-Date" verwechselt. (aus der OnlineHilfe)

-AllowClubber: Importiert die angegebenen Befehle, auch wenn sie die gleichen Namen wie Befehle in der aktuellen Sitzung aufweisen.
Wenn Sie einen Befehl mit dem gleichen Namen wie ein Befehl in der aktuellen Sitzung importieren, werden die ursprünglichen Befehle vom importierten Befehl ausgeblendet oder ersetzt. Weitere Informationen finden Sie unter "about_Command_Precedence".
Standardmäßig werden mit Import-PSSession keine Befehle importiert, die die gleichen Namen wie Befehle in der aktuellen Sitzung aufweisen.
(aus der OnlineHilfe)

In dem Beispiel bekommen alle importierten cmdlets die Ergänzung (-prefix) "MyRemote" vor das Hauptwort "New-ADGroup" wird als "New-MyRemoteADGroup" importiert.
cmdlets deren Namen bereits auf der lokalen Maschine existieren, werden nicht importiert (-Allowclubber ist nicht gesetzt)

- Alle importierten cmdlets werden auf dem RemoteRechner ausgeführt.


Beispiele 3: Import eines Modules aus dem Powershellpack des Windows7 ResourceKits

Das Powershellpack kann kostenlos von der MSDN heruntergeladen und aus dem msi-File installiert werden. Die Installation wirft allerdings einige Fehlermeldungen aus ("falscher Bezeichner"). Trotzdem funktionieren, soweit ich das beurteilen kann, die bereitgestellten Module.

Beispiel 3a: die cmdlets des Modules "TaskScheduler" auf einer lokalen Maschine auflisten

Bevor man ans Importieren von cmdlets geht, sollte man einmal an der Konsole der Remotemaschine überprüfen, ob der Modulimport  funktioniert und die cmdlets verfügbar sind.

import-module taskscheduler
get-command -module taskscheduler -verb *

#Ausgabe

CommandType     Name
-----------     ----
Function        Add-TaskAction
Function        Add-TaskTrigger
Function        Connect-ToTaskScheduler
Function        Get-RunningTask
Function        Get-ScheduledTask
Function        New-Task
Function        Register-ScheduledTask
Function        Remove-Task
Function        Start-Task
Function        Stop-Task

 
Beispiel 3b: Importieren der cmdlets des Modules "TaskScheduler" aus einer RemoteMaschine

$MySession = New-PSSession -ComputerName dom1win7
Invoke-Command -Session $MySession -ScriptBlock {import-module taskscheduler}
Import-Pssession -Session $MySession -module taskscheduler -Prefix MyRemote -Commandtype All

get-command *MyRemote*

#Ausgabe gekürzt

CommandType     Name                                                Definition
-----------     ----                                                ----------
Function        Add-MyRemoteTaskAction                              ...
Function        Add-MyRemoteTaskTrigger                             ...
Function        Connect-MyRemoteToTaskScheduler                     ...
...

- Alle importierten cmdlets erhalten vor dem Verb den im Positionsparamater Prefix angegebenen Zusatz "MyRemote".
- Mit "Commandtype All" werden alle Typen von Befehlsobjekten importiert. Man kann die Befehlsobjekte auch beschränken mit "Commandtype cmdlet" oder "Commandtype Alias"

Das cmdlet Import-PSSession enthält noch einige Positionsparameter mehr, mit denen sich ganz genau die importierenden cmdlets definieren lassen. Diese Parameter sind in der onlinehilfe oder in dem am Anfang des Kapitels angegebenen Technetlink nachschlagbar.


Beispiel 3c: Arbeiten mit dem importierten cmdlet "start-task"

get-help start-MyRemoteTask

#Ausgabe
NAME
    Start-Task

ÜBERSICHT
    Starts a scheduled task

SYNTAX
    Start-Task [<CommonParameters>]

BESCHREIBUNG
    Starts running a scheduled task.
    The input to the command is the output of Get-ScheduledTask.

 Das Look-and Feel der importierten cmdlets lässt vielleicht vergessen, daß die Befehle auf dem Remoterechner abgearbeitet werden und dessen Ressourcen beanspruchen.

4.5.2 Export-PSSession

 Don Jones im TechNet Magazine:  Implicit Remoting

 Technet: Export-PSSession


Beispiel 1: Import eines Modules aus dem Powershellpack des Windows7 ResourceKits

Auch in diesem Beispiel benutze ich ein das Modul Taskscheduler aus dem Windows7 ResourceKit  MSDN: Windows7 Ressource Kit Powershell Pack, welches nur auf dem Remoterechner installiert ist und dessen Befehle auf dem lokalen Rechner verfügbar gemacht werden sollen.
(vergleiche auch Beispiel 3 im Kapitel 4.5.1 Import-PSSession)


Beispiel 1a: Importieren der cmdlets des Modules "TaskScheduler" aus einer RemoteMaschine

$MySession = New-PSSession -computerName dom1win7
invoke-command -session $MySession -Scriptblock {import-module taskscheduler}
Import-Pssession -Session $MySession -module taskscheduler -Prefix MyRemote -Commandtype All

#Ausgabe

ModuleType Name                      ExportedCommands
---------- ----                      ----------------
Script     tmp_551bf780-ec1e-4ad7... {Remove-Task, Get-ScheduledTask, Stop-Task, Add-TaskTrigger...}

 

#Anzeige der importierten cmdlets

get-command -module taskscheduler -verb *
#oder
get-command *myremote*

#Ausgabe

CommandType     Name                                                Definition
-----------     ----                                                ----------
Function        Add-MyRemoteTaskAction                              ...
Function        Add-MyRemoteTaskTrigger                             ...
Function        Connect-MyRemoteToTaskScheduler                     ...
Function        Get-MyRemoteRunningTask                             ...
Function        Get-MyRemoteScheduledTask                           ...
Function        New-MyRemoteTask                                    ...
Function        Register-MyRemoteScheduledTask                      ...
Function        Remove-MyRemoteTask                                 ...
Function        Start-MyRemoteTask                                  ...
Function        Stop-MyRemoteTask                                   ...

 

Beispiel 1b) Exportieren der Taskscheduler-cmdlets in ein Module

Export-PSSession -session $session -commandname *-Task* -outputmodule RemTask -allowclobber

#Ausgabe

    Verzeichnis: C:\Users\blub.DOM1\Documents\WindowsPowerShell\Modules\RemTask


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        09.02.2011     15:46      20636 RemTask.psm1
-a---        09.02.2011     15:46         99 RemTask.format.ps1xml
-a---        09.02.2011     15:46        587 RemTask.psd1

Unter dem Pfad "C:\Users\blub.DOM1\Documents\WindowsPowerShell\Modules\RemTask" wird das neu erstellte Module gespeichert

09.02.2011  15:46                99 RemTask.format.ps1xml
09.02.2011  15:46               587 RemTask.psd1
09.02.2011  15:46            20.636 RemTask.psm1
               3 Datei(en),         21.322 Bytes


Beispiel 1c) Importieren der Taskscheduler-cmdlets in eine lokale PowershellSession

Remove-PSSession -session $session #genauso kann man eine neue PS-Sitzung starten
Import-Module RemTask -prefix myTask
get-command *myTask* #Anzeige der importierten Sessions

#Ausgabe

PS C:\Users\blub.DOM1> get-command *mytask*

CommandType     Name                                                Definition
-----------     ----                                                ----------
Function        Add-myTaskTaskAction                                ...
Function        Add-myTaskTaskTrigger                               ...
Function        New-myTaskTask                                      ...
Function        Remove-myTaskTask                                   ...
Function        Start-myTaskTask                                    ...
Function        Stop-myTaskTask                                     ...



Beispiel 2: Erneutes Laden eines Moduls
In einer neuen Powershellsession auf dem Rechner, auf dem im letzten Beispiel unter "C:\Users\blub.DOM1\Documents\WindowsPowerShell\Modules\RemTask" das Modul RemTask abgelegt wurde, kann man sich das Modul ganz leicht erneut importieren

Import-Module RemTask -prefix myTask
get-command *mytask*

#Ausgabe

CommandType     Name                                                Definition
-----------     ----                                                ----------
Function        Add-myTaskTaskAction                                ...
Function        Add-myTaskTaskTrigger                               ...
Function        New-myTaskTask                                      ...

Das in Beispiel 1 erstellte Module "RemTask" enthält keine Kopien von cmdlets aus dem Module Taskscheduler am Remoterechner, sondern nur eine Art Links auf diese cmdlets
(siehe den Artikel von Don Jones)

The cmdlets aren’t actually copied to your local computer. Instead, the locally created module serves as a kind of shortcut. The cmdlets will always be executed on the remote domain controller, but the cmdlets will seem to be running locally.



5 Troubleshooting

siehe auch:  Technet: about_Remote_Troubleshooting

Vor einer Überprüfung der Verbindung kann man versuchen eine Remoteverbindung (siehe 3.1.6 eine Remotesession mit "new-pssession <Clientname> -usessl" erstellen) herzustellen. Wenn dies funktioniert, kann man sich dieses Kapitel natürlich sparen.

Kommt keine Remoteverbindung zustande, so kann dies mehrere Ursachen haben

5.1 Problem mit dem WinRM-Dienst

5.2 Problem mit der Firewall

5.3 Problem mit dem SSL-Zertifikat

5.4 Problem mit der Sessionkonfiguration

5.5 Prüfen des WS-Man

 

5.1 Problem mit dem WinRM-Dienst

Um die Konfiguration am remoteRechner zu überprüfen, gibt es eine ganze Reihe von Möglichkeiten.


Beispiel 1: Schnelltest am RemoteRechner, ob Remoting enabled ist.

Enter-PSSession -ComputerName localhost

PS C:\Powershell\MyScripts> enter-pssession -computername localhost
[localhost]: PS C:\Users\blub.DOM1\Documents>

Wenn Remoting aktiviert ist und funktioniert, sollte etwa diese Ausgabe erscheinen.

Beispiel 2: Fehlermeldung am lokalen Rechner, wenn der WinRM-Port nicht offen oder kein passender Listener konfiguriert ist

new-pssession dom1win7.dom1.intern -usessl

[dom1win7.dom1.intern] Beim Verbinden mit dem Remoteserver ist folgender Fehler aufgetreten: Der WinRM-Client kann den
Vorgang innerhalb der angegebenen Zeit nicht abschließen. Überprüfen Sie, ob der Computername gültig, der Computer über
 das Netzwerk erreichbar und eine Firewallausnahme für den Windows-Remoteverwaltungsdienst aktiviert ist. Weitere Infor
mationen finden Sie im Hilfethema "about_Remote_Troubleshooting".


Beispiel 3: Anzeige der WinRM-Konfiguration
Ausführen mit Administratorrechten

winrm get winrm/config  
#oder
Winrm get schemas.microsoft.com/wbem/wsman/1/config

#Ausgabe
Config
    MaxEnvelopeSizekb = 150
    MaxTimeoutms = 60000
    MaxBatchItems = 32000
    MaxProviderRequests = 4294967295
    Client
        NetworkDelayms = 5000
        URLPrefix = wsman
        AllowUnencrypted = false
        Auth
            Basic = true
            Digest = true
            Kerberos = true
            Negotiate = true
            Certificate = true
            CredSSP = false
        DefaultPorts
            HTTP = 5985
            HTTPS = 5986
        TrustedHosts = *
    Service
        RootSDDL = O:NSG:BAD:P(A;;GA;;;BA)S:P(AU;FA;GA;;;WD)(AU;SA;GWGX;;;WD)
        MaxConcurrentOperations = 4294967295
        MaxConcurrentOperationsPerUser = 15
        EnumerationTimeoutms = 60000
        MaxConnections = 25
        MaxPacketRetrievalTimeSeconds = 120
        AllowUnencrypted = false
        Auth
            Basic = false
            Kerberos = true
            Negotiate = true
            Certificate = false
            CredSSP = false
            CbtHardeningLevel = Relaxed
        DefaultPorts
            HTTP = 5985
            HTTPS = 5986
        IPv4Filter = *
        IPv6Filter = *
        EnableCompatibilityHttpListener = false
        EnableCompatibilityHttpsListener = false
        CertificateThumbprint = 46 17 1c 53 ea a7 b7 a7  f6 de d7 e2 bc e9 fd 2f85 2c 4c 12
    Winrs
        AllowRemoteShellAccess = true
        IdleTimeout = 180000
        MaxConcurrentUsers = 5
        MaxShellRunTime = 2147483647
        MaxProcessesPerShell = 15
        MaxMemoryPerShellMB = 150
        MaxShellsPerUser = 5

 

Beispiel 4: Abfrage der Listenerkonfiguration
Diese Prüfung finde ich persönlich am übersichtlichsten. In den Zeilen, die mit "Listener" beginnen, kann man erkennen, ob die Konfiguration über GPO oder über lokale cmdlets (dann gibt es keine weiteren Angaben) durchgeführt wurde.

winrm enumerate winrm/config/listener

Listener [Source="GPO"]
    Address = *
    Transport = HTTP
    Port = 5985
    Hostname
    Enabled = true
    URLPrefix = wsman
    CertificateThumbprint
    ListeningOn = 4.11.129.127, 127.0.0.1, ::1, 2002:2c6:817f::2c6:817f, fe80::200:5efe:4.11.129.127%12

Listener [Source="Compatibility"]
    Address = *
    Transport = HTTP
    Port = 80
    Hostname
    Enabled = true
    URLPrefix = wsman
    CertificateThumbprint
    ListeningOn = 4.11.129.127, 127.0.0.1, ::1, 2002:2c6:817f::2c6:817f, fe80::200:5efe:4.11.129.127%12

Listener [Source="Compatibility"]
    Address = *
    Transport = HTTPS
    Port = 443
    Hostname = Dom1Win7.Dom1.intern
    Enabled = true
    URLPrefix = wsman
    CertificateThumbprint = 46 17 1c 53 ea a7 b7 a7  f6 de d7 e2 bc e9 fd 2f85 2c 4c 12
    ListeningOn = 4.11.129.127, 127.0.0.1, ::1, 2002:2c6:817f::2c6:817f, fe80::200:5efe:4.11.129.127%12

 

Wenn der Listener lokal mit "enable-psremoting" oder "set-wsmanquickconfig" konfiguriert ist, kann man sich diese Einstellungen auch in der lokalen Registry betrachten. (siehe Kapitel 1.2.1)

 

5.2 Problem mit der Firewall

Zur Kontrolle der physikalischen Netzverbindung benütze ich den kostenlosen Portscanner von Microsoft, erhältlich im  Micorosoft Download Center: PortqueryV2

Nach dem Entpacken kann man dieses Tool ohne Installation in der Commandline (nicht in Powershell!) aufrufen und mit

portqry -n dom1win7.dom1.intern -e 5985
portqry -n dom1win7.dom1.intern -e 5986

#Ausgabe

....
TCP port 5985 (unknown service): LISTENING

...
TCP port 5986 (unknown service): NOT LISTENING

prüfen, ob die Verbindung offen ist. Wenn die Listener am Zielsystem konfiguriert sind, müssen die Portquery-Befehle ein "Listening" zurückliefern.

Liefern die Befehle "Filtered" zurück, ist die Verbindung auf diesen Ports blockiert. Wenn sich zwischen lokalem und RemoteRechner keine weitere Firewall befindet, hilft es wahrscheinlich, die Windowsfirewall beispielsweise über die Grouppolicy "Windows Firewall mit erweiterter Sicherheit" mit einer eigenen Regel für die Ports 5985 und 5986 zu öffnen.

Anstelle des MS-Tools portqry.exe kann man auch das Tool SimpleTCPCheck.exe verwenden, das ich in VB geschrieben habe. Downloaden inklusive Quellcode kann man es im  hier im MCSEBoard. Der Vorteil liegt in der einfachen Bedienbarkeit, der kurzen Ausgabe und der Möglichkeit mehrere Ports auf einmal zu prüfen.

SimpleTCPCheck 192.168.178.100 5985 5986

#Ausgabe
110

die erste 1 oder 0 bedeutet, ob der Client per ICMP (Ping) erreichbar ist, die übrigen 0-er und 1-er zeigen an, ob die Ports erreichbar sind.

5.3 Problem mit dem SSL-Zertifikat

Ein Zertifikatsproblem kann zum Beispiel vorliegen, wenn

- keine Sperrlisteninformationen abgefragt werden können (häufigste Ursache)
- das Zertifikate gesperrt wurde
- das Zertifikat abgelaufen oder ungültig ist
- Probleme mit der Zertifikatskette vorliegen

Diese Faktoren lassen sich am besten über das CommandlineTool certutil überprüfen.

Weiter kann es auch sein, daß das Zertifikat nicht die notwendigen Eigenschaften enthält, um für eine SSL-Verbindung genutzt werden zu können.

Der erste Schritt ist das von "Set-WsManQuickConfig -usessl" verwendete Zertifikat zu identifizieren. Dazu dient der eindeutige Fingerabdruck "Thumbprint" eines jeden Zertifikakts.
Mit den Befehlen aus Kapitel 5.1 weiter oben, oder bei lokaler Konfiguration auch direkt aus der Registry Kapitel 1.2.1 [Beispiel 3], kann der verwendete Fingerabdruck bestimmt werden.

Der zweite Schritt besteht darin, die auf dem Rechner vorhandenen Zertifikate zu öffnen und dasjenige Zertifikat mit dem passenden Fingerabdruck zu identifizieren. In den Kapiteln 3.2.3 Zertifikat beantragen und 3.2.4 Untersuchen des Zertifikats habe ich dies beschrieben.

Hat man das richtige Zertifikat gefunden, so muss als Letztes das Zertifikat mittels rechter Maustaste -> "alle Aufgaben" -> "Exportieren" in eine Datei ssl.cer gespeichert werden (ohne private Schlüssel, im Base64 Format).


Auf Kommandline(!) erfolgt die Prüfung jetzt durch

certutil -verify c:\temp\ssl.cer

#Ausgabe gekürzt

Aussteller:
    CN=Dom1-CA01
    DC=Dom1
    DC=intern
Antragsteller:
    CN=Dom1Win7.Dom1.intern
Zertifikatseriennummer: 19dae87d000000000035

dwFlags = CA_VERIFY_FLAGS_CONSOLE_TRACE (0x20000000)
dwFlags = CA_VERIFY_FLAGS_DUMP_CHAIN (0x40000000)
ChainFlags = CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT (0x40000000)
HCCE_LOCAL_MACHINE
CERT_CHAIN_POLICY_BASE
-------- CERT_CHAIN_CONTEXT --------
ChainContext.dwInfoStatus = CERT_TRUST_HAS_PREFERRED_ISSUER (0x100)
ChainContext.dwRevocationFreshnessTime: 1 Days, 58 Minutes, 17 Seconds

SimpleChain.dwInfoStatus = CERT_TRUST_HAS_PREFERRED_ISSUER (0x100)
SimpleChain.dwRevocationFreshnessTime: 1 Days, 58 Minutes, 17 Seconds
.....

Exclude leaf cert:
  8f 7a 51 25 c8 b6 74 f9 b6 1a 07 f2 41 08 2b 02 36 15 89 66
Full chain:
  a4 28 4a 2d 5f 24 d7 87 a5 21 e3 16 0d 11 e5 0b 07 a0 ff cf
------------------------------------
Verfizierte Ausstellungsrichtlinien: Kein
Verfizierte Anwendungsrichtlinien:
    1.3.6.1.5.5.7.3.1 Serverauthentifizierung
    1.3.6.1.5.5.7.3.2 Clientauthentifizierung
Sperrstatussüberprüfung des untergeordneten Zertifikats erfolgreich abgeschlosse
n.
CertUtil: -verify-Befehl wurde erfolgreich ausgeführt.

das Ergebnis sollte etwa so aussehen und keine Fehler enthalten.


Treten Fehler auf, die man auf die Schnelle nicht beheben kann, so lassen sich Prüfungen wie der CRL-Check oder die Rootzertifikatsprüfung über Optionen des cmdlets New_WSManSessionOption unterdrücken: siehe  Technet: New-WSManSessionOption

 

5.4 Problem mit der Sessionkonfiguration (Zugriff verweigert)

Erscheint beim Erstellen einer Remoteverbindung diese Fehlermeldung 

new-pssession dom1win7.dom1.intern

[dom1win7.dom1.intern] Beim Verbinden mit dem Remoteserver ist folgender Fehler aufgetreten: Zugriff verweigert

so fehlen Berechtigungen auf einer Sessionkonfiguration. Diese können beispielsweise mit "Enable-PsRemoting" gesetzt werden. Die Ursache war eventuell ein "Disable-PsRemoting".
Manchmal benötigt der betroffene Rechner bei '"Zugriff verweigert" auch einen Reboot, insbesondere wenn "Enable-PsRemoting" selbst die Fehlermeldung bringt.

 

5.5. Prüfen des WS-Man

Beispiel 1: cmdlet Test-WsMan

test-wsman

#Ausgabe

wsmid           : schemas.dmtf.org/wbem/wsman/identity/1/wsmanidentity.xsd
ProtocolVersion : schemas.dmtf.org/wbem/wsman/1/wsman.xsd
ProductVendor   : Microsoft Corporation
ProductVersion  : OS: 0.0.0 SP: 0.0 Stack: 2.0

Die Eigenschaft ProductVersion sieht auf den ersten Blick fehlerhaft aus, scheint aber so zu stimmen.

Ich hatte bisher mit dem WsMan noch keine Probleme.

5.6 Module psdiagnostics


Beispiel 1: Functionen des Moduls psdiagnostics anzeigen

Import-Module psdiagnostics
get-command -module psdiagnostics -verb *

#Ausgabe

CommandType     Name
-----------     ----
Function        Disable-PSTrace
Function        Disable-PSWSManCombinedTrace
Function        Disable-WSManTrace
Function        Enable-PSTrace    
Function        Enable-PSWSManCombinedTrace
Function        Enable-WSManTrace
Function        Get-LogProperties
Function        Set-LogProperties
Function        Start-Trace
Function        Stop-Trace

Es wird beispielsweise unter %windir%\system32\wsmtraces.log nach "Enable-WSManTrace" ein Log geschrieben. Leider war dieses Log für mich nicht lesbar.
Wenn jemand eine Quelle zur Auswertung der Logs kennt, würde mich das sehr interessieren.