Exchange Online PowerShell V2

Für Exchange Online entwickelt Microsoft eine neue PowerShell, die aber nicht mehr gegen einen lokalen Server genutzt wird. Erstmals orientiert sich Microsoft an den eigenen Vorgaben und addiert ein Prefix. Die bisherige Exchange PowerShell wird natürlich weiter wie seit Exchange 2007 gegen lokale Exchange Server genutzt.

Installation

Hinweis: Die neue Exchange PowerShell funktioniert noch nicht mit der PowerShell Core oder PowerShell 7

Schon die Installation unterscheidet sich von bisherigen PowerShell-Erweiterungen. Kein manueller Download von einer Microsoft Downloadseite, sondern sie müssen zuerst das Modul "PowerShellGet" installieren, wenn es nicht schon eh auf dem System installiert ist.

Install-Module PowershellGet

Im zweiten Schritt installieren Sie dann das ExchangeOnlineManagement-Modul

Install-Module -Name ExchangeOnlineManagement

Danach habe ich mir angewöhnt die PowerShell zu schließen und neu zu öffnen, damit die neuen Module auch mit eingebunden werden

Start und neue Befehle

Die starten dann einfach eine ganz normale PowerShell und geben ein:

Connect-ExchangeOnline

Das ist natürlich alles einfacher als die bisherige Online PowerShell mit PSSession, der Office 365 URL und Import-PSSession

Im Juni 2020 habe ich folgende Information gesehen und es hat sich dann das bekannte Anmeldefenster von Office 365 geöffnet, welches auch MFA unterstützt:

Hier noch einmal die Gegenüberstellung als Text:

|--------------------------------------------------------------------------|
|    Old Cmdlets                    |    New/Reliable/Faster Cmdlets       |
|--------------------------------------------------------------------------|
|    Get-CASMailbox                 |    Get-EXOCASMailbox                 |
|    Get-Mailbox                    |    Get-EXOMailbox                    |
|    Get-MailboxFolderPermission    |    Get-EXOMailboxFolderPermission    |
|    Get-MailboxFolderStatistics    |    Get-EXOMailboxFolderStatistics    |
|    Get-MailboxPermission          |    Get-EXOMailboxPermission          |
|    Get-MailboxStatistics          |    Get-EXOMailboxStatistics          |
|    Get-MobileDeviceStatistics     |    Get-EXOMobileDeviceStatistics     |
|    Get-Recipient                  |    Get-EXORecipient                  |
|    Get-RecipientPermission        |    Get-EXORecipientPermission        |
|--------------------------------------------------------------------------|

Kompatibilität ist Trumpf und daher richtet die neue Exchange Online PowerShell V2 auch noch die alten Befehle ein, die in der Liste hier nicht sehen.

Automatisierte Nutzung

Interessant an der neuen PowerShell ist aber auch, dass eine Anmeldung nicht mehr nur mit Benutzername/Kennwort erfolgen kann. Dieser Zugang ist speziell für Automatisierungen nicht sicher. Schließlich müssten Sie die Zugangsdaten ja einem Skript überlassen. Weiterhin müssten Sie dann auch noch Ausnahmen bei MFA eintragen, damit eine Anmeldung per Benutzername/Kennwort möglich ist. Das ist gerade für sensible und privilegierte Konten unerwünscht.

Sie können aber ihrem Skript z.B. ein Zertifikat hinterlegen, mit dem es sich gegen Office 365 authentifizieren kann. Der Vorteil ist, dass Sie kein Kennwort benötigen und dieses damit nicht abgefischt werden kann und MFA quasi auch mit erledigt ist, denn wenn das Zertifikat "nicht exportierbar" auf dem Computer mit dem Skript verbunden ist.

Throttling

Auch wenn Sie sich als Administrator mit Exchange Online verbunden haben, ist das noch kein Freibrief für "unlimited" PowerShell-Aktionen. Es gibt, wie auch für Anwender, ein Throttling und wenn Sie zu schnell und zu viele Commandlets absetzen, dann bekommen Sie folgende Fehlermeldung.

„Your Request is too frequent…“

Vielleicht haben Sie einen Tenant mit 100.000 Postfächern und wollen bei allen einen Eintrag ändern. Aber meist liegt an einer schlechten Programmierung, warum Exchange Online die Anzahl der Anfragen von ihrem Client drosselt. Es gibt einig Limit, die Sie mit passender Programmierung umgehen können. Eine Anhebung der Limit soll nicht möglich sein.

Throttling Wert Einstellung Description

PowerShellMaxConcurrency

3

