Force Teams to Sign Out

Token Resistance

I ran into an interesting scenario yesterday during a tenant migration where users from tenant A were successfully migrated to Tenant B, but their accounts remained logged into Teams – even changing the user account names to their onmicrosoft.com domain and removing their Teams license wouldn’t force them to log out… talk about a token that won’t quit!

The goal here was that the users would log out of Teams – and since their old UPNs were changed behind the scenes – when they tried to log back in using their regular username and password, they’d be passed into the new tenant instead of remaining in the old one. However, this was not happening, and users were remaining signed in to the old tenant – very frustrating!

Initiate Sign-out (the Ctrl-Alt-Del of the cloud)

Now, you should normally be able to force this logout by going to the admin portal, clicking on the user account, then the OneDrive tab, and using the Initiate sign-out option:

In fact, this was a step that was already tried by the team working on the migration (and it didn’t work), before the question even made it across my inbox to see if there was a way I could help force the logout and get this migration wrapped up successfully. This was indeed puzzling, as my expectation was that initiating a one-time sign-out like this would indeed work across all sessions, the way it promised, so I needed to do some testing, and some research!

First off, it turns out that the sign-out option does work – it just takes a while. In my initial testing, web sessions, Office clients, mobile clients, etc. will log out within 5-15 minutes, as promised. However, the Teams client holds on to that token a lot longer after it’s been invalidated and will not sign out until after an hour. Now, that’s not horrible, but it’s still not going to give me the controlled experience that I was looking for, so I needed to dive a little deeper – especially as I wanted PowerShell options… no way would I click through hundreds of users to make this happen!

Force Kick – the Way of the Shell

To do this through PowerShell, you first need to have the Azure AD Preview module installed – if you don’t have it on your system already, open an admin shell and install it by using the Install-Module AzureADPreview command. After that, you can go ahead and connect to Azure AD using Connect-AzureAD, and logging in as normal.

First thing to do is find your user, and see when their current access token is valid from, like so:

Get-AzureADUser -SearchString "Lester Tester" | Select *token*

This will return the RefreshTokensValidFromDateTime, which essentially tells you that any token issued AFTER this date/time is valid – note that the time is in UTC, so you’ll need to adjust for your own time zone.

So far this is just informational, but still useful – especially if you want to find any users you might have missed, or who still have old tokens sticking around. Now, to revoke this access token, simply use the following command:

Get-AzureADUser -SearchString "Lester Tester" | Revoke-AzureADUserAllRefreshToken

This command won’t return anything in the Shell, but if you run the Get-AzureADUser command from above one more time, you should see that your refresh token validation date has been set to the current date and time (again, don’t forget you need to convert from UTC to your own time zone – very annoying!!).

Now that we have the PowerShell basics down, we can easily take this command and scale it out to as many users as we want by filtering on an available attribute – let’s take for instance, the Test family in my tenant:

Get-AzureADUser | ? {$_.DisplayName -match "Test"}  | Select DisplayName,RefreshTokensValidFromDateTime

Once you have your filter working the way you want, just go ahead and re-run that command and pipe it out to the Revoke command:

Get-AzureADUser | ? {$_.DisplayName -match "Test"} | Revoke-AzureADUserAllRefreshToken

If you run your Get command again, you can see that all our users in scope have had their old tokens invalidated:

Now we have a process set that we can scale out and revoke the tokens for hundreds or even thousands of users if we need to. However, that still didn’t solve our timing problem, so I logged in to the Azure AD portal to see if there was somewhere else that I could make this sign-out happen when I wanted it to, and not after an hour (or whenever Teams felt like letting go of its token). Unfortunately, there is not any other magic kill switch in the Azure AD portal, but I did discover something interesting – both running the initiate sign-out option, and revoking the access token through PowerShell do the exact same thing, but with different actors initiating the change:

Sadly, this doesn’t really get us any closer to the final answer – it simply tells me that either method is essentially doing the same thing behind the scenes, and you should have the exact same experience in both cases. Now let’s see what we can do about that delay!

Tweaking that Token

I knew that some time back, Microsoft had introduced the option to configure token lifetimes, so I wanted to see if there was a way I could shorten that process, and get these Teams users logged out when I wanted, not lingering around on the old tenant the way they were. If you check the link above, you can find a lot of interesting info about this whole process, but here’s a handy reference to the defaults, and what they can be changed to:

Seeing that I could get my tokens down as low as 10 minutes was starting to sound a lot more interesting to me, so I wanted to build this out and do some more testing. Here’s what I did:

Start by checking to see which policies you have in place by using Get-AzureADPolicy. If your tenant is like mine, it probably looks like this:

By default, there are no Token Lifetime Policies in place, so we’re going to go ahead and create one.

New-AzureADPolicy -Definition @('{"TokenLifetimePolicy":{"Version":1,"AccessTokenLifetime":"00:10:00","MaxInactiveTime":"00:10:00"}}') -DisplayName "OrganizationDefaultPolicyScenario" -IsOrganizationDefault $true -Type "TokenLifetimePolicy"

