Exchange PowerShell V3

Die neue Exchange Online PowerShell V3 löst sowohl die Exchange Online PowerShell V2 als auch die alte Remote PowerShell (RPS) für Exchange Online ab.

Achtung: Die Abschaltung ist für Sommer 2023 geplant. Bis dahin müssen Sie ihre Skripte angepasst haben, die ein "New-PSSession" nutzen. Für On-Premises ändert sich nichts.

Geschichte

Seit Exchange 2007 nutzen Administratoren die Exchange PowerShell zur Verwaltung der On-Premises Exchange Server. Auch die grafische Oberfläche bedient sich im Unterbau den Commandlets. Zwar kann ein Administrator auch eine "Local PowerShell" allein anhand der DLLs instanzieren, aber das ist eher der Ausnahmefall. Das Exchange Setup bedient sich solch einer rudimentären PowerShell zur initialen Installation aber üblicherweise nutzen Administratoren eine RemotePowershell (Exchange PowerShell). Die Commandlets der PowerShell führen nicht selbst die Änderungen aus, sondern übergeben den Befehl an den Server, der dann die Rollenberechtigungen (RBAC - Role Based Access Control) prüft.

Mit Exchange Online hat sich anfangs damit nichts geändert. Auch hier wurde eine "Remote PowerShell" per HTTPS zum Exchange Online Endpunkt aufgebaut. Die Authentifizierung erfolgte damals, um das Jahr 2007, noch einfach per Benutzername und Kennwort, was nach heutigen Gesichtspunkten nicht mehr sicher ist.

Daher hat Microsoft im November 2021 eine Exchange Online PowerShell V2 als Preview angekündigt und kontinuierlich weiterentwickelt. Im Hintergrund werden die meisten Funktionen nun über die Exchange REST-API, die indirekt auch von der Graph API genutzt wird. Es gab immer noch einige Funktionen, die noch nicht über die REST-API erreichbar waren und daher ein Rückgriff auf die Remote PowerShell erfolgte. Allerdings konnte sich die neue Exchange PowerShell V2 schon mittels "Modern Authentication" anmelden.

Das Ende der Exchange Remote Powershell V1 ist für Januar 2022 vorgesehen.

As a reminder: the Exchange Online PowerShell v1 module with Basic auth will stop working starting October 1, 2022 when Basic authentication is turned off for connections to Exchange Online.
Quelle: https://techcommunity.microsoft.com/t5/exchange-team-blog/moving-from-the-exchange-powershell-v1-module-to-the-v2-preview/ba-p/3450679

Im Dezember 2022 hat Microsoft dann recht überraschend das Ende der Exchange PowerShell V2 für Sommer 2023 angekündigt.

Using RPS through New-PSSession and the v2 module deprecation will be completed by July 2023
Quelle: https://techcommunity.microsoft.com/t5/exchange-team-blog/announcing-deprecation-of-remote-powershell-rps-protocol-in/ba-p/3695597

Warum Microsoft nun so auf die Tube drückt, kann ich nicht sagen. Vermutlich ist der Betrieb der alten "RPS-Plattform" nicht nur aufwändig und teuer sondern auch nicht mehr sicher genug. Lücken sind mir keine bekannt aber die Technik ist über 12 Jahre alt und REST und OAUTH sind einfach moderne Ansätze.

Aktion erforderlich

Mit einer sehr kurzen Vorlaufzeit sind nun alle Firmen aufgerufen ihre Skripte für ein Management von Exchange Online entsprechen anzupassen. Das klingt nach lange aber so einfach ist das nicht, denn es geht nicht nur um einen Administrator, der interaktiv eine Änderung in Exchange Online vornehmen möchte. Bei viele Firmen gibt es komplexe und umfangreiche Skripte zur Automatisierung von Exchange Online. Zwar lassen sich viele Einstellungen für Empfänger auch über das lokale AD-Objekt und den Verzeichnisabgleich (AzureAD Cloud Sync oder ADSync / AADConnect) konfigurieren aber z.B. Postfachempfänger, Group-Mailbox-Einstellungen etc. sind nicht im lokalen AD hinterlegt und daher in der Cloud zu verwalten. All diese Prozesse müssen angepasst werden.

Laut Microsoft "soll" das natürlich alles ganz einfach sein, denn die Commandlets sind weitgehend gleich geblieben und nur der Aufbau der Verbindung ist zu ändern:

Alt: New-PSSession
Neu: Connect-ExchangeOnline