Ein Anwender kann nicht mehr als 3 Sessions parallel offen haben. Das bedeutet, dass Sie eine Session am Ende auch sauber abbauen sollten .

PowerShellMaxTenantConcurrency

9

Für den Tenant gibt es eine globale Einstellung.

PowerShellMaxCmdletsTimePeriod

5 Sek

The time period, in seconds, that a user can run the number of cmdlets defined by the PowerShellMaxCmdlets or ExchangeMaxCmdlets parameter

PowerShellMaxCmdlets

200

The number of cmdlets that can be run per PowerShellMaxCmdletsTimePeriod without being throttled

ExchangeMaxCmdlets

25

This parameter is similar to PowerShellMaxCmdlets but only for Exchange Online cmdlets

PowerShellMaxDestructiveCmdletsTimePeriod

60 Sek

The time period, in seconds, that a user can run the number of cmdlets defined by the PowerShellMaxDestructiveCmdlets parameter

PowerShellMaxCmdletQueueDepth

50

Defines the number of operations that a user can run simultaneously

PowerShellMaxDestructiveCmdlets

120

The number of cmdlets that can be run per PowerShellMaxDestructiveCmdletsTimePeriod without being throttled.  A desuctive cmdlet is one that makes changes to the Office 365 environment (Such as Set or New cmdlets)

OnPremises können de die Werte sogar anpassen. Die Commandlets stehen aber nicht in Exchange Online zur Verfügung.

# In Exchange OnPremises können Sie dies ändern
New-ThrottlingPolicy `
   -Name "PSLimit" `
   -PowerShellMaxCmdlets 10 `
   -PowerShellMaxCmdletsTimePeriod 5

Hintergründe

Ich wollte natürlich wissen, was die neue Exchange Online PowerShell V2 im Hintergrund macht. Natürlich ist alles per HTTPS verschlüsselt, so dass WireShark nicht weiter hilft. Aber Fiddler hilft mit zumindest einen Teil der Daten zu ermitteln. Insbesondere die Anmeldung per OAUTH verrät über das ausgestellte Token schon etwas über die angeforderten Rechte.

Wenn ich das "access_token" z.B. über jwt.io decodiere, dann sieht das JSON-Format wie folgt aus:

{
  "aud": "https://outlook.office365.com",
  "iss": "https://sts.windows.net/3c6855ff-e39f-4d09-a473-33807598ce4b/",
  "iat": xxx,
  "nbf": xxx,
  "exp": xxx,
  "acct": 0,
  "acr": "1",
  "aio": "xxx/xxxx=",
  "amr": [
    "pwd"
  ],
  "app_displayname": "Microsoft Exchange REST API Based Powershell",
  "appid": "fb78d390-0c51-40cd-8e17-fdbfab77341b",
  "appidacr": "0",
  "enfpolids": [],
  "family_name": "Admin",
  "given_name": "o365",
  "ipaddr": "146.251.41.17",
  "name": "admin",
  "oid": "30447744-bee4-474b-816e-eeb6bcb414d1",
  "puid": "1003BFFD99BE045D",
  "scp": "AdminApi.AccessAsUser.All FfoPowerShell.AccessAsUser.All RemotePowerShell.AccessAsUser.All",
  "sid": "87da8436-5072-4365-9066-c0e127e9734f",
  "sub": "xxx-xxx",
  "tid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "unique_name": "admin2@msxfaq.onmicrosoft.com",
  "upn": "admin2@msxfaq.onmicrosoft.com",
  "uti": "xxxx",
  "ver": "1.0",
  "wids": ["xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"]
}

Hier sind die folgenden Daten interessant.

  • "aud": "https://outlook.office365.com"
    Die Exchange Online PowerShell V2 nutzt also nicht Graph als API sondern weiterhin "outlook.office365.com" als Adresse. Aber es natürlich eine RestAPI
  • "scp": "AdminApi.AccessAsUser.All FfoPowerShell.AccessAsUser.All RemotePowerShell.AccessAsUser.All",
    Das sind die "Admin-Rollen" die mein Benutzer in dem Moment hat.

Aber da es sich um eine REST-API handelt, können Sie mit Fiddler natürlich auch jeden einzelnen Aufruf anschauen. Allerdings nutzt die PowerShell nicht die Einstellungen ihres Browsers und nutzt damit auch erst einmal nicht den Fiddler-HTTP-Proxy. Man muss schon den WinHTTP-Proxy umbiegen

netsh winhttp set proxy localhost:8888

Damit sehen Sie dann auch die weitere Aufrufe der Exchange Online PowerShell gegen den Backend Service. Die URLs haben alle die Form

"https://outlook.office.com/adminApi/beta/*"

Weitere Links