Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations biv343 on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Problems building AD connection strings

Status
Not open for further replies.

kmcferrin

MIS
Jul 14, 2003
2,938
US
Hey all, I have a script at work here that is basically a modified version of another script that connects to a group of domains, does a query for admin groups, checks memberships of those groups, etc. Sample code for the piece that I'm having problems with is below:

Code:
arrDomains = Array("domain1.local", "domain2.local", "domain3.local", 
"child1.domain1.local", "child2.domain2.local", "child3.domain3.local")

For i = 0 to UBound(arrDomains)


    'Unless you want to change the domain to check or the format of the 
emailed info, nothing below really needs to be modified.
    On Error Resume Next
    numPersonCount = 0

    arrDNames = Split(arrDomains(i), ".")
    strDSE = "LDAP://"
    For x = 0 to UBound(arrDNames)
        If x = UBound(arrDNames) Then
            strDSE = strDSE & "DC=" & arrDNames(x)
        Else
            strDSE = strDSE & "DC=" & arrDNames(x) & ","
        End If
    Next
    Wscript.Echo strDSE

    Set objAdRootDSE = GetObject("strDSE")
    Set objRS = CreateObject("adodb.recordset")
    varConfigNC = objAdRootDSE.Get("DefaultNamingContext")
    Wscript.Echo "varConfigNC = " & varConfigNC
    strConnstring = "Provider=ADsDSOObject"
    'strWQL = "SELECT ADsPath FROM 'LDAP://" & varConfigNC & "' WHERE 
modifyTimeStamp > '" & strTimeInUTC & "' and (objectCategory = 'Group') and 
(name = 'Domain Admins' or name = 'Administrators' or name = 'Enterprise Admins' or name = 'Schema Admins')"
    strWQL = "SELECT ADsPath FROM '"& varConfigNC & "' WHERE 
(objectCategory = 'Group') and (name = 'Domain Admins' or name = 
'Administrators' or name = 'Enterprise Admins' or name = 'Schema Admins')"
        Wscript.Echo strWQL
        objRS.Open strWQL, strConnstring
        Wscript.Echo "Connection Made"
        Do until objRS.eof

The problem that I'm having is that at some point arrDomains will probably be fed from a text for or something similar, so I cannot hard-code values for objAdRootDSE. I have to be able to parse the array elements, construct the LDAP:// connection strings manually, then connect to the domains. I've traced the problem to this line:

Code:
varConfigNC = objAdRootDSE.Get("DefaultNamingContext")

varConfigNC does not get assigned to anything, so my WQL statement is missing an element. It comes out looking like this:

Code:
SELECT ADsPath FROM ' WHERE (objectCategory = 'Group') and (name = 
'Domain Admins' or name = 'Administrators' or name = 'Enterprise Admins' or 
name = 'Schema Admins')

I've had these problems with other scripts where I couldn't dynamically create the connections, and I always had to put in some statements where a user could make a choice that would then set objAdRootDSE manually to the correct value. But that won't work in this case because the list of domains could change regularly.

I have tried using:

Code:
Set objAdRootDSE = GetObject("strDSE")

both with and without the quotes, but I'm not sure how else to do it. Any suggestions?
 
What happens if you use this ?
Set objAdRootDSE = GetObject(strDSE)

Hope This Helps, PH.
FAQ219-2884
FAQ181-2886
 
Sorry, I formatted that a bit oddly so you probably missed the last line. It doesn't work either way, the results are identical.
 
What is displayed by this statement ?
Wscript.Echo strDSE

Hope This Helps, PH.
FAQ219-2884
FAQ181-2886
 
Which error raises if you comment out the On Error Resume Next instruction ?

Hope This Helps, PH.
FAQ219-2884
FAQ181-2886
 
I have also tried inserting "chr(34)" into the lines that build strDSE so that strDSE ends up being:

"LDAP://DC=sci,DC=local"

But that still doesn't work.
 
