Office 365 Gast-Konten / Azure B2B

Nicht alle Benutzer in einem Office 365 Tenant sind auch zwingend mit der Firma verbunden. Eine Sonderstellung sind "Guest Accounts" in Tenant, die in der Regel nicht durch einen Administrator direkt verwaltet werden. Die Besonderheiten beleuchte ich auf dieser Seite

Wozu und Woher?

Wenn Sie in der Verwaltung ihres Tenant die Benutzer öffnen, dann sehen Sie sehr prominent neben den Benutzern und Gruppen auch die Gastbenutzer. In meinem Spiel und Test-Tenant sind das nur zwei Benutzer

Diese Konten haben Sie in der Regel aber nicht als Administrator angelegt. Sie werden immer dann von Office 365 in ihrem Tenant erzeugt, wenn Anwender in einer Applikation über die Funktion "Guest Access", die es z.B. für Teams Gastzugang aber auch SharePoint u.a. gibt, Berechtigungen eingerichtet haben. Genau wie auf einem Windows Dateiserver kann eine ACL nur um die Objekte erweitert werden, die das Verzeichnis kennt.

Wenn ein Anwender also z.B. "user@msxfaq.de" auf einer Freigabe in seinem Tenant berechtigt, dann legt Office 365 i AzureAD diesen Benutzer als Gast-Benutzer an. Der "reale" Anwender, der sich mit diesem UPN anmeldet, meldet sich natürlich an seinem Tenant oder vielleicht später auch an Facebook, Google oder anderen vertrauenswürdigen Identitätsgebern an, um auf die bereitgestellten Informationen zuzugreifen.

Auf der Webseite sehen Sie auch, dass Sie diese Benutzer sehr wohl löschen können. Ein Editieren ist aber nicht vorgesehen.

Entsprechend war natürlich meine Neugierde geweckt, was die verschiedenen PowerShells dazu sagen.

Gäste und AADConnect

Wer seine Benutzer im lokalen Active Directory verwaltet, wird in der Regel diese mit AzureADConnect in den Tenant repliziere. Dies ist für einen Hybrid-Mode von Exchange On-Premises mit Exchange Online oder Skype for Business mit SFB Online/Teams auch erforderlich. Allerdings interessiert sich AzureADConnect aktuell nicht um diese Gäste. Wenn die Gäste also irgendwie in den Online-Applikationen sichtbar werden, so können Sie nicht in der On-Premises-Umgebung referenziert werden.

AzureAD

Ehe ich aber die AzureAD PowerShell starte, habe ich per https://portal.azure.com noch einmal die gleichen Benutzer angeschaut. Hier geht erstaunlicherweise etwa mehr.

Ich sehe zwar die gleichen Personen und kann auch auf die Gastbenutzer filtern, aber es gibt hier auch einen "New guest User" Button. Allerdings kann ich auch hier dann nur eine Mailadresse eintragen

Der Link zu "Learn More" geht auf folgende URL

Über die AzureAD-Verwaltungskonsole lassen sich auch einige andere Einträge des Benutzers verwalten.

Es hat also schon seine Vorteile, wenn Sie um die Hintergründe wissen, z.B. dass die Office 365 Verwaltungsseite nur eine Teilmenge der AzureAD-Einträge anzeigt.

Azure AD PowerShell

Das sollte sich so ja auch per AzureAD PowerShell verarbeiten lassen. Über das Property "UserType" können Sie hier schnell zwischen Gästen und anderen Konten unterscheiden. Ich habe den Befehl natürlich nicht in meiner kleinen Testumgebung sondern in einem größeren Tenants gestartet. Oft erkennt man so ja noch mehr Feldinhalte, die in einem sauberen Test-Tenant nicht sichtbar sind. Das ist durchaus wichtig für spätere Skripte

Get-AzureADUser -All $true | group usertype -noelement | ft -autosize
Count Name
----- ----
166 Member
60
188 Guest

Hier gibt es neben den 166 Benutzern auch 188 Gäste aber auch 60 Konten ohne Inhalt in "usertype". Eine genauere Auswertung zeigte mir, dass ein Gast immer ein 'usertype -eq "Guest"' hat aber normale Anwender, nicht immer als "member" belegt werden. Die Ursache dazu habe ich noch nicht ermittelt.

