Azure AD Guest Accounts – Office 365 for IT Pros https://office365itpros.com Mastering Office 365 and Microsoft 365 Sun, 14 Apr 2024 19:47:03 +0000 en-US hourly 1 https://i0.wp.com/office365itpros.com/wp-content/uploads/2024/06/cropped-Office-365-for-IT-Pros-2025-Edition-500-px.jpg?fit=32%2C32&ssl=1 Azure AD Guest Accounts – Office 365 for IT Pros https://office365itpros.com 32 32 150103932 How to Purge Guest Accounts with Unredeemed Invitations from Entra ID https://office365itpros.com/2023/02/07/entra-id-guest-accounts-unredeemed/?utm_source=rss&utm_medium=rss&utm_campaign=entra-id-guest-accounts-unredeemed https://office365itpros.com/2023/02/07/entra-id-guest-accounts-unredeemed/#comments Tue, 07 Feb 2023 01:00:00 +0000 https://office365itpros.com/?p=58988

Use PowerShell to Find and Remove Entra ID Guest Accounts Who Don’t Want to Join Your Party

Updated 5 September 2023

A January 30 post by Microsoft’s Jef Kazimer about using Azure Automation with Managed Identities to remove unredeemed guests from Entra ID (Azure AD) promised to be a good read. Jef is a Principal Program Manager in the Microsoft Entra organization. Apart from using Azure Automation (something that every tenant administrator should master), highlighting the Microsoft Graph PowerShell SDK V2.0 (currently in early preview) gave me another reason to read the article.

I have expressed some concerns about Microsoft’s plans for the V2.0 of the Microsoft Graph PowerShell SDK. Leaving those concerns aside, it’s always good to learn how others approach a problem, especially as I’ve recently covered similar ground in terms of how to decide to remove guest accounts using the SDK. The differences between the two methods of reviewing guest accounts is that Jef looks for instances where guest accounts never went through the invitation redemption process to fully validate their accounts. On the other hand, my script looks at how long it’s been since a guest signed into the tenant and the number of groups the account is a member of to determine “staleness.” Let’s consider how to review guest accounts based on unredeemed invitations.

Outlining the Process

On paper, the steps involved to find and remove guest accounts with unredeemed invitations are straightforward:

  • Find guest accounts that have not redeemed the invitations received to join the tenant.
  • Remove the accounts from Entra ID.

Jef’s article suggests that this should be a regular process executed by an Azure Automation job using a managed identity to sign into the Graph and run the necessary PowerShell commands. I agree and think this is a good way to make sure to clear out unwanted guest accounts periodically.

Where I disagree is the detail of how to find the guests. Let’s discuss.

The Need for Administrative Units

Jef uses a dynamic administrative unit (currently a preview feature) to manage guest accounts. While it’s certainly convenient to create a dynamic administrative unit and assign the user management role for the administrative unit to the managed identity, this approach is optional and creates a potential requirement for Entra ID Premium P1 licenses. If your organization has those licenses, using a dynamic administrative unit offers the advantage of reducing the scope for the managed identity to process Entra ID accounts.

In some organizations, using administrative units (both the standard and dynamic variants) could be overkill because user management is a task performed by one or two administrators. In larger organizations, granularity in user management can be a desirable aspect, which is why administrative units exist.

Finding Entra ID Guest Accounts with Unredeemed Invitations

The first step is to find the target set of guest accounts. The simplest way is to run the Get-MgUser cmdlet and filter accounts to look for guests:

Connect-MgGraph -Scope Directory.ReadWrite.All
Select-MgProfile Beta
[array]$Guests = Get-MgUser -Filter "userType eq 'Guest'" -All

The guest accounts we want are those that have the ExternalUserState property set to “PendingAcceptance.” In other words, Entra ID issued an invitation to the guest’s email address, but the guest never followed up to redeem their invitation. This amended call to Get-MgUser fetches the set of guest accounts with unredeemed invitations:

[array]$Guests = Get-MgUser -Filter "userType eq 'Guest' and ExternalUserState eq 'PendingAcceptance'" -All