Voila:

Make note of your policy ID so that you can use it to target this policy if you want to update it (using Set-AzureADPolicy) or delete it (using Remove-AzureADPolicy). Now that our Access Token Lifetime and Max Inactive Time were both set to 10 minutes, I tested again revoking an access token with a user that was signed into Outlook on the Web, Teams in a different browser, the Teams desktop client, and Teams on a mobile device.

Here’s how they behaved:

  1. Outlook on the Web: logged out immediately
  2. Teams Web & Mobile: logged out about 2 minutes later
  3. Teams Desktop: logged out in less than 5 minutes

Sweet, sweet victory!

Final thoughts

After all this fun, here’s a couple of things to keep in mind:

You can revert your settings to default by either deleting the policy you created, or by using the following PowerShell command:

New-AzureADPolicy -Definition @('{"TokenLifetimePolicy":{"Version":1,"AccessTokenLifetime":"00:10:00","MaxInactiveTime":"00:10:00"}}') -DisplayName "OrganizationDefaultPolicyScenario" -IsOrganizationDefault $true -Type "TokenLifetimePolicy"

If for some reason you need to keep your existing policy in place, just target it using the Set-AzureADPolicy command, and update the pieces you need to change – worst-case scenario, delete the policy and create it fresh using the command above. (more info here)

I’m not 100% sure of the impact of running your long term with your access tokens refreshing this quickly – I assume that if Microsoft is allowing you to change the token lifetimes down to 10 minutes, that it’s acceptable to do so. I did run for a couple of hours like this without any adverse side effects, but that’s in my test tenant, not a production environment. If I needed to fulfill the scenario that started this whole thing, I’d probably change my token lifetime policy a day or two before my migration cutover so that all the users would be revoked immediately upon cutover. After that, I’d personally set it back to defaults unless I had a compelling reason to keep the lifetime shorter.

Also, I wouldn’t waste too much time with this, as they’ve already announced that they’re deprecating this feature and instead moving it to a conditional access policy. No clue what that looks like yet but know that it’s coming.


All in all, an intriguing problem, and a fun trip to the solution – hope this helps someone else! Feel free to leave a comment below if you have any questions, or to let me know if any of this was helpful. 😀

 

9 thoughts on “Force Teams to Sign Out

  1. Hi, first of all I want to say thank you for this lovely guide. It worked for me, the only problem I’m encountering is now i’m getting error message in Teams whenever I’m signing into the web. I tried a couple of browsers and even restarted my 2 test pcs and still issue persists. The error code is below:

    teams.microsoft.com/_#/oops?errorCode=feing%tch_user_profile&errorMessage=App%20load20failed:%20app%20fetch_user_profile:%20authenticationService_startup-receivedExpiredToken

    and as you can see, the error message is related to the token, any idea how I can bypass/fix this? Thanks so much!

    Like

    1. I’m sorry, I’ve never seen that issue before – is it just your account, or does the issue persist on multiple accounts? Since you’re logging in on the web, I’d try Incognito mode, clearing my browser cache, & clearing my Windows Credential cache. If you’re able to log in successfully from a different computer entirely, then it might be something tied to your account. Worst case scenario you might need to open a ticket with Microsoft to resolve this. 😦

      Like

      1. Hi Jeremy! Really appreciate the quick response. Yes, this is happening on multiple accounts. I tried all the TS you mentioned yesterday and nothing seems to fix the issue. What I did yesterday to Isolate the problem is I setup a new PC, login the account and I still get the error message. After I revert all back to default, like deleting the Azure Policy and revoking the token, I just refreshed the browser and was able to go into Teams.

        Again, thanks so much! I’ve learned something from this blog. Btw, I wouldn’t bother logging a ticket since the only goal is to kick the o365 sessions, I’ll stick to the old way of not tweaking the token configuration, the only down part is waiting for a couple of hours to get the sessions kick out. lol

        PS. Sorry for my grammar as English is not really my strongest subject.

        Like

  2. Some of these powershell command have been deprecated, and some just don’t work anymore… verified it no longer works.

    Like

  3. Example of Microsoft disregarding a user’s express action. Log out means log out and not somehow auto-login or remember the user id and password the next time teams starts. If a user logs out, then the next time teams runs the user must enter their user id and password.
    How difficult is this to understand?
    Microsoft, stop behaving like 4 year olds and not insult the users and customers by ignoring a user’s security preferences.

    Liked by 1 person

  4. This was a great find. Thank you for writing this. I’m in the middle of a domain migration where the mail is in Office 365 along with onedrive and teams. After migration, nothing worked. I had built a script that disabled ADAL, deleted the OST, removed the AAD token in the Appdata, rebooted twice – and looking up how to get a script to continue found this page. Days of work made redundant! This is so much cleaner and more elegant.

    Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.