Hey everyone,
Last week, I wrote a script to gather information about every computer registered in our database for some software we use. Now, I want to check if each computer has an active entry in our Active Directory (AD). If they don't, I need to delete them from the database.
Currently, I have about 15,000 PCs stored in an array. I'm using a foreach loop to run `Get-ADComputer "PCName" -properties name | select -exp name` within a try-catch block. If `Get-ADComputer` can't find a PC, I save that entry in the catch block.
This process takes me around 5-10 minutes. Is there a way to speed up the checks to see if an AD object exists?
4 Answers
Another effective strategy is to pull all computers from AD into a single array first, instead of checking each one individually. You can do something like:
```powershell
$ADarray = Get-ADComputer -Filter *
$NotInAD = $DBarray | where { $_.Computername -notin $ADarray.Name }
```
This way, you're only querying AD once, and then performing your comparisons locally, which should significantly reduce the time taken!
Consider querying by Organizational Unit (OU) if you know where your computers are. Filtering like this can limit the number of results returned and speed up your queries. For big organizations, one query returning a few hundred objects is way better than thousands of singular queries!
Totally! Targeting specific OUs and bringing back relevant info can save tons of time.
You can speed up your script significantly by using an LDAP filter instead of running `Get-ADComputer` for each PC. Build a single LDAP filter that queries for all your computers in one go, like this:
```powershell
$ldapFilter = "(|(samAccountName={0}`$))" -f ($allComputer.ComputerName -join '$)(samAccountName=')
Get-ADComputer -ldapFilter $ldapFilter
```
This way, you only send one query to the Active Directory. Make sure the total size of the filter doesn’t exceed limits set by Active Directory, and if it does, break it down into smaller batches and process concurrently using `foreach -Parallel` to speed things up even more!
Keep in mind the `MaxTempTableSize` constraint while building your LDAP filter. If you're hitting limits, consider batching your queries into smaller groups.
If you're dealing with large datasets, using HashSets for comparisons can be much faster than traditional methods. Here’s a sample:
```powershell
$adComputers = [System.Collections.Generic.HashSet[string]]::new()
Get-ADComputer -Filter * -Properties Name | ForEach-Object { $adComputers.Add($_.Name) }
$dbComputers = [System.Collections.Generic.HashSet[string]]::new()
# Populate your $dbComputers here
$dbComputers.ExceptWith($adComputers)
```
This reduces the time complexity when comparing your lists and makes it way more efficient!
That's a great point - HashSets can really improve performance when you're dealing with large amounts of data.
Exactly! And using a return of all objects in one batch will save a lot of processing time.