Announcement

Collapse
No announcement yet.

userAccountControl differences

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • userAccountControl differences

    What is the difference between:

    Code:
    objRecordset.Fields("userAccountControl")
    AND

    Code:
    objUser.Get("userAccountControl")
    ?

  • #2
    Re: userAccountControl differences

    About 8 characters

    In the first line of code, a recordset (i.e. a data table) has been created and populated, then one field is being worked with

    In the second, a piece of data is being fetched from something called objUser, which could be anything

    Without the rest of the code, it is not possible to answer the question
    Tom Jones
    MCT, MCSE (2000:Security & 2003), MCSA:Security & Messaging, MCDBA, MCDST, MCITP(EA, EMA, SA, EDA, ES, CS), MCTS, MCP, Sec+
    PhD, MSc, FIAP, MIITT
    IT Trainer / Consultant
    Ossian Ltd
    Scotland

    ** Remember to give credit where credit is due and leave reputation points where appropriate **

    Comment


    • #3
      Re: userAccountControl differences

      I think I figured out what I wanted to do. I asked that because I didn't know how to use the field to also bind to the object.

      Below is the script I'm working on...I don't know if it works. I'm sure it will need some statements for errors if the user does not belong to any groups, if its already hidden from the GAL, and already in the disabled users OU. All of which I'm not really sure how to do yet.



      Code:
      'AD Cleanup
      'This script is intended to clean up disabled users in AD.  Disabled accounts will be moved
      'into the Disabled Users OU, the account will be hidden from GAL if not already,
      'and it will be stripped of all groups
      
      Const ADS_UF_ACCOUNTDISABLE = 2
      Const ADS_SCOPE_SUBTREE = 2
      Const ADS_PROPERTY_DELETE = 4
      Const E_ADS_PROPERTY_NOT_FOUND  = &h8000500D
      
      Set objRootDSE = GetObject("LDAP://rootDSE")
      strDNSDomain = objRootDSE.Get("defaultNamingContext")
      
      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 AdsPath FROM 'LDAP://" & strDNSDomain & "' WHERE " _
          & "objectCategory='person' AND ObjectClass='user'"
      Set objRecordSet = objCommand.Execute
      
      objRecordSet.MoveFirst
      Do Until objRecordset.EOF
          intUAC = objRecordset.Fields("userAccountControl")
          If intUAC AND ADS_UF_ACCOUNTDISABLE Then
              strADsPath = objRecordSet.Fields("ADsPath").Value
      	Set objUser = GetObject(strADsPath)
      	arrMemberOf = objUser.GetEx("memberOf")
      	objUser.HideFromAddressBook = True
      	objUser.SetInfo
      	   For Each Group in arrMemberOf
          		Set objGroup = GetObject("LDAP://" & Group) 
          		objGroup.PutEx ADS_PROPERTY_DELETE, _
              	"member", Array(strADsPath)
          	   objGroup.SetInfo
      	   Next
      	Set objOU = GetObject("LDAP://OU=Disabled Users,DC=domain,DC=com")
          	intReturn = objOU.MoveHere(strADsPath, vbNullString)
          End If
          objRecordset.MoveNext
      Loop
       
      msgbox "All disabled accounts have been moved to the Disabled Users OU!"
      
      objConnection.Close
      WScript.Quit

      Comment


      • #4
        Re: userAccountControl differences

        In your script you are using this SQL query to search the entire AD domain:
        "SELECT AdsPath FROM 'LDAP://" & strDNSDomain & "' WHERE objectCategory='person' AND ObjectClass='user'"
        Where you SELECT only the attribute "AdsPath" of each found User object to be added to the collection of items for this ADODB.Recordset.
        Next, after the search when the record set is created, you entered this statement:
        intUAC = objRecordset.Fields("userAccountControl") but there is no item, in the collection you created, with the name userAccountControl.


        To create a record set not larger then needed, use for your case a LDAP query instead - where you be able to filter on Bitmask attributes so you don't have to connect to each User object that is in the Active Directory.

        Because the LDAP Matching Rule has the following syntax: attributename:ruleOID:=value, you don't use the ADS_UF_ACCOUNTDISABLE = &H2 here.
        When the userAccountControl attribute objectID rule "1.2.840.113556.1.4.803:" (the LDAP_MATCHING_RULE_BIT_AND rule) matches when AND'd with bit2 the user account is disabled. (http://support.microsoft.com/?kbid=269181)

        Code:
        ' The LDAP://RootDSE has an outstanding reference to the server.
        ' Therefore the multiple calls for objItem GetObject won't create extra binds.
        
        Set objRootDSE = GetObject("LDAP://rootDSE")
        strDNSDomain = objRootDSE.Get("defaultNamingContext")
        
        'Start the ADO connection
        Set objCommand = CreateObject("ADODB.Command")
        Set objConnection = CreateObject("ADODB.Connection")
        objConnection.Provider = "ADsDSOObject"
        objConnection.Open "Active Directory Provider"
        objCommand.ActiveConnection = objConnection
        
        'Set the ADO connection query strings
        StartNode = strDNSDomain
        SearchScope = "subtree"
        FilterString = "(&(objectCategory=person)(objectClass=user)" _
                     & "(userAccountControl:1.2.840.113556.1.4.803:=2))"
        Attributes = "adspath"
        
        'Create the LDAP-Query
        LDAPQuery = "<LDAP://" & StartNode & ">;" & FilterString & ";" _
                    & Attributes & ";" & SearchScope
        
        objCommand.CommandText = LDAPQuery
        objCommand.Properties("Page Size") = 100
        objCommand.Properties("Timeout") = 30
        objCommand.Properties("Cache Results") = False
        
        Set objRecordSet = objCommand.Execute
        
        If not objRecordSet.eof then 
          objRecordSet.MoveFirst
          moveToOU = "OU=disabled useraccounts,OU=test,DC=domain,DC=local" 'no spaces! around the seperator "," and the "=" signs!
          While Not objRecordset.EOF
            Set objItem = GetObject(objRecordSet.Fields("AdsPath").Value)
            strUserOU = Replace(objItem.parent, "LDAP://", "")
            If NOT LCase( moveToOU ) = LCase( strUserOU ) Then
        
               ResultsLst = _
                    ResultsLst & objItem.cn & vbTab _
                     & "[" & strUserOU & "]" & vbNewLine
            End If
            Set objItem = Nothing
            objRecordSet.MoveNext
          Wend
        End If
        
        
        wscript.echo ResultsLst
        
        wscript.quit
        - Learn how to create SQL queries to search Active Directory part 1
        - Learn how to create SQL queries to search Active Directory part 2
        - TechNet Webcast: on writing Active Directory search (ADSI-) scripts
        - Scripting Guide: Searching Active Directory
        - appropriate constants in the userAccountControl attribute


        note,
        The loop "For Each Group in arrMemberOf" in your script will not be sufficient see: http://www.rlmueller.net/MemberOf.htm
        To test for group membership see also: http://www.rlmueller.net/freecode1.htm


        \Rems

        This posting is provided "AS IS" with no warranties, and confers no rights.

        __________________

        ** Remember to give credit where credit's due **
        and leave Reputation Points for meaningful posts

        Comment


        • #5
          Re: userAccountControl differences

          Thanks. I modified the script you posted, and changed my for loop with the suggestions rlmueller had. I also added a statement for the address book. I think I have it right now...using the proper conditions for any errors that could come up. Here's what I got, changes are in red from your post:

          Code:
          ' The LDAP://RootDSE has an outstanding reference to the server.
          ' Therefore the multiple calls for objItem GetObject won't create extra binds.
          
          Const ADS_PROPERTY_DELETE = 4
          
          Set objRootDSE = GetObject("LDAP://rootDSE")
          strDNSDomain = objRootDSE.Get("defaultNamingContext")
          
          'Start the ADO connection
          Set objCommand = CreateObject("ADODB.Command")
          Set objConnection = CreateObject("ADODB.Connection")
          objConnection.Provider = "ADsDSOObject"
          objConnection.Open "Active Directory Provider"
          objCommand.ActiveConnection = objConnection
          
          'Set the ADO connection query strings
          StartNode = strDNSDomain
          SearchScope = "subtree"
          FilterString = "(&(objectCategory=person)(objectClass=user)" _
                       & "(userAccountControl:1.2.840.113556.1.4.803:=2))"
          Attributes = "adspath"
          
          'Create the LDAP-Query
          LDAPQuery = "<LDAP://" & StartNode & ">;" & FilterString & ";" _
                      & Attributes & ";" & SearchScope
          
          objCommand.CommandText = LDAPQuery
          objCommand.Properties("Page Size") = 100
          objCommand.Properties("Timeout") = 30
          objCommand.Properties("Cache Results") = False
          
          Set objRecordSet = objCommand.Execute
          
          If not objRecordSet.eof then 
            objRecordSet.MoveFirst
            moveToOU = "OU=Disabled Users,DC=domain,DC=com"
            While Not objRecordset.EOF
              Set objUser = GetObject(objRecordSet.Fields("AdsPath").Value)
                 If objUser.msExchHideFromAddressLists Then
                    'email is hidden, skip
                 Else
                    objUser.msExchHideFromAddressLists = True
                    objUser.SetInfo
                 End If
          
            	arrGroups = objUser.memberOf
               		If IsEmpty(arrGroups) Then
              		  'skip
               		ElseIf (TypeName(arrGroups) = "String") Then
          		  'skip
               		Else
          	   	    For Each strGroup In arrGroups
                         	      Set objGroup = GetObject("LDAP://" & strGroup) 
              		      objGroup.PutEx ADS_PROPERTY_DELETE, _
                  	      "member", Array(strGroup)
              	   	      objGroup.SetInfo
              	   	    Next
               		End If
          
               strUserOU = Replace(objUser.parent, "LDAP://", "")
               If NOT LCase( moveToOU ) = LCase( strUserOU ) Then
               End If
          
              Set objUser = Nothing
              objRecordSet.MoveNext
            Wend
          End If
          
          msgbox "Done!"
          WScript.Quit

          Comment


          • #6
            Re: userAccountControl differences

            I found this article to be pretty good explaining bitwise filtering, as I was looking for some more information on it:

            http://codeidol.com/active-directory...itwise-Filter/

            Comment


            • #7
              Re: userAccountControl differences

              I can't seem to get "removing the users from all groups" to work. I receive the error at "objGroup.SetInfo"

              Error: The server is unwilling the process the request.

              lol I thought that was funny...maybe I will "will" it next time.

              Code:
              	arrGroups = objUser.GetEx("memberOf")
              	If (Err.Number <> 0) Then
                  		On Error GoTo 0
                  		'skip, member of no groups
              	Else
                  		On Error GoTo 0
                  		For Each strGroup In arrGroups
                           	      	Set objGroup = GetObject("LDAP://" & strGroup) 
                  		      	objGroup.PutEx ADS_PROPERTY_DELETE, _
                      	      	"member", Array(strGroup)
                  	   	      	objGroup.SetInfo
                  		Next
              	End If
              EDIT **

              Fixed with this piece of code:

              http://groups.google.com/group/micro...a35ee?lnk=raot

              Code:
              	' Create dictionary object of group objects. 
              	Set objGroupList = CreateObject("Scripting.Dictionary")
              	objGroupList.CompareMode = vbTextCompare
              
                  	    On Error Resume Next
                  	    arrGroups = objUser.GetEx("memberOf")
                  	    If (Err.Number = 0) Then
                              On Error GoTo 0
                              For Each strGroup In arrGroups
                          	     ' Check if group already bound.
                          	     If (objGroupList.Exists(strGroup) = False) Then
                                   ' Add group object to the dictionary object.
                                   Set objGroupList(strGroup) = GetObject("LDAP://" & strGroup)
                          	     End If
                          	     ' Remove user from the group.
                                   objGroupList(strGroup).Remove(objUser.AdsPath)
                              Next
                  	    End If
                  	    On Error GoTo 0
              Last edited by ekrengel; 23rd October 2008, 19:03.

              Comment


              • #8
                Re: userAccountControl differences

                FYI,
                Here are some sample pages of the 'Active Directory Cookbook 2nd edition' by Robbie Allen, Laura E. Hunter.

                @books.google.com
                Recipe;
                6.18. Viewing a User's Group Membership
                6.19. Removing All Group Memberships from a User


                \Rems

                EDIT
                The preview pages were changed.
                just before sendng this post I was able to read both chapters 6.18, 6.19 and also 6.20, now I can read only 6.18 (the google link I found then was a bit differend though).
                Last edited by Rems; 24th October 2008, 23:04.

                This posting is provided "AS IS" with no warranties, and confers no rights.

                __________________

                ** Remember to give credit where credit's due **
                and leave Reputation Points for meaningful posts

                Comment

                Working...
                X