Managing Microsoft 365 (M365) accounts can be a bit of a pain, especially when it comes to cleaning up inactive or unnecessary accounts. Fortunately, the Microsoft.Graph PowerShell modules give us some powerful tools to automate and streamline this process. Today, we’ll have a quick look at how to clean up M365 accounts, along with a few tips and tricks. Let’s get into it!
Prerequisites
Before we dive into the juicy bits, we need to cover some prerequisites:
1. Microsoft Graph PowerShell SDK: Obviously to use the Microsoft Graph PowerShell module, you’ll need to install it using the following command:
Install-PSResource -name Microsoft.Graph2.Administrator Role: Next you will need to have either the global administrator or user administrator role in your M365 tenant.
3. Graph API Permissions: Ensure you have the `User.ReadWrite.All` Graph API permission. More on this in a bit.
Connecting to Microsoft Graph
Before we go too much deeper, we should briefly talk about “Scopes” and authentication in the Graph PowerShell SDK. I say briefly because it would take a much longer post (or series of posts) to fully delve into the topics of scopes and authentications. But what is a “scope”? You can think about a scope as a group of permissions. The names are pretty self-explanatory.
For example, the scope we will use today is “User.ReadWrite.All“, but if you were just searching for users with no intention of changing or writing to a user record, you could use “User.Read.All“. The best practice is to only use the level of permission that you actually need at that time. The number of scopes is constantly changing as Graph workloads are added and deprecated over time. As of this writing there are over 500 unique scopes NOT counting Beta scopes! The official list is here, and a community-maintained list is here.
Thankfully there are only two types of authentications – delegated or application. The easy way to think about it is this – use ‘delegated’ for interactive work and ‘application’ for automation work. The full explanation of authentications is here.
Got it? good! Now, authenticate and connect to your Microsoft Graph environment by running the following command:
Connect-MgGraph -Scopes "User.ReadWrite.All"This will pop up a graphical login screen complete with MFA and all the normal “Logging into Microsoft/Azure/Entra” goodies.
Now that you are connected, we can get to work! Before we start slashing and burning through user accounts, let’s start with a bit of a search, shall we?
Searching for a Single User
Search for a user with the Get-MgUser cmdlet like this:
$UserName = "john.doe@contoso.com"
Get-MgUser -Filter "userPrincipalName eq '$UserName'"Pretty simple huh? Now to build on that, we’ll use the same search basics to find and remove users to clean up your M365 tenant.
Removing a Single User
To remove a single user from your M365 tenant, use the Remove-MgUser cmdlet. For example:
$UserName = "john.doe@contoso.com"
$UserId = (Get-MgUser -Filter "userPrincipalName eq '$UserName'").Id
Remove-MgUser -UserId $UserId -Confirm:$falseRemoving Multiple Users
You can remove multiple users by iterating through a list of user IDs, like this:
$userIds = @("user1@contoso.com", "user2@contoso.com", "user3@contoso.com")
foreach ($userId in $userIds) {
Remove-MgUser -UserId $userId -Confirm:$false
}Removing Users from a CSV File
Or, if you have a list of users in a CSV file, you can remove them using the following script:
$csvPath = "C:\Path\To\Users.csv"
$users = Import-Csv -Path $csvPath
foreach ($user in $users) {
Remove-MgUser -UserId $user.UserPrincipalName -Confirm:$false
}Error Handling and Best Practices
Always, when working with PowerShell automation it’s important to implement error handling. Here are some of the errors you may encounter and some solutions:
Error: 404 Not Found
Cause: The specified user ID does not exist in the tenant.
Solution: Verify the User information (spelling etc.).
Error: 403 Forbidden
Cause: Insufficient permissions to delete the user.
Solution: Check your account has the necessary M365 admin permissions (e.g., User Administrator or Global Administrator) and Graph API permissions (User.ReadWrite.All).
Error: 400 Bad Request
Cause: The URI or method is incorrectly formatted. This is basically a syntax error.
Solution: Double-check your commands and make certain the -filter you are using is on a property that accepts the filter.
This is ‘Just the Beginning’
There is a TON of things you can do with the Graph SDK in PowerShell – be forewarned – it can be a deep rabbit hole to dive down. To get you started, I’ve put some links below to some official docs on the subject. Have fun and happy scripting!
Microsoft Graph PowerShell documentation
PowerShell.org: Microsoft Graph PowerShell Module: Getting Started Guide