Jef’s version uses the Get-MsIDUnredeemedInviteUser cmdlet from the MSIdentityTools module to find guest accounts with unredeemed invitations. It’s certainly worth considering using the MSIdentityTools module to manage Entra ID, but it’s also worth understanding how to do a job with the basic tools, which is what I do here.

Determining the Age of an Unredeemed Invitation

It would be unwise to remove any Entra ID guest accounts without giving their owners a little time to respond. Taking vacation periods into account, 45 days seem sufficient time for anyone to make their minds up. The loop to remove unredeemed guest accounts needs to check how long it’s been since Entra ID issued the invitation and only process the accounts that exceed the age threshold.

Our script can check when Entra ID created an invitation by checking the ExternalUserStateChangeDateTime property, which holds a timestamp for the last time the state of the account changed. The only state change for the accounts we’re interested in occurred when Entra ID created the invitations to join the tenant, so we can use the property to measure how long it’s been since a guest received their invitation.

This code shows how to loop through the set of guests with unredeemed invitations, check if their invitation is more than 45 days old, and remove the account that satisfy the test. To keep a record of what it does, the script logs the deletions.

[datetime]$Deadline = (Get-Date).AddDays(-45)
$Report = [System.Collections.Generic.List[Object]]::new()
ForEach ($Guest in $Guests) {
  # Check Date
  [datetime]$InvitationSent = $Guest.ExternalUserStateChangeDateTime
  If ($InvitationSent -le $Deadline) {
     $DateInvitation = Get-Date($InvitationSent) -format g
     $DaysOld = (New-TimeSpan ($InvitationSent)).Days
     Try { 
        Remove-MgUser -UserId $Guest.Id
        $ReportLine = [PSCustomObject][Ordered]@{  
          Date        = Get-Date
          User        = $Guest.displayName
          UPN         = $Guest.UserPrincipalName
          Invited     = $DateInvitation
          "Days old"  = $DaysOld }
        $Report.Add($ReportLine)
      }
      Catch {
        Write-Error $_
      }
   } #End if
} #End Foreach Guest
Write-Host "Guest Accounts removed for" ($Report.User -Join ", ")

Figure 1 shows some data from the report generated for the deletions. In an Azure Automation scenario, you could create a report in SharePoint Online, send email to administrators, or post a message to a Teams channel to advise people about the removed accounts.

Old Entra ID guest accounts with unredeemed invitations
Figure 1: Old guest accounts with unredeemed invitations

Caveats Before Removing Entra ID Guest Accounts

The code works and stale guest account disappear to the Entra ID recycle bin. However, the danger exists that some of the accounts might be in active use. Take guest accounts created to represent the email addresses of Teams channels. These email addresses represent a connector to import messages into Teams channels. No one can sign into these non-existent mailboxes so no one  will ever redeem the guest invitations. However, the mail user objects created by Exchange Online for these guest accounts allow them to be included in distribution lists, added to address lists, and so on.

Another example is when a guest joins an Outlook group (a Microsoft 365 group whose membership communicates via email). Guest members of these groups do not need to redeem their invitation unless they intend to sign into the tenant to access Teams or SharePoint Online or another application that supports Azure B2B Collaboration. If you remove these guest accounts based on their invitation redemption status, some important email-based communication might fail, and that would be a bad thing.

One way around the issue is to mark Entra ID guest accounts used for these purposes by writing a value into an appropriate property. For instance, set the department to EMAIL. Here’s how to mark the set of guest accounts used to route email to Teams channels:

[array]$MailGuests = $Guests | Where-Object {$_.Mail -Like "*teams.ms*"}  
ForEach ($MG in $MailGuests) { Update-MgUser -UserId $MG.Id -Department "EMAIL" }

And here’s how to mark the guest members for an Outlook group using cmdlets from the Exchange Online management module:

[array]$Members = Get-UnifiedGroupLinks -Identity 'Exchange Grumpy Alumni' -LinkType Member
ForEach ($Member in $Members) { 
  If ($Member.RecipientType -eq "MailUser")  { Set-User -Identity $Member.Name -Department "EMAIL" -Confirm:$False }
}

After marking some guest accounts as exceptions, we can find the set of guest accounts to process with:

