Showing posts with label Azure AD connect. Show all posts
Showing posts with label Azure AD connect. Show all posts

Monday, November 27, 2023

"Stopped deletion threshold exceeded" Error in Azure AD Connect



This topic describes how to prevent "Accidental Deletes" feature in Microsoft Entra Connect.

in Azure AD connect , to prevent accidental deletes is enabled by default and configured to not allow an export with more than 500 deletes. This feature is designed to protect from accidental configuration changes and changes to your on-premises directory that would affect many users and other objects.





if anyone unknowingly deleted the AD objects, you may check that by following below steps: 

  1. Start Synchronization Service from the Start Menu.
  2. Go to Connectors.
  3. Select the Connector with type Microsoft Entra ID.
  4. Under Actions to the right, select Search Connector Space.
  5. In the pop-up under Scope, select Disconnected Since and pick a time in the past. Click Search. This page provides a view of all objects about to be deleted. By clicking each item, you can get additional information about the object. You can also click Column Setting to add additional attributes to be visible in the grid.

Search Connector Space

If you really want to delete the objects, follow the below steps: 

If all the deletes are desired, then do the following:

  1. To retrieve the current deletion threshold, run the PowerShell cmdlet 
  2. Get-ADSyncExportDeletionThreshold. The default value is 500.
  3. To temporarily disable this protection and let those deletes go through, run the PowerShell cmdlet: Disable-ADSyncExportDeletionThreshold.
  4. Run Initial Sync: Start-ADSyncSyncCycle -PolicyType Initial.
  5. To re-enable the protection, run the PowerShell cmdlet: Enable-ADSyncExportDeletionThreshold -DeletionThreshold 500


That is all! 

How to Export Azure AD users to a CSV File with PowerShell script?

The script will download the following Attributes: 


1 ID
2 First name
3 Last name
4 Display name
5 User principal name
6 Email address
7 Job Title
8 Manager display name
9 Manager user principal name
10 Department
11 Company
12 Office
13 Employee ID
14 Mobile
15 Phone
16 Street
17 City
18 Postal code
19 State
20 Country
21 User type
22 On-Premises sync
23 Account status
24 Account created on
25 Last log in
26 Licensed
27 MFA status 



Step 1. Install Microsoft Graph PowerShell Module 


Run PowerShell as administrator. Run the command Install-Module PowershellGet -Force


Step 2. Connect to Microsoft Graph Explorer using  PowerShell

Connect to Azure Active Directory (AAD) with Microsoft Graph PowerShell.

PS C:\> Connect-MgGraph -Scopes "User.Read.All", "UserAuthenticationMethod.Read.All", "AuditLog.Read.All"

Note: Global Administrator right required. 

Step 3. Execute the below script. 

<#

    .SYNOPSIS

    Export-AADUsers.ps1


# Connect to Microsoft Graph API

Connect-MgGraph -Scopes "User.Read.All", "UserAuthenticationMethod.Read.All", "AuditLog.Read.All"


# Create variable for the date stamp

$LogDate = Get-Date -f yyyyMMddhhmm


# Define CSV file export location variable

$Csvfile = "C:\temp\AllAADUsers_$LogDate.csv"


# Define the Get-AllMgUsers function

