Multiple Techniques Available to Stop People Connecting

A recent article about using PowerShell to control Azure AD conditional access policies caused me to start thinking about the techniques used to block user access to Office 365. Four years ago, I considered the problem in a Petri.com article inspired by a French law to allow people to disconnect over the weekend. In places other than France, the need to preserve space between personal and work time became more evident as the Covid-19 pandemic forced many people to work from home. Some worked more, some worked less, and the line between personal and work time blurred. Now, the advance of time and development in technology combine to make it reasonable to revisit the problem.

Update: Microsoft has implemented continual access evaluation (CAE) for critical events like password changes or account blocks in all tenants. The net effect of CAE is that depriving user access to an account works much faster (almost immediately).

Stopping Email Connections Temporarily or Permanently

The issue of disabling service to users isn’t just about stopping people working over the weekend or when they are on vacation. It also applies when people leave a company. Over the years, different techniques have evolved, originally for email connectivity because that’s where the problem first surfaced.

Because Exchange Online supports a rich set of connectivity protocols for mailboxes, you can disable individual protocols by running the Set-CASMailbox cmdlet. In this example, we disable mobile connectivity for a mailbox for both Exchange ActiveSync (EAS) and the Microsoft sync technology used by Outlook mobile:

Set-CASMailbox -Identity Ken.Bowers@Office365itpros.com -ActiveSyncEnabled:$False
Set-CASMailbox -Identity Ken.Bowers@Office365itpros.com -OutlookMobileEnabled:$False

Why disable both protocols? Outlook mobile uses the Microsoft sync technology to enable many advanced features like delegate access to mailboxes, but other clients like the mail apps included in the iOS and Android operating systems use EAS for basic email connectivity with Exchange Online. If you don’t disable both, you create a situation where a user can still connect to their mailbox with a different app. In fact, for completeness, you should also disable the IMAP4 and POP3 protocols to close off any chance that a mobile device can connect to a mailbox.

The weakness of concentrating on disabling protocols is that some information leakage can still occur. Take the example of Outlook mobile. You can disable the Microsoft sync technology to stop clients sending messages and downloading messages to the device, but both iOS and Android use services to notify users of the arrival of new messages. The notifications contain snippets about new messages to allow users to decide if they need to read the full message. These notifications keep on arriving after you disable the sync protocol.

In reality, if you’re serious about controlling mobile devices, you need to deploy a mobile device management (MDM) solution like Intune which allows you to remote wipe corporate data from the device when necessary.

Stopping Access to Office 365

Email is not the only app which steals time over the weekend. Teams, Planner, Yammer, SharePoint Online, and OneDrive for Business all consume hours if people allow. The classic method to block access is to block someone’s Azure AD account. This can be done through the Microsoft 365 admin center by selecting the account and choosing Block sign-in (Figure 1).

How to Block User Access to Microsoft 365 Accounts
Figure 1: Blocking a user’s Azure AD account in the Microsoft 365 admin center.

Blocking the account sets the AccountEnabled property in Azure AD to False. When an account is disabled, the user cannot sign into their Azure AD account:

A user is blocked from signing into their Azure AD account
Figure 2: A user is blocked from signing into their Azure AD account.

Forcing Sign-Outs from Apps

Blocking an account from signing in also sets the RefreshTokensValidFromDateTime property for the account to the date and time the action occurred. The effect is to invalidate the refresh tokens issued to applications for a user and tokens issued to session cookies in browsers and forces the user to reauthenticate to continue using the apps. The Microsoft 365 admin center includes an option to sign a user out of all sessions, so you can do this without blocking an account.

You can also force a sign-out for an account with PowerShell by running the Revoke-AzureADUserAllRefreshToken cmdlet:

Revoke-AzureADUserAllRefreshToken -ObjectId Ken.Bowers@Office365ITPros.com

Resetting sign-ins for an account sets RefreshTokensValidFromDateTime to the current date and time and AccountEnabled to True. The user can now sign in. When this happens, browsers and apps receive new valid tokens. It can take up to 15 minutes before the user can sign into all apps.

Blocking Accounts with PowerShell

Three different PowerShell cmdlets can influence the ability of users to access their accounts. The first two block access to the Azure AD account; the third blocks access to the Exchange Online mailbox:

Set-MsolUser -UserPrincipalName Ken.Bowers@Office365itpros.com -BlockCredential $True
Set-AzureADUser -ObjectID Ken.Bowers@Office365itpros.com -AccountEnabled $False
Set-Mailbox -Identity Ken.Bowers@Office365itpros.com -AccountDisabled:$True

