2

Remove Disabled Active Directory Computers From SCCM Using Powershell

If you’ve been running SCCM for a while you may have noticed that when you delete or disable computers from Active Directory, they don’t replicate to SCCM. Those computer accounts in SCCM will linger around until either the Maintenance task takes place and auto deletes those computer objects or until you manually go in there and delete them yourself. If you’re doing it the second way, we know ain’t nobody got time for dat!! A huge part of system administration is to have things like this automated to the point where you can just set it and forget it. Since I work with SCCM and Powershell on pretty much an everyday basis, I decided to create a script to automate and remove disabled active directory computers from SCCM. I hope you enjoy this super easy way to delete computers not in AD from SCCM.

Script Requirements

In order to run this script successfully you will need the following:

  • Permissions to delete computer accounts within SCCM. (Only if using the -DeleteComputers parameter)
  • The Active Directory Module: Used to gather AD Computer names and Domain names.
  • The ConfigurationManager Module: Used to gather ConfigMgr Computer names and remove objects if specified.

Remove Disabled Active Directory Computers From SCCM Powershell Script

#requires -Module ActiveDirectory
Import-Module (Join-Path $(Split-Path $env:SMS_ADMIN_UI_PATH) ConfigurationManager.psd1)


Function Remove-DisabledADComputersFromSCCM {
    <#
    .Synopsis
        This script will check to see if disabled and deleted computers from Active Directory are still enabled in System Center Configuration Manager.
        For updated help and examples refer to -Online version.
 

    .DESCRIPTION
        This script will check to see if disabled and deleted computers from Active Directory are still enabled in System Center Configuration Manager.
        For updated help and examples refer to -Online version.


    .NOTES   
        Name: Remove-DisabledADComputersFromSCCM
        Author: The Sysadmin Channel
        Version: 1.0
        DateCreated: 2018-Aug-5
        DateUpdated: 2018-Aug-5

    .LINK
        https://thesysadminchannel.com/remove-disabled-active-directory-computers-sccm-powershell/ -


    .EXAMPLE
        For updated help and examples refer to -Online version.

    #>

    [CmdletBinding()]
    param(
        [Parameter()]

        [switch]  $DeleteComputers
    )


    BEGIN {
        #Declaring All Empty Arrays.
        $SearchRoots             = @()
        $SearchRootArray         = @()
        $DomainControllerList    = @()
        $All_ADComputers         = @()
        $RemoveComputersFromSCCM = @()
        
        # =======================================
        #Manually Enter SCCM Information
        # SCCM Site Code (3-digit code) [string]
        #$CMSiteCode = "PAC"

        # SCCM Primary Server (server.domain.com) [string]
        #$CMPrimaryServer = "PAC-SCCM01.ad.thesysadminchannel.com"


        # ============================================
        # Automatically Gather SCCM Information.
        # SCCM Site Code (3-digit code)
        $CMSiteCode = Get-PSDrive -PSProvider CMSITE | select -ExpandProperty Name

        # SCCM Primary Server.
        $CMPrimaryServer = Get-PSDrive -PSProvider CMSITE | select -ExpandProperty Root

        
        # Collection name to clean up (typically 'All Systems' or 'All Workstations') [string]
        $CMCollection = "All Systems"
    }

    PROCESS {
        try {
            #Query the SCCM Server to get the System Discovery Agent. This will pull a list of Domains currently in use by SCCM.
            $Query = Get-WmiObject -Namespace root\sms\site_$CMSiteCode -ComputerName $CMPrimaryServer -Class SMS_SCI_Component -Filter "ComponentName='SMS_AD_SYSTEM_DISCOVERY_AGENT'" -ErrorAction Stop
            $Query.PropLists.Values | Where-Object {$_ -like "LDAP://*"} | ForEach-Object {$SearchRoots += $_.Replace("LDAP://","")}

            foreach ($Root in $SearchRoots) {$Position = $Root.IndexOf("DC="); $SearchRootArray += $Root.Substring($Position)}
            $SearchRoots = $SearchRootArray | select -Unique

            ##Active Directory query portion.

            #Getting domain list from Active Directory to verify and match SCCM client (NetBIOSName) domain property.
            $DomainList = Get-ADForest | select -ExpandProperty Domains

            #Iterate through the SCCM Discovered domains and Active Directory domains to get the Server Property for querying AD Computers.
            Foreach ($Root in $SearchRoots) {
                Foreach ($Domain in $DomainList) {
                    $DomainControllerList += Get-ADDomain -Identity $Domain | Where-Object {$_.DistinguishedName -eq $Root} | select -ExpandProperty PDCEmulator
                }
            }

            #Getting all Active Directory computers from all domains found.
            Foreach ($DomainController in $DomainControllerList) {
                $NetBIOSName = Get-ADDomain -Server $DomainController | select -ExpandProperty NetBIOSName
                $All_ADComputers += Get-ADComputer -Filter * -Server $DomainController | select Name, Enabled, @{Name = 'Domain'; Expression = {$NetBIOSName} }
            }

            #Creating a sub group that only contain disabled computer accounts in AD.
            $ADComputerList = $All_ADComputers | Where-Object {$_.Enabled -eq $false} | Select Name, Domain

            #Reformatting the array to eliminate Enabled field.
            $All_ADComputers = $All_ADComputers | Select Name, Domain


            ##SCCM Query Portion.

            #Setting location to SCCM PSDrive.
            Set-Location "$($CMSiteCode):"

            #Getting all SCCM Computer objects.
            $All_CMComputers = Get-CMDevice -CollectionName 'All Systems' | Where-Object {$_.Name -notlike "*Unknown Computer)"} | Select Name, Domain

            if ($CMCollection -eq 'All Systems') {
                    $CMComputerList = $All_CMComputers
                } else {
                    $CMComputerList = Get-CMDevice -CollectionName $CMCollection |  Where-Object {$_.Name -notlike "*Unknown Computer)"} | Select Name, Domain
            }

            #Using Compare-Object cmdlet to compare both arrays.
            $RemoveComputersFromSCCM += Compare-Object -ReferenceObject $All_ADComputers -DifferenceObject $All_CMComputers -IncludeEqual -Property Name, Domain | Where-Object {$_.SideIndicator -eq '=>'} | select Name, Domain, @{Name = 'AD_Status'; Expression = {'Deleted'}}
            
            if (($CMComputerList.count -eq 0) -or ($ADComputerList.count -eq 0)) {
                #Do nothing since there are no objects in one of the computer lists.
            } else {
                $RemoveComputersFromSCCM += Compare-Object -ReferenceObject $ADComputerList -DifferenceObject $CMComputerList -IncludeEqual -ExcludeDifferent -Property Name, Domain | select Name, Domain, @{Name = 'AD_Status'; Expression = {'Disabled'}}
            }
            

        } catch {
            Write-Output 'An Error Occured'

        } finally {
            if ($RemoveComputersFromSCCM) {
                Write-Output $RemoveComputersFromSCCM
            } else {
                Write-Output ""
                Write-Output 'There are no objects to delete from SCCM'
            }
            

            #Remove the '-Whatif' when you're ready to actually delete the objects from SCCM.
            if ($DeleteComputers) {
                $RemoveComputersFromSCCM | Foreach {Remove-CMDevice -Name $_.Name -Force -WhatIf}
            }
        }
    }

    END {
        Set-Location C:\

    }

}