Ein einzelner Testbenutzer ist mit Get-AzureADUser einfach zu erhalten. Er ist natürlich ziemlich "leer":

PS C:\> Get-AzureADUser -SearchString user1@carius.de | fl

DeletionTimestamp              :
ObjectId                       : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
ObjectType                     : User
AccountEnabled                 : True
AgeGroup                       :
AssignedLicenses               : {}
AssignedPlans                  : {}
City                           :
CompanyName                    :
ConsentProvidedForMinor        :
Country                        :
CreationType                   : Invitation
Department                     :
DirSyncEnabled                 :
DisplayName                    : user1
FacsimileTelephoneNumber       :
GivenName                      :
IsCompromised                  :
ImmutableId                    :
JobTitle                       :
LastDirSyncTime                :
LegalAgeGroupClassification    :
Mail                           : user1@carius.de
MailNickName                   : user1_carius.de#EXT#
Mobile                         :
OnPremisesSecurityIdentifier   :
OtherMails                     : {user1@carius.de}
PasswordPolicies               :
PasswordProfile                :
PhysicalDeliveryOfficeName     :
PostalCode                     :
PreferredLanguage              :
ProvisionedPlans               : {}
ProvisioningErrors             : {}
ProxyAddresses                 : {SMTP:user1@carius.de}
RefreshTokensValidFromDateTime : 13.11.2018 13:52:40
ShowInAddressList              : False
SignInNames                    : {}
SipProxyAddress                :
State                          :
StreetAddress                  :
Surname                        :
TelephoneNumber                :
UsageLocation                  :
UserPrincipalName              : user1_carius.de#EXT#@fcarius.onmicrosoft.com
UserState                      : PendingAcceptance
UserStateChangedOn             : 2018-11-13T13:52:40Z
UserType                       : Guest

Einzelne Werte können mit Set-AzureADUser natürlich auch beschrieben werden

Einladen und Annehmen

Wird ein Gast-Konto neu angelegt, dann hat es den Status "Eingeladen". Der Gast bekommt dann eine Mail:

Natürlich muss sich der Anwender dann erst anmelden um dann den folgenden Dialog zu sehen:

Nachdem der Gats zugestimmt hat, zeigt ein weiterer Get-AzureADUser an, dass sich die folgenden Felder geändert haben

DisplayName : User1 (O365 Carius)
UserState : Accepted
UserStateChangedOn : 2018-11-13T14:23:14Z

Soweit erst mal nichts besonders. Allerdings scheint z.B. die Übernahme des "DisplayName" eine einmalige Kopier-Aktion zu sein. Die Mail-Adresse hat schon übereingestimmt, so dass hier keine Änderung zu sehen war.

Wäre nett, wenn Azure die Stammdaten des eigentlichen Anmeldekontos nicht nur einmal aktualisieren würde, sondern z.B.: bei jeder Anmeldung einfach mal nachschaut. Natürlich mit etwas Throttling.

Anmelden

Schon durch die Annahme der Einladung durch ein Konto, welches in einem anderen Office 365 Tenant als Benutzer registriert war, bin ich in dem Gast-Tenant angemeldet. Natürlich sieht dieser User so erst mal nichts, da er keine Rechte bekommen hat.

Es ist ja "nur" als Identität nun bekannt und kann sich mit seinem Office 365 Konto authentifizieren.

Interessant fand ich, dass ich einen Gast-Benutzer deaktivieren kann. Aber dass ich auch ein Kennwort auf den Gastbenutzer setzen kann, irritiert mir. (die Daten hier sind nicht real)

Get-AzureADUser `
   -SearchString user1@carius.de `
