How to LDAP query without knowing exact OU - vbscript

Set objDomain = GetObject("WinNT://abc.local")
For each objDomainItem in objDomain
if objDomainItem.Class = "User" then
'WScript.echo "Name: " & objDomainItem.Name + " : Full Name: " + objDomainItem.FullName
Set objUser = Nothing
err.clear
Set objUser = GetObject("LDAP://cn=" & objDomainItem.FullName & ",OU=IS, OU=Users, OU=ABC Company, DC=ABC, dc=local")
if err.number = 0 then
wscript.echo "distinguishedName: " & objUser.distinguishedName
end if
end if
Next
Right now, this works fine to list all users in the IS department (OU=IS). But when I take out "OU=IS" to list all users in all departments, it returns nothing; no user objects at all. The only way it will return the user object for the given fullName is if I also specify the OU that that user is contained in; but I do not have the OU to supply it.
Our AD structure is
ABC Company --> Users --> IS
ABC Company --> Users --> FINANCE
ABC Company --> Users --> Management
ABC Company --> Users --> Flight Operations
etc etc etc
I want to use the code above to enumerate all users from the "Users" level, down through ALL departments, but again, as soon as I remove "OU=IS", it returns nothing.
Any help?

Do a query with scope Subtree using an ADODB.Connection and an ADODB.Command object:
base = "<LDAP://OU=Users,OU=ABC Company,DC=ABC,DC=local>"
fltr = "(&(objectClass=user)(objectCategory=Person))"
attr = "distinguishedName,sAMAccountName"
scope = "subtree"
Set cn = CreateObject("ADODB.Connection")
cn.Provider = "ADsDSOObject"
cn.Open "Active Directory Provider"
Set cmd = CreateObject("ADODB.Command")
Set cmd.ActiveConnection = cn
cmd.CommandText = base & ";" & fltr & ";" & attr & ";" & scope
Set rs = cmd.Execute
Do Until rs.EOF
WScript.Echo rs.Fields("distinguishedName").Value
WScript.Echo rs.Fields("sAMAccountName").Value
rs.MoveNext
Loop
Add other attributes to attr as required (the variable contains a list of attribute names as a comma-separated string).
Since these queries require the same boilerplate code every time, I got fed up with writing it over and over again some time ago and wrapped it in a custom class (ADQuery) to simplify its usage:
'<-- paste or include class code here
Set qry = New ADQuery
qry.SearchBase = "OU=Users,OU=ABC Company,DC=ABC,DC=local"
qry.Attributes = Array("distinguishedName", "sAMAccountName")
Set rs = qry.Execute
Do Until rs.EOF
WScript.Echo rs.Fields("distinguishedName").Value
WScript.Echo rs.Fields("sAMAccountName").Value
rs.MoveNext
Loop

Related

Put DN into variable VBS

I am creating a script that will allow me to enter a username in our domain, and have it look up attributes from their AD profile.
So first I am getting the users' DN. Once I have that - I can run;
Set objAD = CreateObject("ADSystemInfo")
Set objUser = GetObject("LDAP://" & ***I NEED DN HERE***)
and query specific attributes to be output.
So what I need to do is somehow get the DN into a variable to put into the LDAP query. I know (I think) I need to get it from the Do Loop below, but am having a complete blank and can't figure out how to just put the whole DN into a variable.
Username = InputBox("Enter UserName to lookup...")
Set rootDSE = GetObject("LDAP://RootDSE")
base = "<LDAP://" & rootDSE.Get("defaultNamingContext") & ">"
fltr = "(&(objectClass=user)(objectCategory=Person)" & "(sAMAccountName=" & UserName & "))"
attr = "distinguishedName,sAMAccountName"
scope = "subtree"
Set conn = CreateObject("ADODB.Connection")
conn.Provider = "ADsDSOObject"
conn.Open "Active Directory Provider"
Set cmd = CreateObject("ADODB.Command")
Set cmd.ActiveConnection = conn
cmd.CommandText = base & ";" & fltr & ";" & attr & ";" & scope
Set rs = cmd.Execute
Do Until rs.EOF
WScript.Echo rs.Fields("distinguishedName").Value
rs.MoveNext
Loop
rs.Close
conn.Close
In case anyone has the same problem - it was an easy fix.
Just needed to write it to a variable instead of echoing.
Do Until rs.EOF
strDN = rs.Fields("distinguishedname").value
rs.MoveNext
Loop

How to retrieve All attributes of given user from given group in ActiveDirectory using VBScript?

