Looking for help speeding up a get-adcomputer query

I’m using the following query to get all the servers that do NOT have the Print-Server role installed. The query takes about 8 minutes to complete. I’m wondering if there is a faster way to retrieve this?

#Create an array for the $ServerDetails objects and the hashtable for them
$EnabledADServers = @()

#get the servers from Active Directory
get-adcomputer -Filter * -Property Name,OperatingSystem,Enabled,DistinguishedName,IPv4Address,DNSHostname | 
Where-Object { ($_.OperatingSystem -like '*Server*') -and ($_.DistinguishedName -notlike "OU=Disabled_Servers,OU=ComputerAccounts,DC=DOMAIN,DC=ca") -and ($_.Enabled -eq "Enabled")} |
Select-Object Name,OperatingSystem,Enabled,DistinguishedName,IPv4Address,DNSHostname | 
    ForEach-Object -Process { 
        $ServerDetails = [PSCustomObject]@{
            FQDN = 'Empty'
            Enabled = 'Empty'
            PrintServer = 'Empty'
            PrintSpooler = 'Empty'
            PrintSpoolerStartType = 'Empty'
            PrintSpoolerSatus = 'Empty'
            PrintSpoolerStartTypeNow = 'Empty'
            Resolveable = 'Empty'
            WinRMEnabled = 'Empty'
        #Populate hash table to hold the server details
        $ServerDetails.FQDN = $_.DNSHostname
        $ServerDetails.Enabled = $_.Enabled

        #Save to the global array
        $EnabledADServers+= $ServerDetails

Of course I cannot imagine your AD structure but a query like this usually takes only seconds to complete.

Depending on your AD structure I highly recommend to use a search base for your queries. It will probably be much faster to specify the OUs you want to query instead of querying all of them and filter them away later on.

So assumed you can specify one OU to search for this should be enough:

$SearchBase = 'OU=Enabled_Servers,OU=ComputerAccounts,DC=DOMAIN,DC=ca'
$EnabledADServers = 
Get-ADComputer -Filter "Enabled -eq '$true'" -SearchBase $SearchBase -Properties OperatingSystem, IPv4Address | 
Where-Object { ($_.OperatingSystem -like '*Server*') } |
ForEach-Object -Process {
        FQDN                     = $_.DNSHostname
        Enabled                  = $_.Enabled
        OperatiingSystem         = $_.OperatingSystem
        PrintServer              = 'Empty'
        PrintSpooler             = 'Empty'
        PrintSpoolerStartType    = 'Empty'
        PrintSpoolerSatus        = 'Empty'
        PrintSpoolerStartTypeNow = 'Empty'
        Resolveable              = 'Empty'
        WinRMEnabled             = 'Empty'

I made up a name for the OU to search for - of course you should use an existing one from your AD. If you want to query more than one OU you simply use a loop. :wink:

And BTW: you’re actually not querrying yet the installed roles of the servers. You will have to do that inside your loop in front of the [PSCustomObject].

If you’re actually querying the servers inside your loop and you just did not show this code the answer would be different then. :wink:

Thank you. That helped considerably. It now returns the enabled servers in just 6 seconds.
Edit: I am searching all of AD. To many acquisitions/sales and IT expansions/contractions so our AD is full of defunct computers. Just in servers, AD has nearly a thousand. In actual it’s less than 500. The scripting is to identify defunct vs live among other things.

I’m glad to hear that. Thanks. :wink:

If you do this regularily you should read about LDAP filters. :wink: