Announcement

Collapse
No announcement yet.

Unlock All AD Accounts (WINNT vs LDAP)

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

  • Unlock All AD Accounts (WINNT vs LDAP)

    So I am trying to figure out which one of these scripts would be better for this purpose...I am guessing LDAP because it is using a bitwise filter, and won't have go through all the accounts in AD...but I figured I'd get another opinion.

    I was using WINNT for a previous post I had to force a password change...but I was also searching for more than 1 ads property...unlike here where I am only searching for locked accounts.

    WINNT:

    Code:
    Const ADS_SCOPE_SUBTREE = 2
    Const ADS_UF_LOCKOUT = &H10
    
    Set objWinNTSysInfo = CreateObject("WinNTSystemInfo")
    strNetBIOSDomain = objWinNTSysInfo.DomainName
    
    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,sAMAccountName FROM 'LDAP://" & strDNSDomain _
        & "' WHERE objectCategory='person' AND ObjectClass='user'"
    
    Set objRecordSet = objCommand.Execute
    
    If not objRecordSet.EOF Then 
      objRecordSet.MoveFirst
      Do Until objRecordSet.EOF
    
         Set objUser = GetObject("WinNT://" & strNetBIOSDomain & "/" _
           & objRecordSet.Fields("sAMAccountName").Value & ",User")
    
          lngFlag = objUser.Get("userFlags")  'instead of "userAccountControl"
          		If ((lngFlag And ADS_UF_LOCKOUT) <> 0) Then
              		blnLocked = False
          		Else
              		blnLocked = True
          		End If
    
          		If (blnLocked = True) then
              		objUser.Put "IsAccountLocked", CLng(0)  'unlock account
    	  		'objUser.IsAccountLocked = False
              		objUser.SetInfo
          		End If
         Set objUser = Nothing
      objRecordSet.MoveNext
      Loop
    End If
    
    objRecordset.Close
    objConnection.Close
    Set objRootDSE = Nothing
    Set objConnection = Nothing
    Set objRecordSet = Nothing
    
    msgbox "All users are now unlocked!"
    
    WScript.Quit(0)

    LDAP:

    Code:
    Const ADS_SCOPE_SUBTREE = 2
    Const ADS_UF_LOCKOUT = &H10
    
    Set objRootDSE = GetObject("LDAP://rootDSE")
    strDNSDomain = objRootDSE.Get("defaultNamingContext")
    
    Set objCommand = CreateObject("ADODB.Command")
    Set objConnection = CreateObject("ADODB.Connection")
    objConnection.Provider = "ADsDSOObject"
    objConnection.Open "Active Directory Provider"
    objCommand.ActiveConnection = objConnection
    
    StartNode = strDNSDomain
    SearchScope = "subtree"
    
    Filterstring = "(&(objectCategory=Person)(objectClass=User)" _
    		"(userAccountControl:1.2.840.113556.1.4.803:=16))" 'find locked out accounts (bitwise)
    
    'Filterstring = "(&(objectCategory=person)(objectClass=user)(lockoutTime>=1))"   'not sure which is better
    
    Attributes = "adspath"
    
    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
      	    While Not objRecordset.EOF
        		Set objuser = GetObject(objRecordSet.Fields("AdsPath").Value)
    		intUAC = objUser.Get("userAccountControl")
          			If ((intUAC And ADS_UF_LOCKOUT) <> 0) Then
              			blnLocked = False
          			Else
              			blnLocked = True
          			End If
    
          			If (blnLocked = True) then
              			objUser.Put "IsAccountLocked", CLng(0)  'unlock account
    	  			'objUser.IsAccountLocked = False
              			objUser.SetInfo
          			End If
        	  	objRecordSet.MoveNext
      	    Wend
     	End If
    
    objRecordset.Close
    objConnection.Close
    Set objRootDSE = Nothing
    Set objConnection = Nothing
    Set objRecordSet = Nothing
    
    msgbox "All users are now unlocked!"
    
    WScript.Quit(0)

  • #2
    Re: Unlock All AD Accounts (WINNT vs LDAP)

    Actually...looking further at my LDAP example...I probably wouldn't need the if/then statements, would I? The bitwise filter is already telling me which accounts are locked out, and will only chose them...I can probably just change it to:

    Code:
    	If NOT objRecordSet.eof Then
      	  objRecordSet.MoveFirst
      	    While Not objRecordset.EOF
        		Set objuser = GetObject(objRecordSet.Fields("AdsPath").Value)
    		intUAC = objUser.Get("userAccountControl")
              			objUser.Put "IsAccountLocked", CLng(0)  'unlock account
    	  			'objUser.IsAccountLocked = False
              			objUser.SetInfo
          			End If
        	  	objRecordSet.MoveNext
      	    Wend
     	End If

    Comment


    • #3
      Re: Unlock All AD Accounts (WINNT vs LDAP)

      After some testing...this seems to be the best way for me...I was getting an error with the bitwise filter for some reason:

      Code:
      Const ADS_SCOPE_SUBTREE = 2
      Const ADS_UF_LOCKOUT = &H10
      
      Set objRootDSE = GetObject("LDAP://rootDSE")
      strDNSDomain = objRootDSE.Get("defaultNamingContext")
      
      Set objCommand = CreateObject("ADODB.Command")
      Set objConnection = CreateObject("ADODB.Connection")
      objConnection.Provider = "ADsDSOObject"
      objConnection.Open "Active Directory Provider"
      objCommand.ActiveConnection = objConnection
      
      StartNode = strDNSDomain
      SearchScope = "subtree"
      
      'Filterstring = "(&(objectCategory=Person)(objectClass=User)" _
      		 '& "(userAccountControl:1.2.840.113556.1.4.803:=16))" 'find locked out accounts (bitwise)
      
      Filterstring = "(&(objectCategory=person)(objectClass=user)(lockoutTime>=1))"   'not sure which is better
      
      Attributes = "adspath"
      
      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
        	    While Not objRecordset.EOF
          		Set objuser = GetObject(objRecordSet.Fields("AdsPath").Value)
      	  		objUser.IsAccountLocked = False
                		objUser.SetInfo
          	  	objRecordSet.MoveNext
        	    Wend
       	End If
      
      objRecordset.Close
      objConnection.Close
      Set objRootDSE = Nothing
      Set objConnection = Nothing
      Set objRecordSet = Nothing
      
      msgbox "All users are now unlocked!"
      
      WScript.Quit(0)

      Comment


      • #4
        Re: Unlock All AD Accounts (WINNT vs LDAP)

        An update on this...I made some changes using rlmullers FindLockedOutUsers . I also added an array to query more than 1 DC...sometimes replication can be really slow and you need to connect to more than 1 DC if your are in a hurry and don't have time to wait for replication. This will give you the option to do that.

        Code:
        ' Set list of DC's
        arrDCs = Array("DC01", "DC02", "DC03")
        
        ' Obtain local Time Zone bias from local machine registry.
        Set objShell = CreateObject("Wscript.Shell")
        lngBiasKey = objShell.RegRead("HKLM\System\CurrentControlSet\Control\" _
            & "TimeZoneInformation\ActiveTimeBias")
        If (UCase(TypeName(lngBiasKey)) = "LONG") Then
            lngBias = lngBiasKey
        ElseIf (UCase(TypeName(lngBiasKey)) = "VARIANT()") Then
            lngBias = 0
            For k = 0 To UBound(lngBiasKey)
                lngBias = lngBias + (lngBiasKey(k) * 256^k)
            Next
        End If
        Set objShell = Nothing
        
        ' Retrieve DNS domain name.
        Set objRootDSE = GetObject("LDAP://rootDSE")
        strDNSDomain = objRootDSE.Get("defaultNamingContext")
        
        ' Retrieve domain lockout duration policy.
        Set objDomain = GetObject("LDAP://" & strDNSDomain)
        Set objDuration = objDomain.lockoutDuration
        lngHigh = objDuration.HighPart
        lngLow = objDuration.LowPart
        If (lngHigh = 0 And lngLow = 0) Then
              ' There is no domain lockout duration policy.
              ' Locked out accounts remain locked out until reset.
              ' Any user with value of lockoutTime greater than 0
              ' is locked out.
              str64Bit = "1"
        Else
            ' Account for error in IADsLargeInteger property methods.
            If (lngLow < 0) Then
                  lngHigh = lngHigh + 1
            End If
              ' Convert to minutes.
              lngDuration = lngHigh * (2^32) + lngLow
              lngDuration = -lngDuration/(60 * 10000000)
        
              ' Determine critical time in the past. Any accounts
              ' locked out after this time will still be locked out,
              ' unless the account has been reset (in which case the
              ' value of the lockoutTime attribute will be 0).
              ' Any accounts locked out before this time will no
              ' longer be locked out.
              ' Trap error if lockoutDuration -1 (2^63 - 1).
            On Error Resume Next
            dtmLockout = DateAdd("n", -lngDuration, Now())
            If (Err.Number <> 0) Then
                On Error GoTo 0
                  ' There is no domain lockout duration policy.
                  ' Locked out accounts remain locked out until reset.
                  ' Any user with value of lockoutTime greater than 0
                  ' is locked out.
                  str64Bit = "1"
            Else
                On Error GoTo 0
                ' Convert to UTC.
                dtmLockout = DateAdd("n", lngBias, dtmLockout)
        
                ' Find number of seconds since 1/1/1601.
                lngSeconds = DateDiff("s", #1/1/1601#, dtmLockout)
        
                  ' Convert to 100-nanosecond intervals. This is the
                  ' equivalent Integer8 value (for this time zone).
                  str64Bit = CStr(lngSeconds) & "0000000"
            End If
        End If
        Set objDuration = Nothing
        Set objDomain = Nothing
        
         ' Start querying arrDCs
         For each strDC in arrDCs
        
          	' Use ADO to search Active Directory.
          	Set objCommand = CreateObject("ADODB.Command")
          	Set objConnection = CreateObject("ADODB.Connection")
          	objConnection.Provider = "ADsDSOObject"
          	objConnection.Open "Active Directory Provider"
          	objCommand.ActiveConnection = objConnection
        
          	' Search the DC in arrDCs
          	StartNode = "<LDAP://" & strDC & "/" & strDNSDomain & ">"
          	SearchScope = "subtree"
        
          	' Filter on all user objects that are still locked out using lockout duration policy
          	Filterstring = "(&(objectCategory=person)(objectClass=user)(lockoutTime>=" & str64Bit & "))"
        
          	Attributes = "adspath"
        
         	' Construct the LDAP syntax query
          	LDAPQuery = StartNode & ";" & FilterString & ";" _
                    		& Attributes & ";" & SearchScope
        
          	' Run the query
          	objCommand.CommandText = LDAPQuery
          	objCommand.Properties("Page Size") = 100
          	objCommand.Properties("Timeout") = 30
          	objCommand.Properties("Cache Results") = False
          	Set objRecordSet = objCommand.Execute
          	If (Err.Number <> 0) Then
                	On Error GoTo 0
                	Wscript.Echo "Domain Controller not available: " & strDC
          	Else
        		' Enumerate all locked out users, and unlock
        		If NOT objRecordSet.eof Then
          	  	  objRecordSet.MoveFirst
          	    	     While Not objRecordset.EOF
            			Set objuser = GetObject(objRecordSet.Fields("AdsPath").Value)
        	  			objUser.IsAccountLocked = False
                  			objUser.SetInfo
            	  		objRecordSet.MoveNext
          	    	     Wend
         		End If
          	End If
        
          	' Clean up
          	objRecordset.Close
          	objConnection.Close
          	Set objConnection = Nothing
          	Set objRecordSet = Nothing
        
         ' Go to the next DC
         Next
        
        Set objRootDSE = Nothing
        
        msgbox "Done!"
        
        WScript.Quit(0)

        Comment

        Working...
        X