Can anyone help me to get All Attributes of given user in given group from active-directory using Vb Script .
On Error Resume Next
Set objGroup = GetObject _
("LDAP://CN=Domain Admins,CN=Users,DC=IMTS,DC=TEST")
objGroup.GetInfo
arrMemberOf = objGroup.GetEx("member")
WScript.Echo "Members:"
For Each strMember in arrMemberOf
WScript.echo strMember.distinguishedName
Next
This is giving me only users in group but i want all attributes on given user
eg:
Account_Expires:
Account_Name_History:
CS_PolicyName:
Admin_Count:
Admin_Description:
Admin_DisplayName:
AllowedAttributes:
AllowedAttributesEffective:
Allowed_Child_Classes:
AllowedChildClassesEffective:
AltSecurityIdentities:
AttributeCertificateAttribute:
Audio:
Bad_Password_Time:
Bad_Pwd_Count:
Bridge_head_ServerListBL:
BusinessCategory:
C:
canonicalName:
carLicense:
co:
So on
Thanks
note: Sorry, I'm not in an environment where I could test it and all this answer is just a memory exercise. I hope it can help
You could try to query the LDAP schema for the User class
Set oSchema = GetObject("LDAP://schema/user")
Then, you can iterate over the MandatoryProperties and OptionalProperties collections storing the retrieved values to later check your users for these attributes
Set oAttributesList = WScript.CreateObject("Scripting.Dictionary")
For Each strAttribute In oSchema.MandatoryProperties
oAttributesList.Add strAttribute, ""
Next
For Each strAttribute In oSchema.OptionalProperties
oAttributesList.Add strAttribute, ""
Next
And once you have the full list, you could use GetEx to retrieve (as an array) the value of each of the attributes for each of the users
Set objGroup = GetObject _
("LDAP://CN=Domain Admins,CN=Users,DC=IMTS,DC=TEST")
objGroup.GetInfo
arrMemberOf = objGroup.GetEx("member")
WScript.Echo "Members:"
For Each strMember in arrMemberOf
Set oMember = GetObject("LDAP://" & strMember)
For Each strAttribute in oAttributesList.Keys
WScript.Echo strAttribute
aData = oMember.GetEx(strAttribute)
For i = 0 to UBound(aData)
WScript.Echo "....: " & aData(i)
Next
WScript.Echo ""
Next
Next

How to find the GUID of a GPO given it's name?

Does anyone know of a way to find the GUID of a specific GPO given its name using VBScript? I've seen a lot of examples to go from a GUID to a GPO, but not the other way around.
Use an LDAP query that filters for a given display name. The name attribute of the GPO contains the GUID.
displayName = "..."
domain = GetObject("LDAP://rootDSE").Get("defaultNamingContext")
Set cn = CreateObject("ADODB.Connection")
cn.Provider = "ADsDSOObject"
cn.Open "Active Directory Provider"
Set cmd = CreateObject("ADODB.Command")
Set cmd.ActiveConnection = cn
cmd.CommandText = "SELECT name " & _
"FROM 'LDAP://CN=Policies,CN=System," & domain & "' " & _
"WHERE objectClass = 'groupPolicyContainer' AND " & _
"displayName = '" & displayName & "'"
Set rs = cmd.Execute
Do Until rs.EOF
WScript.Echo rs.Fields("name").Value
rs.MoveNext
Loop

Search in active directory forest

I have multiple domains in our Active Directory like below:
pnc.com → root domain
europe.pnc.com → Child domain
asia.pnc.com → Child domain
americas.pnc.com → Child domain
I want a write a VBScript that can search for a user in entire forest and show me the location of the user object.
I have tried in the past searching like this but I had to give the exact domain name.
You need to enable referral chasing for subordinate domains:
Set rootDSE = GetObject("LDAP://RootDSE")
base = "<LDAP://" & rootDSE.Get("defaultNamingContext") & ">"
filter = "(&(objectClass=user)(objectCategory=Person))"
attr = "distinguishedName"
scope = "subtree"
Set conn = CreateObject("ADODB.Connection")
conn.Provider = "ADsDSOObject"
conn.Open "Active Directory Provider"
Set cmd = CreateObject("ADODB.Command")
Set cmd.ActiveConnection = conn
cmd.Properties("Chase referrals") = &h20
cmd.CommandText = base & ";" & filter & ";" & attr & ";" & scope
Set rs = cmd.Execute
...
Back in the day I wrote a wrapper class for AD queries, which enables this by default:
'add/import class here
Set qry = New ADQuery
qry.Filter = "..."
qry.Attributes = Array("sAMAccountName", ...)
Set rs = qry.Execute
...