Set-AzureADUser is the preferred cmdlet. It is newer than Set-MsolUser and if you’re going to block access to an account, you should block complete access to all apps rather than just email. Also, when you block an account, the action blocks the mailbox (if provisioned), including forward synchronization to mobile devices. The recommended approach is therefore to run Set-AzureADUser followed by Revoke-AzureADUserAllRefreshToken to ensure the account is blocked with a forced sign-out for all apps.

Implementing a Weekend Block

Coming back to the original issue, which is how to disconnect people from Office 365 for one reason or another. Let’s assume that we only want this to happen for a certain category of user, such as those who work in a specific country. If those people are members of a group, we can use that group to drive the disconnect process. In this example, a distribution list defines the accounts to disconnect:

[Array]$Accounts = Get-DistributionGroupMember -Identity "BlockWeekend" | Select WindowsLiveID, ExternalDirectoryObjectId

ForEach ($Account in $Accounts) {
   Write-Host "Turning Off Office 365 Access for" $Account.WindowsLiveID
   Set-AzureADUser -ObjectId $Account.ExternalDirectoryObjectId -AccountEnabled $False
   Revoke-AzureADUserAllRefreshToken -ObjectId $Account.ExternalDirectoryObjectId  }

A dynamic distribution list might be a better choice because the membership is then driven by properties such as country or city. To fetch the set of users of a dynamic distribution list, we use the recipient filter for the list to find the members:

$AccountFilter = (Get-DynamicDistributionGroup -Identity "French Country Users").RecipientFilter
[Array]$Accounts = Get-Recipient -RecipientPreviewFilter $AccountFilter | Select WindowsLiveID, ExternalDirectoryObjectId

Of course, you can use the Get-AzureADGroupMember cmdlet to fetch details of group members if you prefer. For example:

[array]$Accounts = Get-AzureADGroup -SearchString BlockWeekend | Get-AzureADGroupMember | Select UserPrincipalName, ObjectId

This syntax works with distribution lists, security groups, Microsoft 365 groups, and dynamic Microsoft 365 groups. It doesn’t work with dynamic distribution lists because these objects don’t exist in Azure AD.

The task to disconnect users is straightforward. Every Friday night, we run the PowerShell script to disable access and run another script to reverse the process on Monday morning. The big downside is the way Teams processes blocked accounts to remove them from team rosters (without affecting the group membership). If you can live with this issue while Microsoft considers how to improve the situation, then blocking accounts for short periods might work for your organization.

Using a Conditional Access Policy

Azure AD conditional access policies run after a user successfully authenticates to decide whether they can connect to the requested resource. Membership of a group is one of the supported conditions, meaning that it is easy to create a policy to block access to apps for a group. Because it’s weekend access we want to block, we could add another condition to say that access is OK if the user is in a corporate location, but not if they are at home or anywhere else.

Figure 3 shows the outlines of such a policy. Anyone specified in the Blocked Weekend distribution list (you can also use a security group or Microsoft 365 group) is blocked if they attempt to access an Office 365 app:

How to Block User Access to Microsoft 365 Accounts
Figure 3: Defining a conditional access policy to block user access.

When a user attempt to access an app is blocked by a conditional access policy, they are told that their sign in was successful (authentication worked), but they don’t have permission to access the resource:

A user is blocked by a conditional access policy
Figure 4: A user is blocked by a conditional access policy.

If they are already connected to an app and the app attempts to renew its access token, the conditional access policy will block issuance of the token. Figure 5 shows what the user sees when this happens in Teams (the app is very polite!):

Teams tells the user that it can't get a token
Figure 5: Teams tells the user that it can’t get a token.

Controlling Conditional Access Policies with PowerShell

Conditional access policies allow organizations to exert granular control over the access users have to apps. In our scenario, we want to allow free access during the week. We could disable the conditional access policy during the working week and enable it just for the weekend. This is easily done by editing the policy in the Azure AD portal or with PowerShell. For example, here’s how to enable the policy:

$PolicyId = Get-AzureADMSConditionalAccessPolicy | ? {$_.DisplayName -eq "Block Weekend Access"} | Select -ExpandProperty Id

Set-AzureADMSConditionalAccessPolicy -PolicyId $PolicyId -State Enabled

To disable the policy after the weekend, run:

Set-AzureADMSConditionalAccessPolicy -PolicyId $PolicyId -State Disabled

Changing Conditional Access Policy Conditions

But because we want to illustrate the possibilities which exist to work with conditional access policies through PowerShell, let’s assume that the policy is always active because it’s used during the week to limit access for some users (identified by a group) to certain locations. Over the weekend, we need to update the policy with a different group.