Function Get-AllMgUsers {

    process {

        # Retrieve users using the Microsoft Graph API with property

        $propertyParams = @{

            All            = $true

            # Uncomment below if you have Azure AD P1/P2 to get last log in date

            # Property = 'SignInActivity'

            ExpandProperty = 'manager'

        }


        $users = Get-MgBetaUser @propertyParams

        $totalUsers = $users.Count


        # Initialize progress counter

        $progress = 0


        # Collect and loop through all users

        foreach ($index in 0..($totalUsers - 1)) {

            $user = $users[$index]


            # Update progress counter

            $progress++

            

           # Calculate percentage complete

            $percentComplete = ($progress / $totalUsers) * 100


            # Define progress bar parameters

            $progressParams = @{

                Activity        = "Processing Users"

                Status          = "User $($index + 1) of $totalUsers - $($user.userPrincipalName) - $($percentComplete -as [int])% Complete"

                PercentComplete = $percentComplete

            }

            

            # Display progress bar

            Write-Progress @progressParams


            # Get manager information

            $managerDN = $user.Manager.AdditionalProperties.displayName

            $managerUPN = $user.Manager.AdditionalProperties.userPrincipalName


            # Create an object to store user properties

            $userObject = [PSCustomObject]@{

                "ID"                          = $user.id

                "First name"                  = $user.givenName

                "Last name"                   = $user.surname

                "Display name"                = $user.displayName

                "User principal name"         = $user.userPrincipalName

                "Email address"               = $user.mail

                "Job title"                   = $user.jobTitle

                "Manager display name"        = $managerDN

                "Manager user principal name" = $managerUPN

                "Department"                  = $user.department

                "Company"                     = $user.companyName

                "Office"                      = $user.officeLocation

                "Employee ID"                 = $user.employeeID

                "Mobile"                      = $user.mobilePhone

                "Phone"                       = $user.businessPhones -join ','

                "Street"                      = $user.streetAddress

                "City"                        = $user.city

                "Postal code"                 = $user.postalCode

                "State"                       = $user.state

                "Country"                     = $user.country

                "User type"                   = $user.userType

                "On-Premises sync"            = if ($user.onPremisesSyncEnabled) { "enabled" } else { "disabled" }

                "Account status"              = if ($user.accountEnabled) { "enabled" } else { "disabled" }

                "Account Created on"          = $user.createdDateTime

                # Uncomment below if you have Azure AD P1/P2 to get last log in date

                # "Last log in"                 = if ($user.SignInActivity.LastSignInDateTime) { $user.SignInActivity.LastSignInDateTime } else { "No log in" }

                "Licensed"                    = if ($user.assignedLicenses.Count -gt 0) { "Yes" } else { "No" }

                "MFA status"                  = "-"

                "Email authentication"        = "-"

                "FIDO2 authentication"        = "-"

                "Microsoft Authenticator App" = "-"

                "Password authentication"     = "-"

                "Phone authentication"        = "-"

                "Software Oath"               = "-"

                "Temporary Access Pass"       = "-"

                "Windows Hello for Business"  = "-"

            }


            $MFAData = Get-MgBetaUserAuthenticationMethod -UserId $user.userPrincipalName


            # Check authentication methods for each user

            foreach ($method in $MFAData) {

                Switch ($method.AdditionalProperties["@odata.type"]) {

                    "#microsoft.graph.emailAuthenticationMethod" {

                        $userObject."Email authentication" = $true

                        $userObject."MFA status" = "Enabled"

                    }

                    "#microsoft.graph.fido2AuthenticationMethod" {

                        $userObject."FIDO2 authentication" = $true

                        $userObject."MFA status" = "Enabled"

                    }

                    "#microsoft.graph.microsoftAuthenticatorAuthenticationMethod" {

                        $userObject."Microsoft Authenticator App" = $true

                        $userObject."MFA status" = "Enabled"

                    }

                    "#microsoft.graph.passwordAuthenticationMethod" {

                        $userObject."Password authentication" = $true

                        # When only the password is set, then MFA is disabled.

                        if ($userObject."MFA status" -ne "Enabled") {

                            $userObject."MFA status" = "Disabled"

                        }

                    }

                    "#microsoft.graph.phoneAuthenticationMethod" {

                        $userObject."Phone authentication" = $true

                        $userObject."MFA status" = "Enabled"

                    }

                    "#microsoft.graph.softwareOathAuthenticationMethod" {

                        $userObject."Software Oath" = $true

                        $userObject."MFA status" = "Enabled"

                    }

                    "#microsoft.graph.temporaryAccessPassAuthenticationMethod" {

                        $userObject."Temporary Access Pass" = $true

                        $userObject."MFA status" = "Enabled"

                    }

                    "#microsoft.graph.windowsHelloForBusinessAuthenticationMethod" {

                        $userObject."Windows Hello for Business" = $true

                        $userObject."MFA status" = "Enabled"

                    }

                }

            }


            # Output the user object

            $userObject

        }

    }

}


# Export users to CSV

Get-AllMgUsers | Sort-Object "Display name" | Export-Csv -Path $Csvfile -NoTypeInformation -Encoding UTF8 #-Delimiter ";"



Note : The File will be downloaded to the "C:\Temp"


Disclaimer:  Please do test the script in Test Environment before Production.