locked
Active Directory Query RRS feed

  • Question

  • I'm trying to find a way to search AD to find all users who have the 'userWorkstations' ADSI attribute populated with a certain computer name. (ex. COMPUTER001) Anybody have any ideas?

    G14TS

    Wednesday, December 4, 2013 7:10 PM

Answers

  • Something like this, perhaps:


    PS C:\> get-aduser -filter { userWorkstations -like '*computer001*' } -properties userWorkstations

    Bill

    • Marked as answer by G. Kirk Wednesday, December 4, 2013 7:58 PM
    Wednesday, December 4, 2013 7:28 PM
  • This is a 2003 domain and powershell is not loaded on the DCs. Also I can't add it because it would go against my accredidation. Is there a vbs script that could do this?

    G14TS

    The DCs don't need PowerShell installed, they just need the Active Directory Management Gateway. You can use the AD module from a workstation.

    As for a VBScript method, start your search here:

    http://gallery.technet.microsoft.com/scriptcenter


    Don't retire TechNet! - (Don't give up yet - 12,420+ strong and growing)

    • Marked as answer by G. Kirk Wednesday, December 4, 2013 7:57 PM
    Wednesday, December 4, 2013 7:40 PM
  • Found one that works. Thanks Mike!

    On Error Resume Next 
     
    Const ADS_SCOPE_SUBTREE = 2 
     
    Set objConnection = CreateObject("ADODB.Connection"Set objCommand =   CreateObject("ADODB.Command") 
    objConnection.Provider = "ADsDSOObject" 
    objConnection.Open "Active Directory Provider" 
    Set objCommand.ActiveConnection = objConnection 
     
    objCommand.Properties("Page Size") = 1000 
    objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE  
     
    objCommand.CommandText = _ 
        "SELECT Name FROM 'LDAP://dc=fabrikam,dc=com' WHERE objectCategory='user' " & _ 
            "AND userWorkstations='*atl-ws-01*'" 
    Set objRecordSet = objCommand.Execute 
     
    objRecordSet.MoveFirst 
    Do Until objRecordSet.EOF 
        Wscript.Echo objRecordSet.Fields("Name").Value 
        objRecordSet.MoveNext 
    Loop 


    G14TS

    • Marked as answer by G. Kirk Wednesday, December 4, 2013 7:57 PM
    Wednesday, December 4, 2013 7:56 PM
  • You don't even need VBScript. A custom search in ADUC will do it. The LDAP query is:


    (&(objectCategory=person)(objectClass=user)(userWorkstations=*computer001*))

    Bill

    • Marked as answer by G. Kirk Wednesday, December 4, 2013 8:00 PM
    Wednesday, December 4, 2013 7:57 PM

All replies

  • This is a 2003 domain and powershell is not loaded on the DCs. Also I can't add it because it would go against my accredidation. Is there a vbs script that could do this?

    G14TS

    Wednesday, December 4, 2013 7:28 PM
  • Something like this, perhaps:


    PS C:\> get-aduser -filter { userWorkstations -like '*computer001*' } -properties userWorkstations

    Bill

    • Marked as answer by G. Kirk Wednesday, December 4, 2013 7:58 PM
    Wednesday, December 4, 2013 7:28 PM
  • This is a 2003 domain and powershell is not loaded on the DCs. Also I can't add it because it would go against my accredidation. Is there a vbs script that could do this?

    G14TS

    The DCs don't need PowerShell installed, they just need the Active Directory Management Gateway. You can use the AD module from a workstation.

    As for a VBScript method, start your search here:

    http://gallery.technet.microsoft.com/scriptcenter


    Don't retire TechNet! - (Don't give up yet - 12,420+ strong and growing)

    • Marked as answer by G. Kirk Wednesday, December 4, 2013 7:57 PM
    Wednesday, December 4, 2013 7:40 PM
  • Found one that works. Thanks Mike!

    On Error Resume Next 
     
    Const ADS_SCOPE_SUBTREE = 2 
     
    Set objConnection = CreateObject("ADODB.Connection"Set objCommand =   CreateObject("ADODB.Command") 
    objConnection.Provider = "ADsDSOObject" 
    objConnection.Open "Active Directory Provider" 
    Set objCommand.ActiveConnection = objConnection 
     
    objCommand.Properties("Page Size") = 1000 
    objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE  
     
    objCommand.CommandText = _ 
        "SELECT Name FROM 'LDAP://dc=fabrikam,dc=com' WHERE objectCategory='user' " & _ 
            "AND userWorkstations='*atl-ws-01*'" 
    Set objRecordSet = objCommand.Execute 
     
    objRecordSet.MoveFirst 
    Do Until objRecordSet.EOF 
        Wscript.Echo objRecordSet.Fields("Name").Value 
        objRecordSet.MoveNext 
    Loop 


    G14TS

    • Marked as answer by G. Kirk Wednesday, December 4, 2013 7:57 PM
    Wednesday, December 4, 2013 7:56 PM
  • You don't even need VBScript. A custom search in ADUC will do it. The LDAP query is:


    (&(objectCategory=person)(objectClass=user)(userWorkstations=*computer001*))

    Bill

    • Marked as answer by G. Kirk Wednesday, December 4, 2013 8:00 PM
    Wednesday, December 4, 2013 7:57 PM
  • I will save this PS script for future use. Thanks!

    G14TS

    Wednesday, December 4, 2013 7:57 PM
  • I am new to this.... but wont this query return a user name even if the computer name is say...computer0012345

    Thursday, June 30, 2016 10:15 AM
  • this query will also return a user if his workstation name is Mycomputer001234

    just because it has a matching substring.....

    Thursday, June 30, 2016 10:17 AM
  • The problem here is that the userWorkstations attribute is not a multi-valued array of computer names. Instead, it is a single valued string of comma delimited computer names. The computer name of interest could the first, the last, or somewhere in the middle of the string of names. The only reliable filter uses the wildcard character before and after the name. As noted, this also allows a match with other similar names. The only solution is to find all users with a possible match, then split the value by commas, and check each one. For example:

    Option Explicit
    
    Dim adoCommand, adoConnection, strBase, strFilter, strAttributes
    Dim objRootDSE, strDNSDomain, strQuery, adoRecordset, strUser
    Dim arrComputers, strComputer, strName
    
    strName = InputBox("Enter computer name")
    
    ' Setup ADO objects.
    Set adoCommand = CreateObject("ADODB.Command")
    Set adoConnection = CreateObject("ADODB.Connection")
    adoConnection.Provider = "ADsDSOObject"
    adoConnection.Open "Active Directory Provider"
    Set adoCommand.ActiveConnection = adoConnection
    
    ' Search entire Active Directory domain.
    Set objRootDSE = GetObject("LDAP://RootDSE")
    strDNSDomain = objRootDSE.Get("defaultNamingContext")
    strBase = "<LDAP://" & strDNSDomain & ">"
    
    ' Filter on user objects.
    strFilter = "(userWorkstations=*" & strName & "*)"
    
    ' Comma delimited list of attribute values to retrieve.
    strAttributes = "sAMAccountName,userWorkstations"
    
    ' Construct the LDAP syntax query.
    strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
    adoCommand.CommandText = strQuery
    adoCommand.Properties("Page Size") = 100
    adoCommand.Properties("Timeout") = 30
    adoCommand.Properties("Cache Results") = False
    
    ' Run the query.
    Set adoRecordset = adoCommand.Execute
    
    ' Enumerate the resulting recordset.
    Do Until adoRecordset.EOF
        ' Retrieve values and display.
        strUser = adoRecordset.Fields("sAMAccountName").Value
        arrComputers = Split(adoRecordset.Fields("userWorkstations").value, ",")
        For Each strComputer In arrComputers
            If (LCase(strComputer) = LCase(strName)) Then
                Wscript.Echo strUser
            End If
        Next
        adoRecordset.MoveNext
    Loop
    
    ' Clean up.
    adoRecordset.Close
    adoConnection.Close
    

    My filter does not include clauses to restrict the query to users because the attribute should only apply to user objects anyway. Technically, computer objects also have this attribute (because they have class user as well as computer), but it would be silly to assign values to computers.

    Richard Mueller - MVP Enterprise Mobility (Identity and Access)

    Thursday, June 30, 2016 2:39 PM