Microsoft Entra ID security

How to block sign-in for multiple users in Entra ID

Block sign-in for a list of accounts with Microsoft Graph PowerShell, block accounts 1 at a time in the Microsoft 365 admin centre, or use Altivane's Block sign-in change on the accounts you choose.

By the Published

To block sign-in for multiple users in Microsoft Entra ID, set accountEnabled to false on each account in your list. Blocking stops new sign-ins; it does not end sessions that are already open, which is a separate step. Check the list first: a blocked account locks out anything that signs in as it, including a service account or your own.

Choose the method that fits the job
MethodBest fit
PowerShellA script that reads a CSV of sign-in names and backs up, blocks and records each account.
Admin centreBlocking 1 or 2 accounts, one at a time.
AltivaneRecommended for bulk changes to items you choose from a list, with every result in a change log.

Before you start

A User Administrator can block members who hold no administrator role or only some limited ones; blocking any other administrator needs Privileged Authentication Administrator or Global Administrator. The PowerShell example requests User.EnableDisableAccount.All and User.Read.All; your organisation may require administrator consent.

These examples change the tenant. Try them on 1 or 2 test accounts first, and keep the CSV files the script writes as your record of what changed.

Option 1

Block sign-in for multiple users with PowerShell

Save the sign-in names in users.csv beside the script, under a header of UserPrincipalName.

CSV
UserPrincipalName
alex.morgan@example.com
sam.lee@example.com

Install the modules once, then run the script. It is a dry run until you set $DryRun to $false: Update-MgUser supports -WhatIf, and the script switches it with that variable.

PowerShell
# Install once, if the modules are not already installed.
Install-Module Microsoft.Graph.Authentication, Microsoft.Graph.Users -Scope CurrentUser
PowerShell
# While $DryRun is $true, nothing is changed. Set it to $false to block the accounts.
$DryRun = $true
$ErrorActionPreference = 'Stop'
Connect-MgGraph -Scopes 'User.EnableDisableAccount.All', 'User.Read.All' -NoWelcome
try {
    $stamp = Get-Date -Format 'yyyyMMdd-HHmmss'
    $rows = @(Import-Csv -Path './users.csv' | Where-Object { $_.UserPrincipalName })
    if ($rows.Count -eq 0) { throw 'users.csv needs a UserPrincipalName column and some rows.' }

    # Step 1: read each account as it is now and save it as the backup.
    $properties = 'userPrincipalName,accountEnabled,onPremisesSyncEnabled'
    $backup = foreach ($row in $rows) {
        $upn = $row.UserPrincipalName.Trim()
        try {
            $user = Get-MgUser -UserId $upn -Property $properties
            [pscustomobject]@{
                UserPrincipalName     = $upn
                AccountEnabled        = $user.AccountEnabled
                OnPremisesSyncEnabled = [bool]$user.OnPremisesSyncEnabled
                Error                 = ''
            }
        } catch {
            [pscustomobject]@{
                UserPrincipalName     = $upn
                AccountEnabled        = ''
                OnPremisesSyncEnabled = ''
                Error                 = $_.Exception.Message
            }
        }
    }
    $backup | Export-Csv -Path "./block-backup-$stamp.csv" -NoTypeInformation -Encoding utf8

    # Step 2: block each account that is not blocked already, 1 at a time.
    $results = foreach ($account in $backup) {
        $upn = $account.UserPrincipalName
        $status = 'Failed'
        $detail = $account.Error
        if ($account.Error -eq '') {
            if ($account.AccountEnabled -eq $false) {
                $status = 'No change'
                $detail = 'Sign-in is already blocked.'
            } else {
                try {
                    Update-MgUser -UserId $upn -AccountEnabled:$false -WhatIf:$DryRun
                    $status = if ($DryRun) { 'Preview' } else { 'Blocked' }
                    $detail = ''
                } catch {
                    $detail = $_.Exception.Message
                }
            }
        }
        [pscustomobject]@{ UserPrincipalName = $upn; Status = $status; Detail = $detail }
    }
    $results | Export-Csv -Path "./block-results-$stamp.csv" -NoTypeInformation -Encoding utf8
    $results | Group-Object Status | Select-Object Name, Count | Format-Table
} finally {
    Disconnect-MgGraph | Out-Null
}

The first pass saves block-backup-*.csv before anything changes: whether each account is enabled, and whether it is synchronised from on-premises Active Directory. The second blocks each account still enabled and saves block-results-*.csv with Preview, Blocked, No change or Failed for each. A failure on 1 account, such as a role that cannot change it, goes in Detail and the rest carry on. An account synchronised from on-premises Active Directory may refuse the change, so check OnPremisesSyncEnabled in the backup.

End sessions that are already open

Revoking sessions is a separate step with its own permission. Revoke-MgUserSignInSession invalidates the account's refresh tokens and browser session cookies, so the person must sign in again. Run it on its own, after the block.

PowerShell
# While $DryRun is $true, nothing is changed. Set it to $false to end the sessions.
$DryRun = $true
$ErrorActionPreference = 'Stop'
Connect-MgGraph -Scopes 'User.RevokeSessions.All' -NoWelcome
try {
    $done = 0
    foreach ($row in Import-Csv -Path './users.csv') {
        $upn = $row.UserPrincipalName.Trim()
        try {
            Revoke-MgUserSignInSession -UserId $upn -WhatIf:$DryRun | Out-Null
            $done++
        } catch {
            Write-Warning "${upn}: $($_.Exception.Message)"
        }
    }
    Write-Output "$done accounts handled. Dry run: $DryRun."
} finally {
    Disconnect-MgGraph | Out-Null
}

Option 2

Block sign-in in the admin centre

  1. Sign in to the Microsoft 365 admin centre for the correct tenant.
  2. Go to Users > Active users.
  3. Select the name of the person to block, then select Block sign-in.
  4. On the Block sign-in page, select Block this user from signing in, then Save changes.
  5. Repeat for each person on your list.

Microsoft says a block can take up to 24 hours to take effect. To cut access at once, also select Reset password, then open the person's Account tab and select Sign out of all sessions. These steps cover 1 account at a time; for a longer list, use PowerShell or Altivane.

Common questions

Does blocking sign-in end sessions that are already open?

No. Blocking stops new sign-ins, and Microsoft says it can take up to 24 hours to take effect. End sessions separately: with the revoke script above, the admin centre's Sign out of all sessions, or Altivane's Revoke sign-in sessions change.

How do I undo a block?

Set accountEnabled back to true. In PowerShell, run Update-MgUser with -AccountEnabled:$true for each account, leaving alone any the backup CSV shows were already blocked. In Altivane, run the Allow sign-in change on the same accounts. Revoked sessions do not come back: people sign in again.

Where do I get the list of accounts to block?

From a review you have already made. For accounts with no recent sign-in, see how to find inactive users in Microsoft Entra ID, and check each name before it goes in users.csv.

Microsoft references

Technical references checked on 20 October 2026. The example scripts have been reviewed and syntax checked; they have not been run against a live tenant.

Talk to us about Altivane

Questions, or pricing? Get in touch.

Contact us