So when you run the script it will compare what’s in Active Directory and what’s in System Center Configuration Manager and check if the computer is either deleted or disabled in Active Directory. By using the DeleteComputers parameter it will delete the computers out of SCCM. By default it will only display the difference, and not delete.

Remove Disabled AD Computers

This screenshot is utilizing the -WhatIf parameter for testing purposes. Be sure to uncomment it out from the script when you’re ready to delete.

So that’s how you would remove disabled Active Directory computers from SCCM if you were wondering how to do it. The next step would be to set it up as a scheduled task so it gets ran every so often. This way you don’t continue to have inactive computers in your SCCM environment.

On another note, make sure you check out our YouTube Channel for more awesome sysadmin related content. And if you’re looking to further your Powershell or SCCM knowledge, be sure to check out Learn Powershell In a Month Of Lunches Book for Powershell and Learn SCCM in a Month of Lunches Book for System Center Configuration Manager.

4.8/5 - (23 votes)

Paul Contreras

Hi, my name is Paul and I am a Sysadmin who enjoys working on various technologies from Microsoft, VMWare, Cisco and many others. Join me as I document my trials and tribulations of the daily grind of System Administration.

2 Comments

  1. Did you get sorted Ron?
    Had this script running for years and always worked a treat. Recently migrated our site to new servers and can’t for the life of me get this to run.

    Confirmed both the Configuration Manager and Powershell modules are loaded.
    Previously was setup as a scheduled task on Server 2012. New server is 2022.

  2. i am trying to run your script to delete sccm record for a deleted or disabled machine in AD. i named it remove-disabledcomputersfromsccm.ps1. when i run it in powershell, it returns:
    remove-disabled-computers-from-sccm.ps1. it seems like it isn’t running. am i missing something?

Leave a Reply

Your email address will not be published.