VBScript: Use an LDAP Query to Find All Windows Servers on a Domain

Damn, the ADsDSOObject rocks! This script, which weighs in at less than 20 lines, finds all machines running any form of Windows Server on a given domain. Note that this script isn’t useful in finding domain controllers, but rather any machine running Windows Server.

Awesome

'****************************************************************************
' This script created by Chrissy LeMaire ([email protected])
' Website: http://netnerds.net/
'
' This script finds all machines running Windows Server (NT, 2000, 2003) in AD
'
'Msgbox output provides server name and OS version.
'
' NO WARRANTIES, USE THIS AT YOUR OWN RISK, etc.
'*****************************************************************************

Set objAdRootDSE = GetObject("LDAP://RootDSE")
Set objRS = CreateObject("adodb.recordset")

  varConfigNC = objAdRootDSE.Get("defaultNamingContext")
  strConnstring = "Provider=ADsDSOObject"
  strWQL = "SELECT * FROM 'LDAP://" & varConfigNC & "' WHERE objectCategory= 'Computer' and OperatingSystem = 'Windows*Server*'"
  objRS.Open strWQL, strConnstring
    Do until objRS.eof
   Set objServer = GetObject(objRS.Fields.Item(0))
strServerName = objServer.CN
strOperatingSystem = objServer.OperatingSystem
MsgBox strServerName & " is running " & strOperatingSystem
objRS.movenext
   Set objServer = Nothing
    Loop
  objRS.close

Set objRS = Nothing
Set objAdRootDSE = Nothing

Also, I found this nice reference of Command One Liners while searching the web. Totally handy!

Chrissy is a PowerShell MVP who has worked in IT for nearly 20 years, and currently serves as a Sr. Database Engineer in Belgium. Always an avid scripter, she attended the Monad session at Microsoft’s Professional Developers Conference in Los Angeles back in 2005 and has worked and played with PowerShell ever since. Chrissy is currently pursuing an MS in Systems Engineering at Regis University and helps maintain RealCajunRecipes.com in her spare time. She holds a number of certifications, including those relating to SQL Server, SuSE Linux, SharePoint and network security. She recently became co-lead of the SQL PASS PowerShell Virtual Chapter. You can follow her on Twitter at @cl.

