Exchange Powershell aus der Ferne nutzen
Powershell ist nicht nur lokal eine immense Verbesserung für Administratoren sondern enthält auch leistungsfähige Möglichkeiten zur Fernausführung. Quasi das, was früher per PSEXE oder RCMD genutzt wurde ist mit WinRM und Powershell nun auch Remote möglich. Aber oft sind die Tücken im Detail und diese Seite soll zeigen, wie eine Verbindung von einem Client mit Powershell zum Exchange Management System erfolgen kann und welche Fallstricke dabei zu umgehen sind.
WinRM ist quasi der Nachfolger von COM, DCOM und anderen Wege, aus der Ferne ein System zu verwalten. Auch die Powershell nutzt "WinRM" als Transport, wenn man ihr nichts anderes vorschreibt. Details zu WinRM finden Sie auf WinRM.
eBook Update: Layman’s guide to PowerShell 2.0
remoting
http://www.ravichaganti.com/blog/?p=1780
Sehr lesenswertes eBook zu Powershell und remote
IIS-Verzeichnis "/Powershell"
Durch die Installation von Exchange 2010 tut sich aber noch ein neuer Weg auf. In der Default Webseite des mit installierten IIS landen neben den virtuellen Verzeichnissen für die CAS-Rolle auch ein Verzeichnis "/Powershell", welches von Anwendern so gar nicht angesprochen wird. Dieses Verzeichnis und komplett getrennt von den Exchange Web Services (MSXFAQ.DE - EWS) zu sehen, welche primär einen Zugriff in die Daten von Exchange erlauben.

Wie der IIS-Manager offenbart, gehört "/Powershell" zu Exchange und nicht zu WinRM oder der Powershell als solches. Entsprechend funktionieren die folgenden Beschreibungen nur, wenn der Server ein Exchange 2010 Server ist. Dass Exchange dieses virtuelle Verzeichnis selbst nutzt, können Sie einfach im IISLog kontrollieren. Dort sehen Sie beim Aufruf der Exchange Powershell entsprechende Treffer. (Logdatei gekürzt und Zeilenumbruch addiert)
#Software: Microsoft Internet Information Services 7.5
#Version: 1.0
#Date: 2011-04-07 00:00:19
#Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) sc-status sc-substatus sc-win32-status time-taken
2011-04-07 08:09:43 ip POST /PowerShell PSVersion=2.0 80 - ip Microsoft+WinRM+Client 200 0 0 0
2011-04-07 08:09:43 ip POST /PowerShell PSVersion=2.0 80 NETATWORK\adm-scink ip Microsoft+WinRM+Client 200 0 0 46
2011-04-07 08:09:44 ip POST /PowerShell serializationLevel=Full;clientApplication=EMC; ExchClientVer=14.1.218.15;PSVersion=2.0 80 - ip Microsoft+WinRM+Client 200 0 0 0
2011-04-07 08:09:44 ip POST /PowerShell serializationLevel=Full;clientApplication=EMC; ExchClientVer=14.1.218.15;PSVersion=2.0 80 NETATWORK\adm ip Microsoft+WinRM+Client 200 0 0 15
2011-04-07 08:09:44 ip POST /PowerShell serializationLevel=Full;clientApplication=EMC; ExchClientVer=14.1.218.15;PSVersion=2.0 80 NETATWORK\adm ip Microsoft+WinRM+Client 200 0 0 499
Sie können auch sehen, dass die Exchange Powershell bzw. genauer das Exchange Powershell PSSnapin diesen Weg beschreitet.

Auch diese erste "Verbindung" wird im IIS schon mit geloggt.
Externer Zugriff
Interessant wird die Funktion nun, wenn der Exchange Server per HTTPS von "überall" erreichbar ist und mit entsprechenden Credentials können Sie also einfach eine "Powershell" nutzen, ohne auf dem PC irgendwelche Zusatzprogramme installiert zu haben, d.h. ein Windows XP PC mit Powershell 2.0 reicht aus, um zumindest per Exchange Commandlets dann Exchange zu verwalten. Die GUI haben Sie dabei natürlich nichts installiert.
Dieser Weg ist aber auch interessant, wenn andere Programme, z.B. Provisioning-Systeme wie MIIS,ILM, FIM, DirX, DirXML, SunIDM und andere aus der Ferne die Exchange Konfiguration verändern wollen, aber auf dem Server selbst keine Exchange Powershell installiert werden soll bzw. kann.
Damit das ganze aber funktioniert, muss erst mal die Berechtigung auf dem virtuellen Verzeichnis aktiviert werden. Standardmäßig ist nämlich keine Authentifizierung aktiviert.