The users blocked by a conditional access policy is defined as a policy condition. To see what users are affected by a policy, we can examine its conditions. Here we see that a single group is included in the policy:

((Get-AzureADMSConditionalAccessPolicy -PolicyId $PolicyId).Conditions).Users

IncludeUsers  : {}
ExcludeUsers  : {}
IncludeGroups : {468a9356-cf88-4189-bf85-40b096e3c37f}
ExcludeGroups : {}
IncludeRoles  : {}
ExcludeRoles  : {}

We know this is a group rather than an individual user because it’s listed in the IncludeGroups condition. The group is referenced by its unique Azure AD identifier (a GUID). To find out which group is listed, run the Get-AzureADGroup cmdlet:

Get-AzureADGroup -ObjectId 468a9356-cf88-4189-bf85-40b096e3c37f

ObjectId                             DisplayName                      Description
--------                             -----------                      -----------
468a9356-cf88-4189-bf85-40b096e3c37f Users Blocked for Weekend Access

To switch out one group for another in a policy, we need to:

  • Create a condition set for a conditional access policy. The condition set is built from different types of condition. We are interested in:
    • Applications: This is set to All.
    • Locations: This defines the locations (defined in Azure AD for use with conditional access policies) used by the policy. In our case, we want the policy to apply everywhere except to a location for our HQ.
    • Users: This is what we need to change to switch one group for another.
    • Client app types. This is set to All.
  • Populate the condition set with values.
  • Write the new condition set into the conditional access policy. You overwrite the existing set with a new set.

Here’s an example of code to update our conditional access policy. You can see that the GUID for a different group is written into the condition set:

# Create new condition set
$BlockedUsers = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessConditionSet
# Block all applications
$BlockedUsers.Applications = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessApplicationCondition
$BlockedUsers.Applications.IncludeApplications = "All"
# Add location to exclude (HQ Office)
$BlockedUsers.Locations = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessLocationCondition
$BlockedUsers.Locations.ExcludeLocations = "6ff84108-eab2-4bba-bcea-c952075c2c9f"
$BlockedUsers.Locations.IncludeLocations = "All"
# Add group we want to block
$BlockedUsers.Users = New-Object -TypeName Microsoft.Open.MSGraph.Model.ConditionalAccessUserCondition
$BlockedUsers.Users.IncludeGroups = "64d314bb-ea0c-46de-9044-ae8a61612a6a"
$BlockedUsers.ClientAppTypes = "All"
Set-AzureADMSConditionalAccessPolicy -PolicyId $PolicyId -Conditions $BlockedUsers

Within a few minutes, the updated conditional access policy is effective, and the block is in place.

To reverse the process after the weekend is over, create a new condition set, update the set with the GUID for the original group, and update the policy.

Options and Choices

Conditional access policies require Azure AD Premium licenses. If you’ve already got these licenses, and therefore have invested in conditional access, adding a new policy to control weekend access is not difficult. Being able to control the policies with PowerShell makes it easier to automate switching access on or off on automatic basis.

On the other hand, if you don’t have Azure AD Premium licenses, you can still block user accounts with a few lines of PowerShell. And if you don’t want to block access and simply remind people that they should do less work at the weekend, maybe the technique of using a transport rule to stamp “right to disconnect” disclaimers on internal mail is a good way to go.

Choice is nice…

About the Author

Tony Redmond

Tony Redmond has written thousands of articles about Microsoft technology since 1996. He is the lead author for the Office 365 for IT Pros eBook, the only book covering Office 365 that is updated monthly to keep pace with change in the cloud. Apart from contributing to Practical365.com, Tony also writes at Office365itpros.com to support the development of the eBook. He has been a Microsoft MVP since 2004.

Comments

  1. Narayanan

    We disabled OWA in intune. Then how exchange office and Microsoft business basic license users access their Outlook?

    1. Tony Redmond

      Disabling OWA only removes one client. They can use Outlook desktop or Outlook mobile (or any IMAP4, POP3, or ActiveSync client).

  2. Brom

    Hi

    Is there any way to block access only to OWA?

    Tried to configure conditional access policy to block Exchange Online, but the warning appear “Selecting Office 365 Exchange Online will also affect apps such as OneDrive and Teams”.

    I would appreciate your help.

    1. Pablo

      Let’s try set-casmailbox
      Regards

  3. Vinod

    Hi,

    How to block guest user access to teams in bulk via PowerShell?

    We have around 700 hundred teams and want to block guest users access to those teams.
    Please help us with this.

Leave a Reply