This content is part of the Essential Guide: How to deal with Identity and access management systems

Essential Guide

Browse Sections

Active Directory cleanup trims database bloat

Administrators can avoid unnecessary risks and potential performance issues by removing unneeded and outdated objects from Active Directory.

Active Directory is inarguably critical to the business -- nearly all applications and end users rely on the service for authentication and authorization. In a large enterprise, Active Directory can contain tens of thousands of user accounts, groups, organizational units and Group Policy Objects. It also holds hundreds of thousands of objects -- users, printers and computers -- in its database. And all that data leads to clutter.   

Every business has some kind of Active Directory baggage -- empty groups that are no longer needed, unlinked Group Policy Objects (GPOs), dormant user accounts. Plan an Active Directory cleanup as part of a database update -- it is a good time to clean the clutter that accumulated over the years. Many organizations also make tidying Active Directory part of routine maintenance to keep the database running at optimal speed.

Before starting the cleanup process, an administrator's computer must be on the domain that they will query, and that machine must have Microsoft's Remote Server Administration Tools package installed.

Eliminate unlinked GPOs

GPOs can become unwieldy due to their hierarchical arrangement. Over time, GPOs can conflict with one another, or some can be disabled in some places while enabled in others. One typical piece of Active Directory clutter is unlinked GPOs; these are GPOs that have no connection to an organizational unit and are doing nothing but taking up space in the Active Directory database.

Before starting the Active Directory cleanup process, an administrator's computer must be on the domain that they will query, and that machine must have Microsoft's Remote Server Administration Tools package installed.

To find these GPOs, use the Get-GPOReport cmdlet that comes with the PowerShell Active Directory module. Unlike Get-GPO, this cmdlet goes deeper and pulls out most of the settings inside a single -- or all -- GPOs in a domain.

Retrieve all GPOs in the domain in XML format. Using XML enables dot notation to specify certain properties.

$gpoReport = [xml](Get-GPOReport -All -ReportType XML)

Next, filter the report for GPOs with a null LinksTo property. This will show all unlinked GPOs in the domain.

@($gpoReport.GPOs.GPO).where({ -not $_.LinksTo })

To remove the unlinked GPOs, pipe them to Remove-GPO with the WhatIf parameter. If all looks good, remove the WhatIf parameter to delete these objects.

@($gpoReport.GPOs.GPO).where({ -not $_.LinksTo }) | Remove-Gpo -WhatIf

Remove empty groups

Another typical piece of clutter in the Active Directory database is empty groups, which can accumulate for various reasons, such as testing purposes.

First, generate a report of empty groups with the Get-AdGroup cmdlet and using a where filter:

@(Get-ADGroup -Filter * -Properties isCriticalSystemObject,Members).where({ (-not $_.isCriticalSystemObject) -and ($_.Members.Count -eq 0) })

To remove the empty groups, pipe the result to Remove-AdGroup.

@(Get-ADGroup -Filter * -Properties isCriticalSystemObject,Members).where({ (-not $_.isCriticalSystemObject) -and ($_.Members.Count -eq 0) }) | Remove-AdGroup -WhatIf

Quiz: Test your knowledge of Windows security features

How much do you know about securing Active Directory and Microsoft Azure? This quiz will test your knowledge of the best tools to protect Windows.

Delete unused user accounts

This Active Directory cleanup task removes any unused -- expired, disabled or hasn't been used for 120 days -- user accounts. We find these accounts with the Search-ADAccount cmdlet. This cmdlet allows an administrator to find each category of user accounts with a single line.

Search-ADAccount -AccountInactive -TimeSpan 120 -UsersOnly

Search-ADAccount -AccountDisabled –UsersOnly

Search-ADAccount -AccountExpired –UsersOnly

An administrator can consolidate these commands and export the results into a comma-separated values (CSV) file, as shown in the example below.

$inactiveAccounts = Search-ADAccount -AccountInactive -TimeSpan 120 -UsersOnly

$disabledAccounts = Search-ADAccount -AccountDisabled –UsersOnly

$expiredAccounts = Search-ADAccount -AccountExpired –UsersOnly

$unusedAccounts = $inactiveAccounts + $disabledAccounts + $expiredAccounts

$unusedAccounts | Export-Csv –Path C:\UnusedAccounts.csv

Administrators can export the results for other objects, such as unlinked GPOs and empty groups, to a CSV as well.

To remove the unused user accounts, pipe the results to Remove-AdUser by using the WhatIf parameter. If the output appears correct, remove the WhatIf parameter and run again to execute the delete process.

$unusedAccounts | Remove-AdUser -WhatIf

Next Steps

Exchange administrators must stay on top of database maintenance

The beginner's guide to using Group Policy

Using PowerShell to automate creation of Active Directory user accounts

Dig Deeper on Windows systems and network management