List Microsoft 365 Groups With Disabled Owners

Microsoft 365 groups play a significant role in enabling collaboration across your organization, allowing teams to access shared resources like files, emails, and calendars. Group owners hold the responsibility of managing these resources and ensuring that only the right users have access. However, issues can arise when group owners have disabled accounts, leading to unmanaged or orphaned groups. As an administrator, it’s crucial to identify such groups to maintain proper governance.

In this article, we'll walk through a PowerShell script that queries Microsoft 365 to list only the groups with disabled owners. The output includes valuable information such as the group name, the owner’s name, the owner’s email, and whether the group is public or private. We’ll also discuss how the script works, how it can be further enhanced, and potential errors you might encounter along with their solutions.

The Script

# Connect to Microsoft Graph
Connect-MgGraph -Scopes "Group.Read.All" "User.Read.All"

# Define the query to get all groups
$Groups = Get-MgGroup -Filter "groupTypes/any(c:c eq 'Unified')" -Property DisplayName Mail Visibility Id -All

# Create an array to hold the result
$GroupsWithDisabledOwners = @()

foreach ($Group in $Groups) {
    # Get the owners of the group
    $Owners = Get-MgGroupOwner -GroupId $Group.Id
    
    foreach ($Owner in $Owners) {
        # Get owner details including the account status
        $OwnerDetails = Get-MgUser -UserId $Owner.Id -Property DisplayName Mail AccountEnabled

        # Check if the owner account is disabled
        if ($OwnerDetails.AccountEnabled -eq $false) {
            # Store the group and disabled owner information
            $GroupsWithDisabledOwners += [pscustomobject]@{
                "Group Name" = $Group.DisplayName
                "Owner Name" = $OwnerDetails.DisplayName
                "Owner Mail" = $OwnerDetails.Mail
                "Privacy" = if ($Group.Visibility -eq "Private") { "Private" } else { "Public" }
            }
        }
    }
}

# Output the result in a table format
$GroupsWithDisabledOwners | Format-Table -Property "Group Name" "Owner Name" "Owner Mail" "Privacy" -AutoSize

How the Script Works

  1. Connect to Microsoft Graph: The script starts by establishing a connection to Microsoft Graph with the appropriate permissions using the Connect-MgGraph cmdlet. The script requires two permissions:
    • "Group.Read.All": This scope allows reading all Microsoft 365 groups.
    • "User.Read.All": This scope allows reading user information, including account status.
  2. Retrieve All Microsoft 365 Groups: The script uses the Get-MgGroup cmdlet to retrieve all Microsoft 365 groups. We filter by groupTypes to ensure we are only dealing with Unified groups (Microsoft 365 groups). We also retrieve essential properties like the group’s DisplayName, Mail, Visibility, and Id.
  3. Get Group Owners: Once the groups are retrieved, the script uses Get-MgGroupOwner to get a list of all owners for each group based on the group’s ID.
  4. Check if Owners are Disabled: For each owner, we query their details using the Get-MgUser cmdlet. This allows us to check if the owner’s account is disabled (AccountEnabled -eq $false).
  5. Store and Display Information: If the owner is found to be disabled, we store the group name, owner’s name, owner’s email, and the group’s privacy setting (public or private) in a custom object. Finally, the script outputs the information in a table using Format-Table for better readability.

Further Enhancments

While the current script serves its purpose of identifying groups with disabled owners, there are several ways you can enhance it to make it even more powerful:

  1. Exporting Results to a CSV File: If you need to keep a record or share the results with other administrators, exporting the data to a CSV file might be useful. You can do this by replacing the last line of the script with:
  2. $GroupsWithDisabledOwners | Export-Csv -Path "C:\DisabledGroupOwnersReport.csv" -NoTypeInformation
    
  3. Sorting and Filtering: You might want to prioritize certain groups or only display those with a specific number of disabled owners. For example, you can sort the groups by their owner count or filter the list for public groups:
  4. $GroupsWithDisabledOwners | Where-Object { $_.Privacy -eq "Public" } | Sort-Object -Property "Group Name"
  5. Handling Large Environments: If your organization has hundreds or thousands of groups, you may run into performance issues. You can add pagination to the Get-MgGroup and Get-MgGroupOwner cmdlets by using the -Top parameter to process the data in smaller chunks.
  6. Notify Admins: You can extend the script to automatically send notifications (e.g., via email) to administrators when groups with disabled owners are detected.

Possible Errors & Solutions

Error Cause Solution
Insufficient Privileges The account running the script lacks permissions. Ensure the account has Group.Read.All and User.Read.All permissions.
Cannot convert null to type 'System.Boolean' Some owners may not have an AccountEnabled property. Add a condition to handle users without the AccountEnabled property.
Error: "Throttling" Microsoft Graph might throttle requests if too many are made in a short time. Implement request throttling by adding delays (Start-Sleep) between requests, especially if querying large numbers of groups. Alternatively, consider retrieving data in smaller batches using the -Top parameter.
Cannot convert null to type 'System.Boolean' If some owners are external users or guest users, they may not have an AccountEnabled property, causing the script to fail. You can handle this case by adding a condition that checks if the user has an AccountEnabled property:
if ($OwnerDetails.PSObject.Properties.Match('AccountEnabled')) { ... }
Error: "Not Found" for Owners In some cases, you may get an owner ID that no longer exists or has been removed from the tenant. Wrap the Get-MgUser cmdlet inside a Try-Catch block to handle any missing owners gracefully:

    Try {
    $OwnerDetails = Get-MgUser -UserId $Owner.Id -Property DisplayName, Mail, AccountEnabled
    } Catch {
    Write-Host "Owner not found for Group: $($Group.DisplayName)"
    }

Conclusion

Identifying groups with disabled owners in Microsoft 365 is a critical task for ensuring that all groups are properly managed and do not become orphaned. This Graph PowerShell script automates the process of finding these groups and their disabled owners, providing you with a clear, actionable report.

By extending the script with features like exporting results to CSV, sorting, and notification capabilities, you can further enhance its usefulness in managing your Microsoft 365 environment. If you encounter any errors, the provided solutions should help you troubleshoot common issues.

With this script as part of your administrative toolkit, you'll be better equipped to maintain security and governance over your Microsoft 365 groups. Happy scripting!

© m365corner.com. All Rights Reserved. Design by HTML Codex