[array]$Guests = Get-MgUser -Filter "userType eq 'Guest'" -All | Where-Object {$_.ExternalUserState -eq "PendingAcceptance" -and $_.Department -ne "EMAIL"}

All of this goes to prove that setting out to automate what appears to be a straightforward administrative task might lead to unforeseen consequences if you don’t think through the different ways applications use the objects.

Using SDK V2.0

Coming back to using V2.0 of the Microsoft Graph PowerShell SDK, nothing done so far needs V2.0. The only mention of a V2.0-specific feature is the support for a managed identity when connecting to the Graph. The code used to connect is:

Connect-MgGraph -Identity

A one-liner is certainly convenient, but it’s possible to connect to a managed identity with the Graph SDK with code that is just a little more complicated. Here’s what I do:

Connect-AzAccount -Identity
$AccessToken = Get-AzAccessToken -ResourceUrl "https://graph.microsoft.com"
Connect-MgGraph -AccessToken $AccessToken.Token

Going from three lines to one is probably not a huge benefit!


So much change, all the time. It’s a challenge to stay abreast of all the updates Microsoft makes across Office 365. Subscribe to the Office 365 for IT Pros eBook to receive monthly insights into what happens, why it happens, and what new features and capabilities mean for your tenant.

]]>
https://office365itpros.com/2023/02/07/entra-id-guest-accounts-unredeemed/feed/ 3 58988
Reporting Group Membership for Azure AD Guest Accounts with the Microsoft Graph PowerShell SDK https://office365itpros.com/2023/01/18/old-azure-ad-guest-accounts/?utm_source=rss&utm_medium=rss&utm_campaign=old-azure-ad-guest-accounts https://office365itpros.com/2023/01/18/old-azure-ad-guest-accounts/#comments Wed, 18 Jan 2023 01:00:00 +0000 https://office365itpros.com/?p=58742

Finding Azure AD Guest Accounts in Microsoft 365 Groups

The article explaining how to report old guest accounts and their membership of Microsoft 365 Groups (and teams) in a tenant is very popular and many people use its accompanying script. The idea is to find guest accounts above a certain age (365 days – configurable in the script) and report the groups these guests are members of. Any old guest accounts that aren’t in any groups are candidates for removal.

The script uses an old technique featuring the distinguished name of guest accounts to scan for group memberships using the Get-Recipient cmdlet. The approach works, but the variation of values that can exist in distinguished names due to the inclusion of characters like apostrophes and vertical lines means that some special processing is needed to make sure that lookups work. Achieving consistency in distinguished names might be one of the reasons for Microsoft’s plan to make Exchange Online mailbox identification more effective.

In any case, time moves on and code degrades. I wanted to investigate how to use the Microsoft Graph PowerShell SDK to replace Get-Recipient. The script already uses the SDK to find Azure AD guest accounts with the Get-MgUser cmdlet.

The Graph Foundation

Graph APIs provide the foundation for all SDK cmdlets. Graph APIs provide the foundation for all SDK cmdlets. The first thing to find is an appropriate API to find group membership. I started off with getMemberGroups. The PowerShell example for the API suggests that the Get-MgDirectoryObjectMemberGroup cmdlet is the one to use. For example:

$UserId = (Get-MgUser -UserId Terry.Hegarty@Office365itpros.com).id 
[array]$Groups = Get-MgDirectoryObjectMemberGroup  -DirectoryObjectId $UserId -SecurityEnabledOnly:$False

The cmdlet works and returns a list of group identifiers that can be used to retrieve information about the groups that the user belongs to. For example:

Get-MgGroup -GroupId $Groups[0] | Format-Table DisplayName, Id, GroupTypes

DisplayName                     Id                                   GroupTypes
-----------                     --                                   ----------
All Tenant Member User Accounts 05ecf033-b39a-422c-8d30-0605965e29da {DynamicMembership, Unified}

However, because Get-MgDirectoryObjectMemberGroup returns a simple list of group identifiers, the developer must do extra work to call Get-MgGroup for each group to retrieve group properties. Not only is this extra work, calling Get-MgGroup repeatedly becomes very inefficient as the number of guests and their membership in groups increase.

Looking Behind the Scenes with Graph X-Ray