Ganz so einfach ist es natürlich nicht, denn Sie müssen dazu zuerst die neue Exchange Online Powershell 3.0 installieren, die nun aber auch mit der PowerShell 7 auf Windows, Linux und MacOS läuft.

Wenn auf ihrem Management System noch keine PowerShell 7 installiert ist, sollten Sie in dem Zuge gleich den Umstieg machen. Ich arbeite fast nur noch in der PSWH und nutze die alte PowerShell nur noch, wenn ich alte COM-Interop-Funktionen oder eben die "alten" Exchange RPS-basierten Funktionen gebraucht habe. Ich hoffe, dass das nun alles Geschichte ist.

Sie sollten in dem Zuge auch die Anmeldung überarbeiten. Gerade die neue Möglichkeit die PowerShell als "Application" (EXO PowerShell Automation) anzumelden (Azure CBA), ist eine gerne genommene Verbesserung zur Härtung der Anmeldevorgänge. Dennoch ist ein Blick auf die Liste der Einschränkungen ratsam.

Mir fällt da insbesondere die Funktion "Get-ConnectionInformation" auf. Bisher habe ich nach der Verbindung zur Exchange PowerShell geprüft, ob die Verbindung erfolgreich war, z.B. indem ich ein Get-PSSession ausgewertet oder einen einen anderen "GET"-Befehl der Exchange Powershell gestartet und den Fehler geprüft habe. Get-PSSession kann aber die neuen REST-Verbindung nicht anzeigen. Dazu stellt Microsoft nun ein "Get-ConnectionInformation" bereit.

Wenn Sie dann all ihre Skripte umgestellt haben, dann vergessen Sie nicht WinRM wieder besser abzusichern. Auch das schreibt ihnen die PowerShell beim Login direkt auf den Bildschirm:

This V3 EXO PowerShell module contains new REST API backed Exchange Online cmdlets which 
doesn't require WinRM for Client-Server communication. You can now run these cmdlets after
turning off WinRM Basic Auth in your client machine thus making it more secure.
Quelle: Exchange Online PowerShell v3

Installation

Die Installation selbst ist unspektakulär. Ich nutze dazu die Powershell 7 und installiere das Modul mittels "Install-Module". Wenn sie schon eine ältere Version installiert haben, dann bekommen Sie einen Hinweis die gewünschte Version aktiv daneben zu installieren.

Sie können aber auch einfach mit "Update-Module" die vorhandene Version durch die neue Version ersetzen.

Verbindung

Anstatt eines "New-PSSession" können Sie nun folgenden vereinfachten Code nutzen:

Import-Module ExchangeOnlineManagement
Connect-ExchangeOnline

So öffnet sich dann ein Browser, um die Credentials einzugeben und ggfls. MFA-Abfragen zu bestätigen. Für die Automatisierung interessanter sind natürlich die Optionen einer Anmeldung als App mit Zertifikat Die Details dazu habe ich schon auf der Seite EXO PowerShell Automation beschrieben. Eine App hat den großen Vorteil, dass diese Zugangsdaten nicht für eine interaktive Anmeldung per Browser, Client o.ä. genutzt werden können. Selbst wenn die Zugangsdaten daher ausgeleitet werden, kann ein Angreifer sich damit z.B. nicht an einem PC oder anderen Diensten interaktiv anmelden. Wobei ein Exchange Admin schon genug Unfug anstellen kann. Denken Sie daher an eine sichere Speicherung der Zugangsdaten.

Achtung:
Connect-ExchangeOnline überschreibt die Commandlets der lokale Powershell, d.h. obwohl es Get-EXORecipient gibt, ersetzt er auch Get-Recipient, denn Connect-ExchangeOnline bindet sowohl das Module "ExchangeOnlineManagement" aber auch die alten Befehle ein. Sie können aber die Commandlets mit dem Parameter "-prefix" mit einem eigenen Prefix versehen. Für eigene Skripte ist dies ganz brauchbar.

 

Nach der Verbindung sollte die das neue Commandlet "Get-ConnectionInformation" zur Kontrolle nutzen.

PS C:\> Get-ConnectionInformation