| Set-AzureADUserPassword `
   -Password ("Geheimes Kennwort4!" | ConvertTo-SecureString -AsPlainText -Force)

Der Befehl mit richtigen Daten läuft problemlos durch. Ich werde mich nun natürlich nicht mit meiner "Mailadresse" anmelden können. Aber der UPN könnte ein Hinweis sein. Der Versuch einer Anmeldung an "portal.office365.com" mit eben diesem UPN war dann auch erfolgreich. Office 365 glaubte, dass ich ich als "user1@carius.de" angemeldet hätte, obwohl ich "user1_carius.de#EXT#@fcarius.onmicrosoft.com" als UPN und das eben frisch gesetzte Kennwort verwendet habe.

Das eröffnet natürlich auch neue Optionen, wenn z.B. eine Person in einem anderen Tenant keinen Zugriffe mehr hat, weil Sie z.B. die Firma verlassen und damit auch die Anmeldung mit dem originalen UPN verloren hat. Dann kann der Admin des Tenants mit den Daten einfach das Kennwort setzen und so dem Gastbenutzer weiterhin zugriff gewähren.

Noch interessanter ist, wenn sich der Gastbenutzer wie gewohnt mit seinem Office 365 Konto anmeldet und der Administrator dennoch das Kennwort auf ein ihm bekannten Wert setzt. Er kann dann so tun, als wäre er der Benutzer und verifizieren, was der Gast genau kann und was nicht.

MsolOnline

Die Commandlets der AzureAD-Powershell sind deutlich leistungsfähiger. Das sehe ich schon an der beschränkten Filterfunktion von Get-MSOLUser. Es gibt nämlich keine Filterfunktion auf z.B. Gastbenutzer o.ä. Da hilft nur die komplette Liste mit nachgeschalteter Where-Abfrage oder die direkte Adressierung über den UPN

PS C:\> Get-MsolUser -UserPrincipalName "user1_carius.de#EXT#@fcarius.onmicrosoft.com" | fl


ExtensionData                          : System.Runtime.Serialization.ExtensionDataObject
AlternateEmailAddresses                : {user1@carius.de}
AlternateMobilePhones                  : {}
AlternativeSecurityIds                 : {16 3 127 254 137 18 80 67}
BlockCredential                        : False
City                                   :
CloudExchangeRecipientDisplayType      : 6
Country                                :
Department                             :
DirSyncProvisioningErrors              : {}
DisplayName                            : User1 (O365 Carius)
Errors                                 :
Fax                                    :
FirstName                              :
ImmutableId                            :
IndirectLicenseErrors                  : {}
IsBlackberryUser                       : False
IsLicensed                             : False
LastDirSyncTime                        :
LastName                               :
LastPasswordChangeTimestamp            : 13.11.2018 14:13:33
LicenseAssignmentDetails               : {}
LicenseReconciliationNeeded            : False
Licenses                               : {}
LiveId                                 : xxxxxxxx
MSExchRecipientTypeDetails             :
MSRtcSipDeploymentLocator              :
MSRtcSipPrimaryUserAddress             :
MobilePhone                            :
ObjectId                               : xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx
Office                                 :
OverallProvisioningStatus              : None
PasswordNeverExpires                   :
PasswordResetNotRequiredDuringActivate :
PhoneNumber                            :
PortalSettings                         :
PostalCode                             :
PreferredDataLocation                  :
PreferredLanguage                      :
ProxyAddresses                         : {SMTP:user1@carius.de}
ReleaseTrack                           :
ServiceInformation                     : {}
SignInName                             : user1@carius.de
SoftDeletionTimestamp                  :
State                                  :
StreetAddress                          :
StrongAuthenticationMethods            : {}
StrongAuthenticationPhoneAppDetails    : {}
StrongAuthenticationProofupTime        :
StrongAuthenticationRequirements       : {}
StrongAuthenticationUserDetails        :
StrongPasswordRequired                 :
StsRefreshTokensValidFrom              : 13.11.2018 14:13:33
Title                                  :
UsageLocation                          :
UserLandingPageIdentifierForO365Shell  :
UserPrincipalName                      : user1_carius.de#EXT#@fcarius.onmicrosoft.com
UserThemeIdentifierForO365Shell        :
UserType                               : Guest
ValidationStatus                       : Healthy
WhenCreated                            : 13.11.2018 13:52:4

Mehr ist hier aber auch nicht zu finden als in Get-AzureADUser.

Skype for Business

Interessanter ist vielleicht die Funktion in den Applikationen. So ein "Gast-Benutzer" kann ja durchaus auch für Exchange Online oder Skype for Business Online relevant bzw. nützlich werden. Bei einem Hybrid-Mode ist es natürlich wieder knifflig, da AADConnect die Gastbenutzer nicht nach On-Premises repliziert. Eine Suche in einem größeren Tenant hat da auch wieder eine interessante Liste geliefert.

Get-CSOnlineUser | group HostingProvider -noelement

Count Name
----- ----
142
105 SRV:
33 sipfed.online.lync.com

Hier sind also 33 Objekte schon in SfB Online und 105 Objekte On-Premises. Auch diese Zahlen passen nie ganz, denn es gibt lokale Objekte wie ResponseGroups, die nicht durch AADConnect erfasst werden und eine Rückreplikation von "Cloud Only"-Objekten gibt es auch kaum. Wobei dann wenigstens hier die Objekte mit "sipfed.online.lync.com" richtig angelegt sind.

Schaue ich mir so ein einzelnes Objekt einmal genauer an und gruppiere diese nach "InterpretedUserType", dann sehe ich folgendes

Get-CSOnlineUser | ? {$_.HostingProvider -eq ""} | group InterpretedUserType

Count Name
----- ----
   16 PureOnlineNoService
  120 DirSyncNoService
    5 DirSyncDisabledUser
    1 DirSyncNoServiceNotInPDL

Diese Benutzer sind also gar nicht für Skype for Business aktiviert. Gastbenutzer sind aber keine darunter.

Exchange Online

Anders sieht es aber in Exchange Online aus. Hier sind auch die Gäste sofort als Objekt mit der PowerShell erreichbar.

PS C:\Users\fcarius> Get-Recipient user1@carius.de |fl

Identity                           : user1_carius.de#EXT#
Alias                              : user1_carius.de#EXT#
ArchiveGuid                        : 00000000-0000-0000-0000-000000000000
AuthenticationType                 : Managed
City                               :
Notes                              :
Company                            :
CountryOrRegion                    :
PostalCode                         :
CustomAttribute1                   :
CustomAttribute2                   :
CustomAttribute3                   :
CustomAttribute4                   :
CustomAttribute5                   :
CustomAttribute6                   :
CustomAttribute7                   :
CustomAttribute8                   :
CustomAttribute9                   :
CustomAttribute10                  :
CustomAttribute11                  :
CustomAttribute12                  :
CustomAttribute13                  :
CustomAttribute14                  :
CustomAttribute15                  :
ExtensionCustomAttribute1          : {}
ExtensionCustomAttribute2          : {}
ExtensionCustomAttribute3          : {}
ExtensionCustomAttribute4          : {}
ExtensionCustomAttribute5          : {}
Database                           :
ArchiveDatabase                    :
DatabaseName                       :
Department                         :
ExternalDirectoryObjectId          : 8af32445-1c92-464f-aa97-c85bf718d023
ManagedFolderMailboxPolicy         :
EmailAddresses                     : {SMTP:user1@carius.de}
ExpansionServer                    :
ExternalEmailAddress               : SMTP:user1@carius.de
DisplayName                        : User1 (O365 Carius)
FirstName                          :
HiddenFromAddressListsEnabled      : True
EmailAddressPolicyEnabled          : False
LastName                           :
ResourceType                       :
ManagedBy                          : {}
Manager                            :
ActiveSyncMailboxPolicy            : Default
ActiveSyncMailboxPolicyIsDefaulted : True
Name                               : user1_carius.de#EXT#
Office                             :
ObjectCategory                     : NAMPR20A001.PROD.OUTLOOK.COM/Configuration/Schema/Person
OrganizationalUnit                 : nampr20a001.prod.outlook.com/Microsoft Exchange Hosted Organizations/fcarius.onmicrosoft.com
Phone                              :
PoliciesIncluded                   : {}
PoliciesExcluded                   : {{26491cfc-9e50-4857-861b-0cb8df22b5d7}}
PrimarySmtpAddress                 : user1@carius.de
RecipientType                      : MailUser
RecipientTypeDetails               : GuestMailUser
SamAccountName                     : user1535371208570991
ServerLegacyDN                     :
ServerName                         :
StateOrProvince                    :
StorageGroupName                   :
Title                              :
UMEnabled                          : False
UMMailboxPolicy                    :
UMRecipientDialPlanId              :
WindowsLiveID                      : user1_carius.de#EXT#@fcarius.onmicrosoft.com
HasActiveSyncDevicePartnership     : False
AddressListMembership              : {\All Recipients(VLV), \All Mail Users(VLV)}
OwaMailboxPolicy                   :
AddressBookPolicy                  :
SharingPolicy                      :
RetentionPolicy                    :
ShouldUseDefaultRetentionPolicy    : False
MailboxMoveTargetMDB               :
MailboxMoveSourceMDB               :
MailboxMoveFlags                   : None
MailboxMoveRemoteHostName          :
MailboxMoveBatchName               :
MailboxMoveStatus                  : None
MailboxRelease                     :
ArchiveRelease                     :
IsValidSecurityPrincipal           : True
LitigationHoldEnabled              : False
Capabilities                       : {}
ArchiveState                       : None
SKUAssigned                        :
WhenMailboxCreated                 :
UsageLocation                      :
ExchangeGuid                       : 00000000-0000-0000-0000-000000000000
ArchiveStatus                      : None
SafeSendersHash                    :
SafeRecipientsHash                 :
BlockedSendersHash                 :
WhenSoftDeleted                    :
ExchangeVersion                    : 1.1 (15.0.0.0)
DistinguishedName                  : CN=user1_carius.de\#EXT\#,OU=fcarius.onmicrosoft.com,OU=Microsoft Exchange Hosted
                                     Organizations,DC=NAMPR20A001,DC=PROD,DC=OUTLOOK,DC=COM
ObjectClass                        : {top, person, organizationalPerson, user}
WhenChanged                        : 13.11.2018 17:06:42
WhenCreated                        : 13.11.2018 14:58:25
WhenChangedUTC                     : 13.11.2018 16:06:42
WhenCreatedUTC                     : 13.11.2018 13:58:25
OrganizationId                     : NAMPR20A001.PROD.OUTLOOK.COM/Microsoft Exchange Hosted Organizations/fcarius.onmicrosoft.com -
                                     NAMPR20A001.PROD.OUTLOOK.COM/ConfigurationUnits/fcarius.onmicrosoft.com/Configuration
Id                                 : user1_carius.de#EXT#
Guid                               : 3c75d1ba-090c-4356-bdb3-e629514eeb90
OriginatingServer                  : CY1PR20A001DC06.NAMPR20A001.PROD.OUTLOOK.COM
IsValid                            : True
ObjectState                        : Unchanged

Allerdings gibt es wichtige Felder für Exchange:

EmailAddresses                     : {SMTP:user1@carius.de}
ExternalEmailAddress               : SMTP:user1@carius.de
HiddenFromAddressListsEnabled      : True
RecipientTypeDetails               : GuestMailUser"

Die Objekte werden also nicht in der GAL angezeigt und sind vom Typ her klar als Gäste erkennbar. Zudem belegen sie keine Adresse in ihrer Domäne. Sie könnten die Kontakte aber sichtbar machen und sogar mit Zusatzdaten (Adresse, Telefon etc.) füttern.

SIP, SMTP und UPN

Die Einladung eines Gasts in einen Tenant erfolgt üblicherweise über die Mailadresse. Das ist der primäre Schlüssel, den ein Anwender oder Administrator kennt. Der UPN ist in der Regel ja nicht bekannt und wird im Außenverhältnis auch kaum genutzt. Das bringt nun natürlich Probleme mit sind, wenn der UPN und die SMTP-Adresse unterschiedlich ist. Mit der SMTP-Adresse kann sich der Anwender ja nicht wirklich anmelden. Also wird man versuchen den Gast über die UPN-Adresse einzuladen. Damit wird zwar dann ein richtiges Gastkonto erstellt, aber der Anwender bekommt die Mail dazu nicht.

Später wird es mit Teams z.B. noch Probleme geben, da verpasste Mails über den Teams-SMTP-Dienst versendet werden. Der ist aber nicht Bestandteil des Exchange Online Tenant sondern steht quasi nebendran. Daher können Sie von Teams nach extern auch keine Exchange Online Kontakte zum umschreiben der Mails verwenden. Auch funktioniert Teams mit "Hybrid Centralized Mail Transport" nicht, da die Mail gar nicht die Exchange Plattform des Tenants nutzt.

Mit all dem Wissen bewahrheitet es sich immer wieder, dass Sie am besten alle drei Felder Mail, SIP, UPN identisch halten.

Gast und AADConnect

Passend dazu habe ich dann natürlich mal einen Kontakt im lokalen AD angelegt und wollte sehen, was AADConnect daraus macht. Zuerst prüfe ich nach AzureADUser und finde nur ein Objekt, welches auch nicht per DirSync verbunden ist

Get-AzureADUser -SearchString user1@carius.de| fl fl *sync*,userstate*,usertype,userprincipalname

DirSyncEnabled     :
LastDirSyncTime    :
UserState          : Accepted
UserStateChangedOn : 2018-11-13T14:23:14Z
UserType           : Guest
UserPrincipalName  : user1_carius.de#EXT#@fcarius.onmicrosoft.com

Aber wir haben ja gelernt, dass Exchange Kontakte auch im Azure Active Directory zu AzureADContacts werden. Also suche ich mit "Get-AzureADContact". Beachten Sie dabei die Filter-Syntax, die sich von gewohnten Filtern unterscheidet. Vor dem "eq" kommt wirklich kein "-"

Get-AzureADContact  -Filter "mail eq 'user1@carius.de'" | fl

DeletionTimestamp          :
ObjectId                   : xxxxxxx-xxxx-xxxx-xxxxxxxx-xxxxxxxxx
ObjectType                 : Contact
City                       :
CompanyName                :
Country                    :
Department                 :
DirSyncEnabled             : True
DisplayName                : user1 (contact)
FacsimileTelephoneNumber   :
GivenName                  : Frank
JobTitle                   :
LastDirSyncTime            : 13.11.2018 20:19:25
Mail                       : user1@carius.de
MailNickName               : user1_Carius__contact_
Mobile                     :
PhysicalDeliveryOfficeName :
PostalCode                 :
ProvisioningErrors         : {class ProvisioningError {
                               ErrorDetail: <ServiceInstance Name="exchange/namprd20-001-01" xmlns="http://schemas.microsoft.com/online/error/2010/07">
                               <ObjectErrors>
                                 <ErrorRecord>
                                   <ErrorCode>Ex1472D1</ErrorCode>
                                   <ErrorParameters>
                                     <ErrorParameter>SMTP:user1@carius.de</ErrorParameter>
                                     <ErrorParameter>NAMPR20A001.PROD.OUTLOOK.COM/Microsoft Exchange Hosted
                             Organizations/fcarius.onmicrosoft.com/frank_carius.de#EXT#</ErrorParameter>
                                   </ErrorParameters>
                                   <ErrorDescription>The proxy address "SMTP:user1@carius.de" is already being used by the proxy addresses or LegacyExchangeDN of
                             "NAMPR20A001.PROD.OUTLOOK.COM/Microsoft Exchange Hosted Organizations/fcarius.onmicrosoft.com/frank_carius.de#EXT#". Please choose another
                             proxy address.</ErrorDescription>
                                 </ErrorRecord>
                               </ObjectErrors>
                               <LinkErrors />
                             </ServiceInstance>
                               Resolved: False
                               Service: exchange
                               Timestamp: 13.11.2018 20:21:01
                             }
                             }
ProxyAddresses             : {SMTP:user1@carius.de}
SipProxyAddress            :
State                      :
StreetAddress              :
Surname                    : Carius (contact)
TelephoneNumber            :

Wie sie sehen, legt er ein zweites Objekte an aber beschwert sich zugleich, dass dieses Objekte nicht die Mailadresse erhalten kann, da es schon ein anderes Objekt gibt. Wenn es also schon "Guest Access"-User gibt, die eine externe Mailadresse besetzen, dann können Sie nicht wirklich noch neue Benutzer anlegen.

Umgekehrt konnte ich aber problemlos erst einen Kontakt über AADConnect anlegen und danach einen neuen Gastbenutzer im AzureAD addieren, der die gleiche Mailadresse hat. So ganz konsistent ist das wohl noch nicht.

Weitere Links

Azure Active Directory B2B Collaboration: simple, secure external sharing of your Apps and Services
https://www.youtube.com/watch?v=AhwrweCBdsc