The Azure AD admin center (and the Entra admin center) both list the groups that user accounts (tenant and guests) belong to. Performance is snappy and it seemed unlikely that the code used was making multiple calls to retrieve the properties for each group. Many of the sections in these admin centers use Graph API requests to fetch information, and the Graph X-Ray tool reveals those requests. Looking at the output, it’s interesting to see that the admin center uses the beta Graph endpoint with the groups memberOf API (Figure 1).

Using the Graph X-Ray tool to find the Graph API for group membership

Azure AD Guest Accounts
Figure 1: Using the Graph X-Ray tool to find the Graph API for group membership

We can reuse the call used by the Azure AD center to create the query (containing the object identifier for the user account) and run the query using the SDK Invoke-MgGraphRequest cmdlet. One change made to the command is to include a filter to select only Microsoft 365 groups. If you omit the filter, the Graph returns all the groups a user belongs to, including security groups and distribution lists. The group information is in an array that’s in the Value property returned by the Graph request. For convenience, we put the data into a separate array.

$Uri = ("https://graph.microsoft.com/beta/users/{0}/memberOf/microsoft.graph.group?`$filter=groupTypes/any(a:a eq 'unified')&`$top=200&$`orderby=displayName&`$count=true" -f $Guest.Id)
[array]$Data = Invoke-MgGraphRequest -Uri $Uri
[array]$GuestGroups = $Data.Value

Using the Get-MgUserMemberOf Cmdlet

The equivalent SDK cmdlet is Get-MgUserMemberOf. To return the set of groups an account belongs to, the command is:

[array]$Data = Get-MgUserMemberOf -UserId $Guest.Id -All
[array]$GuestGroups = $Data.AdditionalProperties

The format of returned data marks a big difference between the SDK cmdlet and the Graph API request. The cmdlet returns group information in a hash table in the AdditionalProperties array while the Graph API request returns a simple array called Value. To retrieve group properties from the hash table, we must enumerate through its values. For instance, to return the names of the Microsoft 365 groups in the hash table, we do something like this:

[Array]$GroupNames = $Null
ForEach ($Item in $GuestGroups.GetEnumerator() ) {
   If ($Item.groupTypes -eq "unified") { $GroupNames+= $Item.displayName }
}
$GroupNames= $GroupNames -join ", "

SDK cmdlets can be inconsistent in how they return data. It’s just one of the charms of working with cmdlets that are automatically generated from code. Hopefully, Microsoft will do a better job of ironing out inconsistencies when they release V2.0 of the SDK sometime later in 2023.

A Get-MgUserTransitiveMemberOf cmdlet is also available to return the membership of nested groups. We don’t need to do this because we’re only interested in Microsoft 365 groups, which don’t support nesting. The cmdlet works in much the same way:

[array]$TransitiveData = Get-MgUserTransitiveMemberOf -UserId Kim.Akers@office365itpros.com -All

The Script Based on the SDK

Because of the extra complexity in accessing group properties, I decided to use a modified version of the Graph API request from the Azure AD admin center. It’s executed using the Invoke-MgGraphRequest cmdlet, so I think the decision is justified.

When revising the script, I made some other improvements, including adding a basic assessment of whether a guest account is stale or very stale. The assessment is intended to highlight if I should consider removing these accounts because they’re obviously not being used. Figure 2 shows the output of the report.

Report highlighting potentially obsolete guest accounts
Figure 2: Report highlighting potentially obsolete Azure AD guest accounts

You can download a copy of the script from GitHub.

Cleaning up Obsolete Azure AD Guest Accounts

Reporting obsolete Azure AD guest accounts is nice. Cleaning up old junk from Azure AD is even better. The script generates a PowerShell list with details of all guests over a certain age and the groups they belong to. To generate a list of the very stale guest accounts, filter the list:

[array]$DeleteAccounts = $Report | Where-Object {$_.StaleNess -eq "Very Stale"}

To complete the job and remove the obsolete guest accounts, a simple loop to call Remove-MgUser to process each account:

ForEach ($Account in $DeleteAccounts) {
   Write-Host ("Removing guest account for {0} with UPN {1}" -f $Account.Name, $Account.UPN) 
   Remove-MgUser -UserId $Account.Id }

