asp-classicactive-directoryadodbldap-queryscripting.dictionary

ASP: Reading Scripting.Dictionary with ADODB.Command Result


I'm trying to query the userAccountControl from Active Directory and match it against a dictionary that I've set up in my script.

First of all I set up my dictionary object and fill it:

dim uac
Set uac=Server.CreateObject("Scripting.Dictionary")
uac.add "512", "Enabled Account"
uac.add "514", "Disabled Account"
uac.add "544", "Enabled, Password Not Required"
uac.add "546", "Disabled, Password Not Required"
uac.add "66048", "Enabled, Password Doesn't Expire"
uac.add "66050", "Disabled, Password Doesn't Expire"
uac.add "66080", "Enabled, Password Doesn't Expire & Not Required"
uac.add "66082", "Disabled, Password Doesn't Expire & Not Required"
uac.add "262656", "Enabled, Smartcard Required"
uac.add "262658", "Disabled, Smartcard Required"
uac.add "262688", "Enabled, Smartcard Required, Password Not Required"
uac.add "262690", "Disabled, Smartcard Required, Password Not Required"
uac.add "328192", "Enabled, Smartcard Required, Password Doesn't Expire"
uac.add "328194", "Disabled, Smartcard Required, Password Doesn't Expire"
uac.add "328224", "Enabled, Smartcard Required, Password Doesn't Expire & Not Required"
uac.add "328226", "Disabled, Smartcard Required, Password Doesn't Expire & Not Required"

Then I connect to my Active Directory to query it:

Set objDomain = GetObject ("GC://RootDSE")
objADsPath = objDomain.Get("defaultNamingContext")
Set objDomain = Nothing
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.provider ="ADsDSOObject"
objConn.Properties("User ID") = "domain\administrator"
objConn.Properties("Password") = "password"
objConn.Properties("Encrypt Password") = True
objConn.open "Active Directory Provider"
Set objCom = CreateObject("ADODB.Command")
Set objCom.ActiveConnection = objConn
objCom.CommandText ="select name,userAccountControl FROM 'GC://"+objADsPath+"' where sAMAccountname='*' and objectCategory='user' and objectCategory='person' ORDER by sAMAccountname"

Then I loop through the results like so:

Set objRS = objCom.Execute
Do While Not objRS.EOF Or objRS.BOF
Response.Write objRS("name")
set uacResult = objRS("userAccountControl")
objRS.MoveNext
Response.Flush
Loop
objRS.Close
objConn.Close
Set objRS = Nothing
Set objConn = Nothing
Set objCom = Nothing
Set objADsPath = Nothing
Set objDomain = Nothing

This all works absolutely fine. What I want to do now is to query the uac dictionary that I created using the result from objRS("userAccountControl"). When I try to do that, it returns a blank value?

set uacResult = objRS("userAccountControl")
Response.Write uac.Item(uacResult)
Response.Write " (" & uacResult & ")"

I'm stumped - is the objRS value returned as a string?? It works if I do Response.Write uac.Item("512") but not if I do Response.Write uac.Item(uacResult)

Any ideas?


Solution

  • You've already found a valid solution, but I want to explain what's going on here.

    The keys of a Dictionary object can be of any type except arrays (see the docs). Since you used the Set statement, the variable uacResult is an object reference (more on that later). When you call the Item method on the Dictionary, it is actually looking for key that matches the object reference, instead of searching for the string as you expected. CStr() corrects that by explicitly converting the object reference to a string.

    Since you used the Set keyword in its assignment, uacResult ends up containing a reference to a Field object, since the default property of the Recordset object is the Fields collection. When you call CStr(uacResult), this is converting the object to a string by calling the default property of the Field object, which is the Value property. You could achieve the same effect in a few different ways:

    ' method 1 - from accepted answer (https://stackoverflow.com/a/17786308/249624)
    set uacResult = objRS("userAccountControl")
    Response.Write uac.Item(CStr(uacResult))
    
    ' method 2 - explicitly using the Value property
    set uacResult = objRS("userAccountControl")
    Response.Write uac.Item(uacResult.Value)
    
    ' method 3 - make uacResult a string instead of a Field object
    uacResult = objRS("userAccountControl")
    Response.Write uac.Item(uacResult)
    
    ' method 4 - same as method 3, but explicitly use the Value property
    uacResult = objRS("userAccountControl").Value
    Response.Write uac.Item(uacResult)