Posted in Active Directory, Networking, VBScript
20 comments on “VBScript: Use an LDAP Query to Find All Windows Servers on a Domain
  1. I’m glad you found the one-liners handy. If you come up with any good ones, I hope you’ll share.

  2. Mike says:

    Thank you!

    This is just what I have been looking for!

    Mike

  3. MHC says:

    Perfect, works right out of the box.

  4. Mark C says:

    That’s a great script. However, is it possible to have the results outputted to a .csv file rather than being displayed in a message box?

  5. Andrew says:

    hi – wondering if you could help me with getting this output into a txt file?

    I’m a scripting newbie!

    Thanks

  6. Trond Hindenes says:

    Andrew,
    Change the MsgBox to wscript.echo, save your script and run like this:

    cscript myscriptfile.vbs >C:\output.txt

    The easist way to pipe to a text file instead of screen.

    -Trond

  7. Jerry Tienter says:

    Hi,

    This is a GREAT script. Could you please add some code to identify the sql server instances running on the server with the users and permissions?

    Thanks.

  8. joesph.sakar says:

    How do we enumerate AD windows servers in a domain across the trust

  9. Richard Gardner says:

    ” joesph.sakar | January 8, 2009 @ 11:59 pm
    How do we enumerate AD windows servers in a domain across the trust”

    I have not tried that but I would have to assume that you would need a few things to enumerate any info across trusts, and even then, I believe you would need to have rights granted in those trusted domains. You may even have to have an account in that domian, and instead change context

    ‘this line here presumes you are “in” the context for the information you are trying to seek.

    Set objAdRootDSE = GetObject(“LDAP://RootDSE”)

    You can instead explicitly note the context you want, and provide credentials, with a traditional LDAP bind/query.

    Remember that to get all fancy with code will usually lead to frustration, and to KISS. Usually, you already have a relationship with a local domain admin for the trusted domain, and you can simply hand him this script that Chrissy generously provides above. Or they can give you or you already have admin rights, if you are centrally managing the trusted domains from your central administrative domain.

    From within the central domain, you can only gain certain amounts of info about a trust (which equates to what the GUI gives you), see:

    http://www.activexperts.com/activmonitor/windowsmanagement/adminscripts/monitoring/ad/#EnumTrusRelationShips.htm

    Cheers!

  10. Edward Hong says:

    I used this script and it worked great, but I discovered that I’m running into a limitation of 1000 records. Any idea why, and any idea how I can increase the limit? (Yes, I’m dealing with a pretty huge AD structure). If I have to, I can change the Select criteria to search for OS versions individually, but I was hoping for a simple answer to this. Thanks!

  11. Ryan says:

    Edward,

    I know it has been a while since you posted this, but I thought I would reply to you about your question. LDAP limits its results to 1000 by default.

    Not sure how to get around this through a vbscript, but I ran into this on a vb.net app I built a few years ago.

  12. Alex says:

    If you are looking for a powershell version, you could try this:

    $strOperatingSystem = “Windows*Server*”

    $objDomain = New-Object System.DirectoryServices.DirectoryEntry

    $objSearcher = New-Object System.DirectoryServices.DirectorySearcher
    $objSearcher.SearchRoot = $objDomain

    $objSearcher.Filter = (“OperatingSystem=$strOperatingSystem”)

    $colProplist = “name”
    foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}

    $colResults = $objSearcher.FindAll()

    foreach ($objResult in $colResults)
    {
    $objComputer = $objResult.Properties;
    $objComputer.name
    }

  13. Grant Pagliaro says:

    Thanks, had a similar requirement and this helped a lot.

  14. Catalin says:

    Looks great! Thank you very much!

    Does anyone know what I should change to get this script to enumerate all servers from the entire forest?

    Thanks in advance

  15. Catalin says:

    –EDIT–
    Found how: — just replace:

    <> in
    varConfigNC = objAdRootDSE.Get(“defaultNamingContext”)

    with

    <>

    Still, I am reaching the 1000 limit too :(

  16. MountyTech says:

    Hi,

    Thanks for the script. Do you know how I could limit the search by OU? Not the whole domain.

    Thanks

  17. Toxie says:

    By default, mazpagesize is set to 1000 so only 1000 results will be returned. It's an AD thing.

    ntdsutil "LDAP Policies" connections "connect to server %DCNAME%" q "set maxpagesize to 3000" "commit changes" q q

  18. masterblaster says:

    Tried to add serial number from the list of gathered servers with no luck. Any ideas?

    '****************************************************************************
    ' This script created by Chrissy LeMaire ([email protected])
    ' Website: http://netnerds.net/
    '
    ' This script finds all machines running Windows Server (NT, 2000, 2003) in AD
    '
    'Msgbox output provides server name and OS version.
    '
    ' NO WARRANTIES, USE THIS AT YOUR OWN RISK, etc.
    '*****************************************************************************

    Set objAdRootDSE = GetObject("LDAP://RootDSE")
    Set objRS = CreateObject("adodb.recordset")

    varConfigNC = objAdRootDSE.Get("defaultNamingContext")
    strConnstring = "Provider=ADsDSOObject"
    strWQL = "SELECT * FROM 'LDAP://" & varConfigNC & "' WHERE objectCategory= 'Computer' and OperatingSystem = 'Windows*Server*'"
    objRS.Open strWQL, strConnstring
    Do until objRS.eof
    Set objServer = GetObject(objRS.Fields.Item(0))
    strServerName = objServer.CN
    strOperatingSystem = objServer.OperatingSystem

    Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\" & strServerName & "rootcimv2")
    Set colSMBIOS = objWMIService.ExecQuery ("SELECT * FROM WIN32_BIOS", ,48)

    For Each objSMBIOS in colSMBIOS
    wscript.echo "Host Name:" & strServerName
    wscript.echo "OS Version:" & strOperatingSystem
    Wscript.Echo "Service Tag: " & objSMBIOS.SerialNumber
    Wscript.Echo "—–"

    objRS.movenext
    Set objServer = Nothing
    Loop
    objRS.close

    Set objRS = Nothing
    Set objAdRootDSE = Nothing

  19. Todd says:

    Slighly modified powershell script from above that changes the max pagesize limit to 4000 from default 1000..

    ## Start

    $strOperatingSystem = “Windows*Server*”

    $objDomain = New-Object System.DirectoryServices.DirectoryEntry

    $objSearcher = New-Object System.DirectoryServices.DirectorySearcher
    $objSearcher.SearchRoot = $objDomain

    $objSearcher.PageSize = 4000
    $objSearcher.Filter = (“OperatingSystem=$strOperatingSystem”)

    $colProplist = “name”
    foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}

    $colResults = $objSearcher.FindAll()

    foreach ($objResult in $colResults)
    {
    $objComputer = $objResult.Properties;
    $objComputer.name
    }

Leave a Reply

Your email address will not be published. Required fields are marked *

*