Obsolete or stale guest accounts are not harmful, but their presence slows down processing like PowerShell scripts. For that reason, it’s a good idea to clean out unwanted guests periodically.


Learn about mastering the Microsoft Graph PowerShell SDK and the Microsoft 365 PowerShell modules by subscribing to the Office 365 for IT Pros eBook. Use our experience to understand what’s important and how best to protect your tenant.

]]>
https://office365itpros.com/2023/01/18/old-azure-ad-guest-accounts/feed/ 2 58742
Adding QR Codes to Microsoft Authenticator for Entra ID Guest Accounts https://office365itpros.com/2023/01/04/microsoft-authenticator-app-qr/?utm_source=rss&utm_medium=rss&utm_campaign=microsoft-authenticator-app-qr https://office365itpros.com/2023/01/04/microsoft-authenticator-app-qr/#comments Wed, 04 Jan 2023 01:00:00 +0000 https://office365itpros.com/?p=58395

Moving to a New Mobile Phone Means New Codes for the Microsoft Authenticator App

Moving to a new mobile device always involves a certain amount of hassle. The advent of mobile authenticator apps makes the move a little harder, especially when guest accounts on other tenants are involved.

In my case, I moved from an oldish iPhone 11 to a new iPhone 14. I was very happy with the 11 and used it since 2019. However, its battery showed signs of age and I fancied a change, which is all the reason I needed to get the 14.

Moving apps from an old iPhone to a new device is very easy. Minor hassles like making Outlook the default mail app for iOS and adding Teams to the pinned app list are easily overcome. It’s all the messing around with app passwords and authentication that causes the hassle.

Which brings me to the Microsoft Authenticator app. I am a strong proponent of multi-factor authentication and use the authenticator app to protect my Microsoft 365 and other accounts, including services like GitHub and Twitter. The app has a backup and recovery capability that I used to restore details of the accounts I use with authenticator. Unhappily (as noted in the support article), “Only your personal and non-Microsoft account credentials are stored, which includes your username and the account verification code that’s required to prove your identity.”

MFA Responses by Microsoft Authenticator App Need Device-Specific Credentials

For Microsoft school or work (Entra ID) accounts, the article explains that accounts that use push notifications (like MFA challenges) need additional verification to recover information. Push notifications require using a credential tied to a specific device. To restore accounts protected by MFA using the authenticator app on the new phone, this means that “you must scan a QR code given to you by your account provider.

The key to getting a new QR code for your Entra ID account is the Security info section of the My account page. After signing into your account, this section displays the sign-in methods used to access your account (Figure 1). This is the same kind of information that’s available when examining authentication methods for user accounts with the Microsoft Graph PowerShell SDK.

Listing sign-in methods for an Entra ID account
Figure 1: Listing sign-in methods for an Entra ID account

Note: If a user can’t access the My account page because they don’t have access to their old phone and therefore cannot respond to an MFA challenge, an administrator can temporarily downgrade the MFA requirement to SMS to allow the user to sign in and access the page.

Adding a QR Code for a New Device

Remember that the credential used by the Microsoft Authenticator app to respond to MFA challenges is device-specific. To generate a new QR code, click Add sign-in method and select Authenticator app from the list of options. You’ll then be told that you need to install the app, which is fine because it’s already on the device. Click Next to start the setup process and click Next again to see a new QR code for the app (Figure 2).

enerating a new QR code for the Microsoft Authenticator app
Figure 2: Generating a new QR code for the Microsoft Authenticator app

You can scan the code using Authenticator and once this happens, the connection between account, app, and credential works. The process includes a verification step to prove that the Authenticator app can use the credential.

After setting up Authenticator for a new device, you’ll have multiple Microsoft Authenticator entries in your sign-in methods list (one per device). It’s perfectly safe to remove the entries for devices that you no longer use.

Adding a QR Code for a Guest Account

Everything works very nicely for a full tenant account. Generating a QR code to allow Authenticator to satisfy MFA challenges for a guest account is a little more complicated. I have guest accounts in multiple Microsoft 365 organizations, mostly because I am a guest member of Teams in those organizations. Let’s assume that you see that a guest account shows up in Authenticator flagged with “Action required” (Figure 3). This means that Authenticator can’t satisfy challenges for this account because it doesn’t have the necessary credentials.