VBScript \ Active Directory Searched by displayname and received 2 of the same

I have my script to search by displayname and return the userid, which works fine.
but when I encounter a displayname that has 2 entries in AD i.e.
pavle stojanovic - he is from company 1
pavle stojanovic - he is from company 2
the userid doesnt get displayed because the script doesnt know what to do ?
how do i over come this ? if I get a return of 2 or more I'd like to say in the output hey i found the same name twice etc.. here are the userids and companies for both.
If you want to see the script its below...
strFile = objFSO.GetParentFolderName(Wscript.ScriptFullName) & "\users.xls"
Set objWorkbook = objExcel.Workbooks.Open(strFile)
objWorkbook.Activate
objExcel.Visible = False
intRow = 2 ' starts reading file at line 2
' this part runs a loop through the excel file reading each userid and getting data requested.
' ---------------------------------------------------------------------------------------------
Do Until objExcel.Cells(intRow,1).Value = ""
ExcelRow = objExcel.Cells(intRow, 1)
Call GetOU ' calling sub to search
intRow = intRow + 1
Loop
' This section just formats the excel file to widen the columns
' --------------------------------------------------------------
Set objRange = objExcel.Range("A1")
objRange.Activate
Set objRange = objExcel.ActiveCell.EntireColumn
objRange.AutoFit()
Set objRange = objExcel.Range("B1")
objRange.Activate
Set objRange = objExcel.ActiveCell.EntireColumn
objRange.AutoFit()
Set objRange = objExcel.Range("C1")
objRange.Activate
Set objRange = objExcel.ActiveCell.EntireColumn
objRange.AutoFit()
Set objRange = objExcel.Range("D1")
objRange.Activate
Set objRange = objExcel.ActiveCell.EntireColumn
objRange.AutoFit()
objExcel.ActiveWorkbook.Save
objExcel.Quit
' Sub to get Details for user
' ----------------------------
Sub GetOU
On Error Resume Next
Set objRootDSE = GetObject("LDAP://RootDSE")
strDomain = objRootDSE.Get("DefaultNamingContext")
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand = CreateObject("ADODB.Command")
Set objCommand.ActiveConnection = objConnection
objCommand.Properties("Size Limit") = 100000
objCommand.Properties("Searchscope") = 2
objCommand.CommandText = "SELECT distinguishedName FROM 'LDAP://" & _
strDomain & _
"' WHERE objectCategory='User' AND DisplayName = '" & _
ExcelRow & "'"
Set objRecordSet = objCommand.Execute
If Not objRecordSet.EOF Then
strDN = objRecordSet.Fields("distinguishedName").Value
' ###########################################################
' ###########################################################
' This is where the script does 'its thing' ...
' gets what you want.
' ------------------------------------------------
Set MyUser = GetObject ("LDAP://" & strDN)
objExcel.Cells(intRow, 3).Value = UCASE(MyUser.SamAccountName)
' ###########################################################
' ###########################################################
Else
Wscript.Echo "User Not Found: " & ExcelRow
End If
Err.Clear
End Sub
If multiple accounts are found, the Record Set will have multiple records and you'll need to loop through it. Your code currently only gets the first item in the Record Set.
Change If Not objRecordSet.EOF Then to Do While Not objRecordSet.EOF
Then
strDN = objRecordSet.Fields("distinguishedName").Value
' ###########################################################
' ###########################################################
Set MyUser = GetObject ("LDAP://" & strDN)
When inserting the users into the spreadsheet, you'll want to control the placement of the cell dynamically so the same cell isn't written over at each loop.
objExcel.Cells(intRow, 3).Value = UCASE(MyUser.SamAccountName)
At the end of processing this user, you'll use this to move to the next object (user) in the Record Set
objRecordSet.MoveNext
Then instead of End If, you'll use Loop
EDIT:
Also, instead of connecting to the object using Set MyUser = GetObject(etc), could you just use "SELECT sAMAccountName FROM... in your query then strsAMAccountName = objRecordSet.Fields("sAMAccountName") to save some memory/time?
Edit2:
I am doing this in my script.
If objRecordSet.RecordCount = 0 Then
'Things to do if not found
Exit Sub 'Then exit before entering loop
End If
Also, if the user isn't found then objRecordSet.EOF will equal True.

Resources