ConnectionId : 92d33719-df99-4042-84c4-3d58d1d7493b
Id : 1
Name : ExchangeOnline_1
UserPrincipalName : admin@msxfaqdev.onmicrosoft.com
ConnectionUri : https://outlook.office365.com
AzureAdAuthorizationEndpointUri : https://login.microsoftonline.com/organizations
TokenExpiryTimeUTC : 22.12.2022 21:55:35 +00:00
CertificateAuthentication : False
ModuleName : C:\\AppData\Local\Temp\tmpEXO_kykd22kt.gd2
ModulePrefix :
Organization :
DelegatedOrganization :
AppId :
PageSize : 1000
TenantID : 604d9047-44e5-443a-ad8f-98abe5748b0a
TokenStatus : Active

Leider finden Sie hier keinen sprechenden Namen der Organisation aber über die TenantID können Sie sicher sein, den richtigen Tenant anzusprechen. Wenn Sie die Berechtigungen haben, dann hilft auch ein "Get-OrganizationConfig".

PS C:\> Get-OrganizationConfig | fl name,identity,displayname,OrganizationalUnitRoot

Name : msxfaqdev.onmicrosoft.com
Identity : msxfaqdev.onmicrosoft.com
DisplayName : msxfaqdev
OrganizationalUnitRoot : msxfaqdev.onmicrosoft.com

Alle weiteren regulären Befehle sind dann wieder unverändert. Allerdings sollten Sie am Ende die Verbindung auch wieder geplant abbauen, damit die Ressourcen entsprechend wieder freigegeben werden:

Disconnect-ExchangeOnline

Denn jede Verbindung zählt und die Anzahl der gleichzeitig erlaubten Verbindung ist begrenzt, womit wir gleich zum Thema Thottling kommen.

Commandlet Overwrite

Wenn Sie in einer PowerShell-Session z.B.: parallel mit Exchange Online und Exchange On-Premises arbeiten wollen, dann müssen Sie auf die Konflikte achten, denn beide PowerShells nutzen zum Teil die gleichen CMDlet-Namen. Dies ist mir bei der Entwicklung von Compare-GAL aufgefallen, wo ich mit "Get-Recipient" die lokalen Exchange Empfänger auslesen und mit "Get-EXORecipient" die Exchange Online Empfänger.

Ich habe in dem Skripte also zuerst die Exchange On-Premises Verbindung eingerichtet und dann die Exchange Online Verbindung hergestellt. Ich habe aber nicht daran gedacht, dass ein "Connect-ExchangeOnline" nicht nur die "*-EXO*"-Commandlets aktiviert, sondern eben auch noch die alten CMDLets. Das können Sie einfach sehen:

Es kommt aber keine Warnung, dass die CMDLets überschrieben werden. Einen Parameter "-NoClobber", wie es ihn bei Import-Module gibt, hat Microsoft bei Connect-ExchangeOnline schlichtweg nicht vorgesehen. Allerdings gibt es den Parameter "Prefix" den ich dann nutze, z.B. um einfach den Tenant-Namen zu addieren.

Connect-ExchangeOnline -prefix msxfaqlab
Get-msxfaqlabrecipient

Damit kann ich sogar in einer PowerShell mich zu mehreren Exchange Online Tenants verbinden. Sie müssen allerdings dran denken.

Throttling

Wer Massenänderungen per PowerShell bei Exchange Online machen möchte, muss sich auch hier mit dem Thema "Throttling" beschäftigen. Nur weil ihr PowerShell-Script als authentifizierte Application gestartet wurde, darf es nicht unbeschränkt die Ressourcen von Microsoft belasten. Microsoft "berechnet" jeden Befehl mit Kosten, die von einem Guthaben abgezogen werden, welches aber immer wieder aufgeladen wird. Es geht also darum, die Anfragen "richtig" zu stellen und ggfls. zu drosseln.

In der Regel bremst ExchangeOnline einen übereifrigen Client dadurch aus, dass die Antworten verzögert geliefert werden. Da ein PowerShell Script meist sequentiell abgearbeitet wird, verlängert sich so die Laufzeit. Eine Überwachung der Laufzeit kann ihnen bei der Suche helfen.

Als Programmierer sollten Sie z.B. Filter schon bei der Abfrage addieren und nicht erst alle Elemente abfragen und dann im Skript nachträglich zu filtern. Es kann aber auch sinnvoll sein, die Liste komplett zu laden, wenn Sie danach verschiedene Auswertungen auf der gleichen Liste fahren. Zudem sollten Sie am Ende die Verbindung wieder sauber mit einem "Disconnect-ExchangeOnline" wieder abbauen.

Denken Sie dann aber daran, dass die Daten ggfls. schon veraltet sind. Dies kennen Sie aber alles schon von EWS, Graph und anderen Diensten.

Weitere Links