Heh. I didn't even see that in there. That's what I get for re-using a co-workers code.

C:\domainadminsgroupsmodified.vbs(55, 5) Active Directory: The directory property cannot be found in the cache.
 
[1]
>I have tried using
>Set objAdRootDSE = GetObject("strDSE")
>both with and without the quotes
There you shouldn't even attempt to try. No quote: that's clear.

[2] As the domain1.local is apprently not containing domain2.local, hence, in general case, they are not in the same forest. Plus, the user executing the script is logged onto a domain which can be anything than the domains specifying in the array, hence, it is more so need to bind to the proper domain in the array with supplied credential otherwise it won't work.

[3] You can discover the domain the user who execute the script is in by the standard ritual.
[tt]
set objRootDSE = GetObject("LDAP://rootDSE")
wscript.echo "LDAP://" & objRootDSE.Get("defaultNamingContext")
[/tt]
If again you found
>"LDAP://DC=sci,DC=local"
then it is clear that the use executing the script is not even in any of the domains in the array!

[4] Hence, the critical element is to bind to the domains in the array furnishing proper credential of the user (which may or may not succeed). To supply credential, you do it by opendsobject of dso...
ref If you bind serverless, just take out the flag ADS_SERVER_BIND and use only ADS_SECURE_AUTHENTICATION flag.

After successfully bind the correct domain, you could start contemplating doing the rest.
 
>"LDAP://DC=sci,DC=local"

That was a mistake. I just wasn't as thorough as I should have been in anonymizing my post. But sci.local does correspond to domain1.local in my example, and the script is being executed by an account that is in the sci.local/domain1.local domain, and that domain is trusted by all other domains (this account does have the ability to authetnicate and manage all of the other domains listed). But the error that I am getting is on the first domain, which is where the account holds domain admin rights. So it shouldn't be anything authentication related.
 
So I guess what it comes down to is, what is the correct syntax for using a variable in place of the "LDAP://rootDSE" in:

Code:
    Set objAdRootDSE = GetObject("LDAP://rootDSE")
    Set objRS = CreateObject("adodb.recordset")
    varConfigNC = objAdRootDSE.Get("DefaultNamingContext")

 
>what is the correct syntax for using a variable in place of the "LDAP://rootDSE"
[tt]
x="LDAP://rootDSE"
Set objADRootDSE=GetObject(x)
varConfigNC = objAdRootDSE.Get("DefaultNamingContext")
[/tt]
x at the place is just like the strDSE is. But rootDSE is a special object requested by the standard/RFC that every LDAP directory to maintain. You sure cannot use indiscriminately any other ads object and apply the syntax of get("defaultnamingcontext") because they don't have that attribute.
 
OK. So what you're saying is that because rootDSE is a special object, you cannot construct a variable that holds the same value as the name of rootDSE (or rootDSE from another domain) and then bind to that value. I see.

So is there any way that you can think of to dynamically create a name for a domain that you want to bind to for executing queries? Or am I stuck to having it hard-coded in the script?
 
But the way you make out strDSE is fine (using split etc...). Only that you said it failed to bind to the object: the objAdDSE (how it is named does not matter) being "nothing". That's why I think you should look into the credential problem. I may be wrong. I, like anybody else, cannot look through the screen to the other side of the wire.
 
Now I feel stupid, but after stepping through this line by line I found the problem. The problem is that this line is trying to get the default naming context of what I set the objAdRootDSE to previously:

Code:
varConfigNC = objAdRootDSE.Get("DefaultNamingContext")

But it's actually unnecessary. If I'm pre-loading the domains from an array, then I already know the default naming contexts for those domains. So if I dump that line and then replace all instances of varConfigNC with strDSE then I should be set. The only reason that line existed before was because the original script was only supposed to work for the current domain, and it was using the rootDSE LDAP object to determine the naming context. Doh!

For the record, this is one reason why I hate having to modify inherited scripts.
 
think of modifying inherited scripts as a form of sudoko....or chinese torture!!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top