The Microsoft Authenticator app flags that action is needed to fix an account
Figure 3: The Microsoft Authenticator app flags that action is needed to fix an account

To secure the credentials for the account, the trick is to use the option to switch organizations via the icon in the top right-hand corner of the My Account page. This reveals the set of organizations that your account belongs to, starting with your account in the home tenant and then listing the organizations (aka host tenants) where you have a guest account (Figure 4).

Selecting an organization where an account is a guest
Figure 4: Selecting an organization where an account is a guest

Switching to another organization uses your account (the guest account in this case) to sign-into that organization. You can then use the Security Info page to go through the same steps to generate a new QR code and add it to the entry for the guest account in the Authenticator app. The Authenticator app should now be able to satisfy MFA challenges for the guest account when signing into the target organization.

Microsoft Authenticator App Restored to Good Health

Moving to a new iPhone isn’t something people do every day and it’s easy to forget how to renew credentials in different services. Getting new QR codes for the Authenticator app is in that category. Fortunately, the process isn’t quite as painful as I first anticipated after restoring the backup to my new phone and everything is now working as expected.

PS. If you use the Authenticator app on an Apple Watch, remember that from January 2023, the Authenticator app no longer supports WatchOS. Microsoft says that WatchOS is “incompatible with Authenticator security features.” I read that to mean that some of the changes Microsoft made recently to harden Authenticator against MFA fatigue like number matching and additional context just don’t work in the constrained real estate available for watch devices.

]]>
https://office365itpros.com/2023/01/04/microsoft-authenticator-app-qr/feed/ 6 58395
Guest Accounts Can’t Update Their Photos with the Microsoft Graph PowerShell SDK https://office365itpros.com/2022/06/07/azure-ad-guest-account-photo/?utm_source=rss&utm_medium=rss&utm_campaign=azure-ad-guest-account-photo https://office365itpros.com/2022/06/07/azure-ad-guest-account-photo/#respond Tue, 07 Jun 2022 01:00:00 +0000 https://office365itpros.com/?p=55373

Upgrading Scripts to Use New Cmdlets

Microsoft plans to deprecate the Azure AD and Microsoft Online Services (MSOL) PowerShell modules in late 2022 or early 2023. Apart from the license management cmdlets, the other cmdlets in these modules will continue to work but will be unsupported. Eventually, the cmdlets will stop working, so the time is ripe for upgrading scripts and seeking new ways of getting things done, like how to manage Azure AD guest accounts.

In most cases, it’s possible to upgrade scripts by replacing Azure AD cmdlets with cmdlets from the Microsoft Graph PowerShell SDK. As we prepare for the launch of the Office 365 for IT Pros (2023 Edition) eBook, we’re going through all the Azure AD and MSOL code examples in the book to replace as many as possible with either Microsoft Graph API queries or SDK cmdlets. Microsoft publishes a useful cmdlet map to help developers match old cmdlets with suitable replacements.

Sometimes, it’s not yet possible to replace a cmdlet because Microsoft doesn’t yet provide a direct equivalent in the Graph. In these instances, we’re leaving the older code in place because it will continue to work. When a suitable replacement is available, we’ll update the book with new Graph-based code.

It’s Good to Use Photos with Azure AD Accounts

We recommend that tenant administrators add photos for all Azure AD accounts, both regular user accounts and guest accounts. Having a face to recognize makes it easier to appreciate who’s involved in sharing a document or participating in a channel conversation in Teams. Tenant administrators are busy people, and even if they devote time to “guest hygiene” (cleaning up unwanted or obsolete guest accounts), they might not get around to adding photos for guest accounts via the Azure AD admin center or PowerShell. This is why it’s good if guest accounts can update their own photos.

In April 2021, I wrote about how to use cmdlets from the Azure AD PowerShell module to update the photo for your Azure AD guest account in another Microsoft 365 tenant. It’s a relatively straightforward procedure that’s facilitated by the way the Azure AD module works. Once you have a connection to a tenant, you can work with accounts and other objects the signed-in account can access. In this instance, your guest account.