Das ist so aber nicht ganz richtig, da der IIS schon eine "Native Authentication" nutzt, die Sie unter den "Modulen" finden:

Insofern bedeutet, dass alle Authentifizierungsmodule auf "disabled" stehen, dass der IIS selbst keine Authentifizierung vornimmt. Aber Das Modul greift hie schon vorher ein und kann unabhängig von einer nicht weiter erforderlichen nachgeschalteten IIS-Authentifizierung arbeiten. Das funktioniert aber nur innerhalb des gleichen Forest mit Benutzern im Forest, da diese Kerberos-Funktion nicht über Trusts oder für explizite Anmeldedaten geeignet ist.
Für eine Anmeldung unter Angabe von Benutzername und Kennwort müssen die anderen Authentifizierungsverfahren aktiviert werden. Sobald Sie die "Windows Authentication" aktiviert haben, können Sie sich schon per Kerberos oder NTLM anmelden. Das kann können Sie zwar über die IIS Verwaltung machen, aber der korrekte Weg ist die Exchange Powershell. Schließlich ist auch dies ein Exchange virtuelles Verzeichnis und sie können nie sicher sein, dass diese Einstellung nicht dort irgendwann von Exchange aus einem anderen Datenbestand repliziert wird.
Get-PowerShellVirtualDirectory | Set-PowerShellVirtualDirectory -WindowsAuthentication $true
Letztlich können Sie im IIS die Änderung der Powershell genauso kontrollieren.
- Set-PowerShellVirtualDirectory
http://technet.microsoft.com/en-us/library/dd298108.aspx
Wenn Sie aber auch die "Basic Authentication" aktivieren wollen, dann sollten Sie unbedingt den Zugriff per SSL erzwingen, damit die Anmeldedaten ausreichend geschützt sind.
Rechte für Benutzer
In all meinen Exchange 2010 Umgebungen waren alle Benutzer auch für den zugriff per Remote Powershell aktiviert. Natürlich können Sie nur die Funktionen ausführen, die ihnen über ihre Rollen (Siehe RBAC) zugänglich sind. Aber falls der Zugriff nicht möglich sein sollte, dann prüfen Sie die aktuelle Einstellung einfach mal mit einem:
[PS] C:\>Get-User | ft name, *power*
Name RemotePowerShellEnabled
---- -----------------------
Administrator True
Guest True
krbtgt True
DiscoverySearchMailbox {D919BA05-46A6-415f-80AD-7E09334B... True
mailuser True
mailboxuser True
Archiv User True
Bad User True
Sales1 True
user1 True
user2 True
W2003$ True
Sollte die Funktion wider Erwarten nicht aktiv sein, dann ist sie schnell gesetzt
Set-User username -RemotePowerShellEnabled $True
- Steuern des Benutzerzugriffs auf die
Windows-Remoteverwaltung
http://help.outlook.com/de-de/140/dd256962.aspx - Troubleshooting Exchange 2010 Management Tools
startup issues
http://blogs.technet.com/b/exchange/archive/2010/02/04/3409289.aspx - User.RemotePowerShellEnabled Property
http://msdn.microsoft.com/en-us/library/microsoft.exchange.data.directory.management.user.remotepowershellenabled%28v=exchg.140%29.aspx
SSL und Zertifikate
Auch wenn sie die Anmeldung "eigentlich" mit einem sicheren Kennwortverfahren (NTLM2, Kerberos) absichern, so könnte jemand doch die HTTP-Nutzdaten mitlesen und Rückschlüsse auf Mailadresse, Benutzernamen etc. erhalten. Auch die Verwendung von "Basic" als Anmeldeverfahren ist manchmal erforderlich, weil Proxies vielleicht nicht die NTLM-Anmeldung unterstützen. Die Installation eines Zertifikats erfolgt, wie Sie es von IIS kennen.
-
IIS Zertifikat einrichten
Mit wenigen Schritten erweitern Sie ihren Webserver um die Fähigkeit, verschlüsselte Verbindungen zu akzeptieren -
E2K7: Zertifikate
So richten Sie Zertifikate für den Einsatz von SSL ein.
Aber auch hier müssen Sie natürlich dafür sorgen, das die Clients das Zertifikat auch akzeptieren. Dazu zählen die vier Grundtugenden:
- Name Im Zertifikate (Antragsteller bzw. SAN-Namen)
- Gültigkeitszeitrum
- Vertrauen der Ausstellende CA
- Zwischenzertifizierungsstellen
- CRL
Allerdings können Sie über einen kleinen Trick natürlich die strengen Prüfungen zumindest temporär abschalten.
Dies kann durchaus für Tests und für Fehlersuche ratsam sein um Fehler bei den Zertifikaten zu ignorieren und andere Fehler zu finden. Eine Dauerlösung darf dies natürlich nicht sein.
Sie müssen dazu einmal eine PSSessionOption mit den entsprechenden Einstellungen generieren
$SkipCertificate = New-PSSessionOption `
-SkipCACheck `
-SkipCNCheck '
-SkipRevocationCheck
Diese Option geben Sie dann als "SessionOption" beim New-PSSession an.
Authentifizierung
Wenn Sie dann die PSSession aufbauen, dann müssen Sie natürlich Anmeldedaten mitgeben. Wenn Sie die explizite Angabe weglassen, dann nutzt das Commandlet einfach die lokalen Credentials. Das funktioniert natürlich nur, wenn ihr PC im gleichen Forest ist und der lokal angemeldete Benutzer sowieso entsprechende berechtigt ist. Ansonsten müssen Sie natürlich die Anmeldedaten mit angeben. Das Ganze funktioniert natürlich über Get-Credential. Allerdings ist es in Skripten immer besser, das Kennwort nicht mit in den Skriptcode zu lesen. Wenn man es schon nicht eingeben will, dann sollte das Kennwort verschlüsselt in einer eigenen Datei liegen, welche dann nachgeladen wird. Das hat auch den Vorteil, dass bei einer Kennwortänderung nicht das Skript geändert werden muss.
Sicher ist dies natürlich auch, wenn auf die Kennwortdatei nicht von unautorisierten Personen zugegriffen kann.
Technisch könnte das so aussehen. Mit einem Einzeiler können Sie das Kennwort verdeckt eingeben und in einer Datei speichern
read-host -assecurestring | convertfrom-securestring | out-file .\kennwort.txt
Das Kennwort können Sie dann im Skript selbst wieder nachladen mit:
$user = "domain\username" $pass = (get-content -path $passwordfile | convertto-securestring) $cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $user,$pass
Bei Einsatz von New-PSSession werden die Credentials dann mit der Option "-credential" angegeben. Das ist aber noch nicht alles, denn der Parameter "-Authentication" bestimmt, wie die Anmeldung an weiter gegeben wird. Möglich ist hier eine Option aus einer Auswahl:
| Wert | Beschreibung |
|---|---|
| Default | Das eingestellte Standardverfahren wird verwenden |
| Basic | Anmeldedaten werden BASE64-codiert übertragen. Kompatibelste Form aber ohne SSL denkbar unsicher. |
| Negotiate | Client und Server "handeln" das Verfahren aus. Dies ist aber meines Wissens auf Windows Verfahren (also die verschiedenen NTLM-Optionen und Kerberos beschränkt) |
| NegotiateWithImplicitCredential | |
| Credssp | Verfahren um Client Credentials an den Server zu übergeben (Windows XPSP3 oder höher erforderlich |
| Digest | Verfahren zur sicheren Übertragung des Kennworts (Verschlüsselung mit MD5) über eine unsichere Verbindung. |
| Kerberos | Damit ist eine explizite Anmeldung per Kerberos erforderlich. |
Wie bei jeder HTTP-Verbindung auch versucht der Client natürlich einen anonymen Zugriff um dann über die erste 401-Fehlermeldung des Webservers zu erfahren, welche Anmeldeverfahren der Webserver anbietet. Hier muss es natürlich eine Übereinstimmung geben.
In der Praxis versuche ich immer den Einsatz von "Negotiate". Kerberos funktioniert nicht, wenn der Client nicht in der der Zieldomäne selbst ist oder ein Foresttrust vorhanden ist. Basic ist der Fallback, wenngleich ich dann schon auf dem Server SSL erzwinge.
Sehr große Umgebungen und Limit auf 524288000
Niemand würde einen Webservice einfach so im Internet bereit stellen. Daher hat auch Exchange "Obergrenzen", die nicht überschritten werden dürften. Dazu gehört z.B. die maximale Buffergröße für Anfragen und Antworten. Wer also mit einem "Ret-Recipient" viele tausend Empfänger abruft, kann spätestens beim PIPE zum nächsten Befehl auf einen Fehler stoßen:
C:>get-recipient -resultsize unlimited | update-recipient
Sending data to a remote command failed with the following error message: The total data received from the remote clien
t exceeded allowed maximum. Allowed maximum is 524288000. For more information, see the about_Remote_Troubleshooting He
lp topic.
+ CategoryInfo : OperationStopped: (System.Manageme...pressionSyncJob:PSInvokeExpressionSyncJob) [], PSRe
motingTransportException
+ FullyQualifiedErrorId : JobFailure
Sie sehen schon, dass "-Resultsize unlimited" schon mal die Grenze von 1000 Objekten auflösen muss, damit es überhaupt so weit kommen kann. Die Lösung ist natürlich einfach: sie können den Aufruf natürlich in kleinere Pakete aufsplittern. Zuverlässiger ist aber die Trennung über eine FOR-Schleife:
$recipients = get-recipient -resultsize
unlimited
Foreach ($recipient in $recipients) {
Update-recipient -identity $recipient
}
Zuerst werden also die Daten in eine Variable geladen und erst dann einzeln als Anfragen wieder abgesetzt. Damit umgehen Sie eine weitere Problematik der Pipeline.
Proxy-Server auf dem Weg
Nun kann es natürlich sein, dass der Client die Gegenstelle, also den IIS, gar nicht direkt erreicht. HTTP und HTTPS sind ja Protokolle, die gerne über Proxy Server geleitet werden. Das kann auf der Clientseite ein Proxy sein, der den Zugriff in das Internet überhaupt erst zulässt und hierbei natürlich eine Authentifizierung erwartet. Für diesen Zugriff müssten Sie dann über die PSSessionOption konfigurieren und beim herstellen der Session angeben.
$PSSessionOptions = New-PSSessionOption `
-ProxyAccessType {None|IEConfig|WinHttpConfig|AutoDetect|NoProxyServer} `
-ProxyAuthentication {Default|Basic|Negotiate|NegotiateWithImplicitCredential|Credssp|Digest|Kerberos} `
-ProxyCredential $PSCredential
- New-PSSessionOption
http://technet.microsoft.com/de-de/library/dd819436.aspx
Auf der Seite des Servers kann dies ein Reverse-Proxy oder eine Firewall sein, die den Zugang sicher "veröffentlicht". Hier könnte auch noch mal eine Authentifizierung statt finden. Wobei Sie hier schlechte Karten haben, wenn die Gegenseite z.B. eine Portalseite vorgeschaltet hat o.ä. Es hängt schon von der Art ab, wie der Server "/Powershell" veröffentlicht. Fragen Sie im Zweifelsfall dort nach, wie Sie einen Zugang erhalten können.
Und was ist WinRM ?
Bei der ganzen Diskussion mit "/Powershell" stellt sich natürlich mit die Frage, wo WinRM nun mit ins Boot kommt. Eigentlich gar nicht sichtbar, denn der Zugriff von Client zum Server erfolgt einzig über HTTP/HTTPS auf den IIS, welcher hinter /Powershell die entsprechenden Dienste anbietet. Für diese Funktion müssen Sie also nicht erst WINRM "remotefähig" machen und komplizierte Listener für die Ports 5985 oder 5986 erstellen, die von Firewall sowieso per Default nicht zugelassen sind. Da ist die Konfiguration eines IIS samt dessen Logging und Port 443 deutlich einfacher.
Das hat auch nichts mit den Befehlen "Enable-PSRemoting" und "Disable-PSRemoting" zu tun, welche ebenfalls nur für WinRM entsprechende Listener erstelle, Berechtigungen vergeben und die Windows Firewall anpassen.
eBook Update: Layman’s guide to PowerShell 2.0
remoting
http://www.ravichaganti.com/blog/?p=1780
Praktischer Einsatz
Mit folgenden Zeilen sollten Sie von einem beliebigen PC, auf dem die Powershell 2.0 installiert wurde, eine Verbindung zu einem Exchange Server herstellen können. Auf eine umfangreiche Fehlerbehandlung, die für einen automatischen Einsatz natürlich erforderlich ist, wurde zugunsten der Übersichtlichkeit verzichtet:
# Zertifikatsprüfungen für Testumgebung abschalten
$SkipCertificate = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck
# Anmeldedaten erfragen
$cred = Get-Credential
# PS-Session starten
$Session = New-PSSession `
-ConfigurationName Microsoft.Exchange `
-ConnectionUri https://<E2K10Server>.domain.com/PowerShell/ `
-Authentication Negotiate `
-SessionOption $SkipCertificate `
-credential $cred
# Importieren der erzeugten Session in die aktuelle Session
# lokal gleichlautende Commandlets werden ersetzen
Import-PSSession -Session $Session -AllowClobber
# hier können Sie nun wie gewohnt agieren
Get-OrganizationConfig
# Wenn Sie fertig sind, dann sollten Sie die Sessions wieder sauber abbauen
Remove-PSSession -Session $Session
Sie können dieses Zeile natürlich auch als PS1-Datei speichern aber für eine automatische Verarbeitung fehlt eine sichere Kennwortablage und natürlich jedes Reporting, Alerting o.ä. Starten Sie daher besser eine Powershell und geben Sie manuell die einzelnen Zeilen ein. Dann können Sie vor dem abschließenden "Remote-PSSession" auch noch weitere Exchange Commandlets ausprobieren.
Lync remote nutzen
Auch Lync nutzt nicht die Funktionen von WinRM, sondern hat ebenfalls eine eigene Webservice-basierte Lösung geschaffen, die sogar noch den alten Namen "OCS" enthält
- Microsoft Lync Remote
PowerShell Administration
http://blog.insidelync.com/2011/08/remote-lync-powershell-administration/
Weitere Links
- RBAC
- WinRM
- Create a Manual Remote Shell Connection
http://technet.microsoft.com/en-us/library/dd335083.aspx - Connect Remote Exchange Management Shell to an Exchange Server
http://technet.microsoft.com/en-us/library/dd297932.aspx - Exchange 2010 Management Architecture – Using a
single machine to manage multiple Exchange 2010
Organizations
http://www.msexchange.org/articles_tutorials/exchange-server-2010/management-administration/management-administration/exchange-2010-management-architecture-single-machine-manage-multiple-exchange-2010-organizations.html - Programmatic Access via Remote PowerShell in
Exchange Server 2010
http://blogs.technet.com/b/exchange/archive/2009/11/02/3408653.aspx
Wie sprechen Sie Powershell remote aus C#/VB.Net an - Enable and Use Remote Commands in Windows PowerShell
http://technet.microsoft.com/en-us/magazine/ff700227.aspx - Hey, Scripting Guy! Weekend Scripter: How Can I Run
Windows PowerShell Commands Remotely?
http://blogs.technet.com/b/heyscriptingguy/archive/2010/03/14/hey-scripting-guy-march-14-2010.aspx - PowerShell 2.0 remoting guide: Part 12 – Using
CredSSP for multi-hop authentication
http://www.ravichaganti.com/blog/?p=1230 - eBook Update: Layman’s guide to PowerShell 2.0
remoting
http://www.ravichaganti.com/blog/?p=1780 - SharePoint 2010 remoting
http://sharepoint.microsoft.com/blogs/zach/Lists/Posts/Post.aspx?ID=45 - Exchange 2010 remoting
http://www.mikepfeiffer.net/2010/02/managing-exchange-2010-with-remote-powershell - Lync Server 2010
http://blogs.technet.com/b/csps/archive/2010/08/03/scriptremotedesktopicon.aspx










