Immediately revoke access to Microsoft 365 applications

This is a follow up to my previous article on how to revoke access in the service, updated to reflect the latest changes in the service. The old method still works and can be used, however as Microsoft is deprecating the Azure AD PowerShell module, it’s time to switch to the “modern” alternative, which is the Graph API and the corresponding Graph SDK for PowerShell. In addition, we will talk about some new features introduced in Azure AD/Microsoft 365 since the original article was published, which might also help with the task at hand.

It is worth noting that we still do not have a way to revoke Access tokens, only Refresh tokens are impacted. Thus “immediately” is sort of a wishful thinking, and in reality up to one hour delay might be experienced before the user is asked to re-authenticate. Features such as Continuous Access Evaluation can help speed up the process and make it effectively immediate, however certain caveats might apply. Make sure to review the feature documentation and familiarize yourself with them in order to avoid surprises!

Before covering the cmdlets/API requests we can use to revoke access, we need to talk about the permissions required. As with most things Graph, we have two methods available to perform the operation – via delegate permissions (running as a user) or via application permissions (running as a background task). When using the application permissions model, the corresponding application must have the User.ReadWrite.All permission granted. The same permission is required when you are performing the operation in the delegate permission model, however the user executing the cmdlet will also need to have one of the following admin roles assigned, depending on the target’s account type:

Invalidate refresh tokens of limited admins User Administrator
Invalidate refresh tokens of non-admins Password Administrator
Invalidate refresh tokens of privileged admins Privileged Authentication Administrator

Assuming you have the required permissions, you can use the Graph API’s /revokeSignInSessions endpoint to perform the operation. Issue a POST request against the endpoint, with an empty payload. Here’s an example with using the Graph explorer tool:


Revoke access example via the Graph explorer

To perform the same operation via PowerShell, make sure you are connected to a session with sufficient permissions, then issue the Revoke-MgUserSignInSession cmdlet. Luckily, the cmdlet does support providing the UPN value instead of GUID. Successful execution will return a value of “True”, as shown below:

C:\> Revoke-MgUserSignInSession -UserId

As with most other cmdlets from the Graph SDK for PowerShell, no pipeline support is offered, so if you have to get the user ID or run the cmdlet against multiple users, things get unnecessary complicated. Doable, but the experience can be much better. The following example gets a user based on a filter query and runs the Revoke-MgUserSignInSession cmdlet against it:

C:\> Get-MgUser -Filter "displayName eq 'test'" | % { Revoke-MgUserSignInSession -UserId $_.Id }

The syntax used above has the added benefit that it will process any and all user objects returned, so you can also use it for bulk scenarios. For example, run the cmdlet against all users in a given department:

C:\> Get-MgUser -Filter "department eq 'HP'" | % { Revoke-MgUserSignInSession -UserId $_.Id}

As another bulk example, here’s how to run the cmdlet against all members of a given group:

C:\> Get-MgGroupMember -GroupId 84b18857-3c01-48be-b707-492019c57142 | % { Revoke-MgUserSignInSession -UserId $_.Id }

That’s it for the cmdlet – as with most Graph replacements, it’s a crappier syntax, but it gets the job done. And in case you are looking for the replacement of the Revoke-AzureADSignedInUserAllRefreshToken cmdlet, there is none. To achieve the same task via the Graph API, you can use the /me/revokeSignInSessions endpoint, whereas to do the same in the Graph SDK for PowerShell, you will have to leverage a “raw” query via the Invoke-GraphRequest cmdlet.

Lastly, few words on features that relate to the above, which were introduced since the last article was published. Continuous Access Evaluation is your primary weapon here, as it enforces near real-time revocation of access tokens/active sessions. The best part is that the feature is enabled by default and requires zero configuration on your end, however as mentioned above it’s worth examining the documentation and familiarizing yourself with some caveats/limitations. Apart from CAE, we have the sign-in frequency controls and idle session timeout for Microsoft 365 web apps, and probably few others that I cannot recall atm. The bottom line is that we’re in a much better position to enforce this now, compared to what we had few years ago.

Let me know if you have any questions on the process.

7 thoughts on “Immediately revoke access to Microsoft 365 applications

  1. SysAdmin-E says:

    Good info. Why is it so difficult to immediately revoke an access token? Or is there some other option? Is it just the nature of how access tokens work and they are so common that it’s difficult to use something “better?” Even Continuous Access Evaluation doc mentions up to 15 minutes delay.

    1. Vasil Michev says:

      It’s a combination of design decision and the massive scale of the cloud, which necessitates some forms of caching…

  2. Steve says:

    Thanks for this. Quick question: is ‘Revoke-SPOUserSession’ is redundant with the above Graph command or should they both be used?

  3. says:

    Gostei muito do conteúdo.
    Gostaria de ver mais exemplos sobre.


Leave a Reply

Your email address will not be published. Required fields are marked *

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