Time moves on and it was time to upgrade the example showing how guests can upload their own photos. Unhappily, although the Set-MgUserPhotoContent cmdlet is available to replace the Set-AzureADUserThumbNailPhoto cmdlet, the technique of connecting to a target tenant with a guest account to update the account photo doesn’t work. At least, it doesn’t work unless the target tenant meets specific criteria.

Experimenting with the Microsoft Graph PowerShell SDK

I experimented with several target tenants where I have guest accounts to see what’s possible. The Connect-MgGraph cmdlet is happy to connect to a tenant and you can sign in with your guest account. At this point, things go wrong. Once you connect with the Azure AD module, you can update the guest account as described in the post referenced above.

However, the Microsoft Graph takes a more restrictive approach to permissions (or scope). Administrators must grant consent to the service principal used for interactive sessions with the Microsoft Graph PowerShell SDK for the permissions to interact with user accounts. In this case, consent must be in place for the User.ReadWrite.All permission before it’s possible to update a user account (or guest account) with a photo. Interactive sessions with the PowerShell SDK use delegated permissions, so even though the permission is User.ReadWrite.All (implying access to all mailboxes), the Graph constrains the scope of the permission to the signed-in user.

Our renowned technical editor, Vasil Michev, thought that he had solved the problem and published a note to that effect. Unhappily, further investigation proved that using the Microsoft Graph PowerShell SDK to connect to a target tenant to update the photo for a guest account only works if the service principal for the Microsoft Graph PowerShell enterprise app (application id 14d82eec-204b-4c2f-b7e8-296a70dab67e) has consent for the User.ReadWrite.All permission.

The Service Principal Question

Meeting these requirements means that someone has run Connect-MgGraph at some time in the past in the target tenant. This action creates the service principal if it’s not already known to Azure AD. If the service principal doesn’t exist in the target tenant, Connect-MgGraph cannot proceed until an administrator signs in to create the service principal (Figure 1). After the creation of the service principal, it can receive consent to use permissions, including User.ReadWrite.All.

Azure AD prompts to create the service principal for the Microsoft Graph PowerShell SDK

Azure AD Guest Account
Figure 1: Azure AD prompts to create the service principal for the Microsoft Graph PowerShell SDK

Although these conditions might exist for some tenants, there’s no guarantee that the service principal exists and holds the permission. For example, connecting to the Microsoft tenant with a guest account reveals that the User.Read permission is available, but the User.ReadWrite.All permission is not.

Disconnect-MgGraph
Connect-MgGraph -TenantId 72f988bf-86f1-41af-91ab-2d7cd011db47
Welcome To Microsoft Graph!
Get-Mgcontext

ClientId              : 14d82eec-204b-4c2f-b7e8-296a70dab67e
TenantId              : 72f988bf-86f1-41af-91ab-2d7cd011db47
CertificateThumbprint :
Scopes                : {openid, profile, User.Read, email}
AuthType              : Delegated
AuthProviderType      : InteractiveAuthenticationProvider
CertificateName       :
Account               :
AppName               : Microsoft Graph PowerShell
ContextScope          : CurrentUser
Certificate           :
PSHostVersion         : 5.1.22000.653
ClientTimeout         : 00:05:00

In a nutshell, it’s possible to use the Microsoft Graph PowerShell SDK to update photos for guest accounts in other tenants, but only when the conditions are exactly right.

That Permissioned Service Principal

In closing, let me note once again the cumulative nature of the service principal used by the Microsoft Graph PowerShell SDK. If an administrator consents to a permission for use with the Graph SDK, that permission remains assigned to the service principal unless an administrator removes it. Over time, permissions accrue, and the service principal becomes highly permissioned. This makes it easy for tenant administrators to run SDK cmdlets in interactive sessions, but it’s possibly not what you want to happen. On the upside, interactive sessions use delegated permissions rather than application permissions, so the Graph won’t allow the signed-in user to access data that they couldn’t otherwise open. Which is nice to know.

]]>
https://office365itpros.com/2022/06/07/azure-ad-guest-account-photo/feed/ 0 55373
Don’t Give Up on Azure AD Guest Accounts https://office365itpros.com/2022/06/06/azure-ad-guest-accounts-valuable/?utm_source=rss&utm_medium=rss&utm_campaign=azure-ad-guest-accounts-valuable https://office365itpros.com/2022/06/06/azure-ad-guest-accounts-valuable/#comments Mon, 06 Jun 2022 01:00:00 +0000 https://office365itpros.com/?p=55362

