Stack of old laptops

I want to quickly talk about inactive objects in Active Directory (AD). User accounts in AD get the most attention to detail, and their decommissioning when someone leaves the company is highly prioritized. However, most AD Administrators would admit to forgetting or neglecting to clean up computer objects when a server or workstation is decommissioned. I have been guilty of failing this step occasionally too. Additionally, computer objects in a large-scale environment can become impossible to track. So, I want to share my safeguard to this problem.

Short on time? TLDR


Are Inactive Computer Objects a Security Risk?

maybe

Before I move on to discussing inactive object safeguards, I want to talk about their security implications. So, are inactive or old computer objects inside AD a security risk? The best answer I can come up with is maybe? Multiple sources say that old computer objects in AD pose a “security risk.”, but none of them ever explain what the risks are.

The only attack vector I can see is an Attacker physically stealing an old computer. Domain joined computers have more default rights than a default user account. These additional rights might be just what an Attacker needs. However, if someone is physically stealing computers, you have a lot of other security failings that need addressing first.

I did not find any known method of leveraging inactive computer accounts without performing physical attacks. The more common threat actors are all remote, rendering this attack useless to them.

So Why Worry about Inactive Computer Objects?

The simple answer is to keep AD clean and reduce your attack surface. There is no downside to maintaining an AD clean and clear of possible attack points. Accidentally removing a needed object is quickly fixed by rejoining the system to the domain. So there is no real downside.


Manually Cleaning Inactive Computer Objects

Let’s review the proper way to decommission a Computer object in AD. This is the process you should follow when decommissioning a server or workstation.

  1. Remove the computer as a member of any group, other than the primary group(Domain Computers). Stripping rights and permissions is key.
  2. Disable the computer object.
  3. Move the computer object to a designated “disabled” OU.

Automating the Clean-up of Inactive Computer Objects

The safeguard I use to keep AD clean is a PowerShell script that runs daily. The script will search AD for systems that have a “LastLogonTimeStamp” older than 90 days. Any computer with a time stamp older than 90 days will have all its group memberships removed, moved to the disabled OU, and deactivated. So even if I am not informed of a decommissioned server this script will catch it.

Here is the script that runs daily from a scheduled task on a Domain controller.

# Specify inactivity range value below
$InactiveDays = 90

# $time variable converts $DaysInactive to LastLogonTimeStamp property format for the -Filter switch to work
$InactiveDate = (Get-Date).Adddays(-($InactiveDays))

# Eet the basic search path in AD. You can limit the search to a specific OU.
# Examples
# $SearchOUbase = 'CN=Computers,DC=EXAMPLE,DC=COM'
# $SearchOUbase = 'DC=EXAMPLE,DC=COM'
$SearchOUbase = 'OU=Desktops,DC=EXAMPLE,DC=COM'

# The disabled Computers OU location in AD.
$DisabledOULocal = 'OU=Disabled.Desktop,OU=Desktops,DC=EXAMPLE,DC=COM'

# Search for Computers that have been inactive for more than X days.
$InactiveComputerObjects = Get-ADComputer -SearchBase $SearchOUbase -Filter {LastLogonTimeStamp -lt $InactiveDate -and Enabled -eq $true} `
-ResultPageSize 2000 -resultSetSize $null -Properties Name, OperatingSystem, SamAccountName, DistinguishedName, LastLogonDate

# Check if $InactiveComputerObjects is empty. If it is, then no computers are inactive.
if ($null -ne $InactiveComputerObjects) {

    #For each inactive computer, Disable the Computer AD object, update the discription, and move the computer to the Disabled.Desktop OU.
    $InactiveComputerObjects | ForEach-Object {
        # Current Computer Object.
        $CurrentComputerObject = $_
        # Get the old(currently) set computer discription.
        $ComputerOldDescription = (Get-ADComputer -Identity $CurrentComputerObject -Prop Description).Description

        #Get the old OU location of the computer.
        $ComputerOldOU = $CurrentComputerObject.DistinguishedName

        # Get all groups the computer is a member of.
        $ComputersGroupMemberships = Get-ADPrincipalGroupMembership $CurrentComputerObject.DistinguishedName

        # Foreach group, remove the computer from the group.
        $ComputersGroupMemberships | ForEach-Object {
            # If $_.DistinguishedName not equal to "Domain Computers", then remove the computer from the group.
            if ($_.name -ne 'Domain Computers') {
                Remove-ADPrincipalGroupMembership -Identity $CurrentComputerObject -MemberOf $_.DistinguishedName -Confirm:$False
            }
        }

        # Disable the computer in AD.
        Disable-ADAccount $CurrentComputerObject

        # Update the computer description.
        Set-ADComputer $CurrentComputerObject -Description "$ComputerOldDescription -- Account disabled $(Get-Date -format "yyyy-MM-dd") by AD-PowerAdmin. :: OLD-OU: $ComputerOldOU"

        # Move the computer to the Disabled.Desktop OU.
        Move-ADObject $CurrentComputerObject -targetpath $DisabledOULocal
    }
}
exit 0

Download The Script from My GitHub!

Invoke-WebRequest https://raw.githubusercontent.com/Brets0150/CG_BlueTeamTools/main/Clean-InactiveComputers.ps1 ./Clean-InactiveComputers.ps1

Wrapping-up; TLRD

  • There is a security risk of leaving inactive computer objects in AD. However, any known attack vectors require physical access.
  • Keep AD clean to reduce your attack surface.
  • Follow a thorough decommissioning process.
  • Use a PowerShell script to catch stale and inactive computers and automatically decommission them.