Azure B2B Collaboration Likely to be Dominant for Immediate Future

The introduction of shared channels in Teams is a big deal, as is the advent of Azure AD Direct Connect, the vital underpinning that enables tenants to accept the credentials granted to accounts in other Microsoft 365 tenants. Cross-tenant access policies control who can share channels in your organization and who can share channels in other organizations.

Some might have missed the news that cross-tenant access settings can also control Azure B2B collaboration (guest accounts). This is also a big step forward because it addresses the need some tenant administrators have expressed to be able to control the organizations where their users can join groups using Azure AD guest accounts. Control over inbound guests has been available with the Azure AD B2B Collaboration policy for several years, so adding outbound control is welcome.

Sharing with Teams

Last week, Microsoft posted about the ways to collaborate externally using Teams. The descriptions of Azure AD Direct Connect, Azure B2B Collaboration, and external federation (one-to-one chat and calls with people in other organizations) were accurate, and the information was well-timed. Many Microsoft 365 tenants are figuring out their external collaboration strategy and wondering where to put their effort over the coming years,

I’ve heard a few commentators say that Azure AD guest accounts now have limited usefulness. The theory is that everyone will move to shared channels. I think that’s overstating the case more than a little. Shared channels are very convenient, especially in their accessibility. There’s no need to switch to another tenant to access information. Shared channels are right there, listed by your favorite Teams client alongside the other teams and channels from your home tenant.

For now, shared channels are only sharable with accounts from other Microsoft 365 tenants. Shared channels will reveal their full potential when they support access from Microsoft Services Accounts (MSAs), a feature that Microsoft is working on.

Azure AD Guest Accounts Still Super-Valuable

But even when that happens, I think Azure AD guest accounts still continue to offer a lot of value. Switching to another tenant can slow access down a tad, but switching performance is much faster now than it used to be (even if it’s not one of the improvements listed in Microsoft’s latest news about Teams performance), and I think I am now immune to the need to switch to a tenant to collaborate with people in that organization. Muscle memory is a great thing and it’s one of the reasons why many of the teams I use feature lots of Azure AD guest accounts (Figure 1).

Team with multiple Azure AD guest accounts in its membership
Figure 1: Azure AD Guest Accounts are a big part of a many teams

Once added to a tenant, a guest has full access to the teams and groups they are a member of. Within a single team, they can access up to 200 regular channels and, if added as a member, they can participate in another 30 private channels. A shared channel has its own roster of members and if a team supports multiple shared channels, the channel owner must share with external users in each channel.

Most of the external organizations I work with have teams with multiple channels. Some are channel-happy and explore the limits set by Teams. Others are more restrained. Even so, the teams usually have several channels to support discussions about different topics. Private channels don’t seem to be popular but are present and I use some in other tenants. Shared channels might be a better choice than private channels in many cases, especially when MSA support is available.

The Question of Guest Hygiene

Mention guest hygiene and you’re probably thinking about the mess unwelcome guests can make in your house. Microsoft says that using Azure B2B Collaboration means that organizations should implement “a guest hygiene process to remove guest accounts when no longer needed.” In other words, instead of remaining passive and letting Azure AD guest accounts accumulate over time, organizations should review old guest accounts and figure out if they should remain.

A simple check against age will often highlight unused guest accounts. If you have Azure AD Premium P2 licenses, Microsoft offers a more sophisticated account review process. No matter what approach you take, it’s a good idea to run an annual review to clean out old accounts.

Overall, it’s likely that Azure AD guest accounts will remain the foundation for most external collaboration based on Microsoft 365 groups and teams. Shared channels will nibble away and take some of the work, but it won’t take over from Azure AD guest accounts in the immediate future.

]]>
https://office365itpros.com/2022/06/06/azure-ad-guest-accounts-valuable/feed/ 2 55362