Automate Active Directory tasks with scripts

Automate Active Directory tasks with scripts

Over the last month or so, I have been working to automate user account maintenance in Active Directory. In addition to creating and deleting users, I wanted to automate the following tasks:

  • determine if account is enabled or disabled
  • retrieve user information such as first name, last name, phone number, account creation date, etc.
  • find out when a user last logged in
  • find out when a user's password was last set and when it will expire
  • determine if an account is locked out and if it is, unlock it
  • check to see if a user's account is set to expire and when
  • set a user's account to expire or to never expire
  • list all groups in Active Directory
  • list all groups that a user is a member of
  • add a user to a specific group

While coming up with methods to do each of the tasks mentioned above, I created a 'master' script that referenced each task. I hope you find this script useful. To use it, simply copy the following into a text file using a text editor (I recommend Notepad++), name the file 'ADScripting.vbs' (or something similar), modify the AD specific lines to indicate a specific user, OU and group in your environment, go to a command line, change to the directory that contains the script and type: cscript ADScripting.vbs > UserInfo.txt

'***** Initial Setup *****
Dim StrOU, strUser, strDNSDomain, objCommand
Dim objRootLDAP, objGroup, objUser, strQuery
Dim strDN, objManager, strDateCreated

' Use ADO to get Active Directory information
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection

'Get Time Zone Information from local computer
dtmLatestLogon = #1/1/1601#
dtmWhenCreated = #1/1/1601#

strComputer = "."
Set objWMIService = GetObject("winmgmts:\" & strComputer & "rootcimv2")
Set colTimeZones = objWMIService.ExecQuery("Select * From
Win32_TimeZone")
For Each objTimeZone in colTimeZones
    intTimeZoneBias = objTimeZone.Bias
    intDaylightBias = objTimeZone.DaylightBias
Next

'***** Define User and Group Information *****
'##### -- Change These Values -- #####
strUser = "CN=TestUser," ' Name of existing AD user
strOU = "OU=Test," ' Name of OU that user is in
strGroup = "CN=Test Group," ' Name of existing group to add user to
'##### -- End Section -- #####

'***** Bind to AD and get LDAP name
set objRootLDAP = GetObject("LDAP://RootDSE")
strDNSDomain = objRootLDAP.Get("DefaultNamingContext")

'***** Retrieve User Object for specified user *****
set objUser = GetObject ("LDAP://" & strUser & strOU & strDNSDomain)


'***** Check if account is Enabled or Disabled *****

If objUser.AccountDisabled=True Then
Wscript.Echo objUser.DisplayName & "'s account is DISABLED."
Else
Wscript.Echo objUser.DisplayName & "'s account is NOT DISABLED."
End If
'Wscript.Quit

'***** Get User Account Info *****
Wscript.Echo "First Name: " & objUser.Name
Wscript.Echo "Last Name: " & objUser.sn
Wscript.Echo "Title: " & objUser.Title
Wscript.Echo "SAMAccountName: " & objUser.SAMAccountName
Wscript.Echo "Display Name: " & objUser.DisplayName
Wscript.Echo "Distinguished Name: " & objUser.DistinguishedName
Wscript.Echo "Email Address: " & objUser.mail
Wscript.Echo "Telephone Number: " & objUser.TelephoneNumber
Wscript.Echo "Mobile Phone: " & objUser.mobile
Wscript.Echo "Logon Count: " & objUser.LogonCount
Wscript.Echo "Manager: " & objUser.Manager
   'Account Creation Date
dtmWhenCreated = objUser.WhenCreated
dtmWhenCreated = DateAdd("n", intTimeZoneBias, dtmWhenCreated)
dtmWhenCreated = DateAdd("n", -intDaylightBias, dtmWhenCreated)
Wscript.Echo "Account Created: " & dtmWhenCreated
'Wscript.Quit

'***** Get Last Logon Information for User *****'
Wscript.Echo "Retrieving last logon information for " & strUser & "...."

Const ADS_SCOPE_SUBTREE = 2

Set objRootDSE = GetObject("LDAP://RootDSE")
strConfigurationNC = objRootDSE.Get("configurationNamingContext")

objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE

objCommand.CommandText = _
    "SELECT ADsPath FROM 'LDAP://" & strConfigurationNC & "' WHERE
objectClass='nTDSDSA'" 
Set objRecordSet = objCommand.Execute

objRecordSet.MoveFirst

Do Until objRecordSet.EOF
    Set objParent =
GetObject(GetObject(objRecordset.Fields("ADsPath")).Parent)
    strDCName = objParent.dnsHostName


    Set objLastLogon = objUser.Get("lastLogon")

    intLastLogonTime = objLastLogon.HighPart * (2^32) +
objLastLogon.LowPart
    intLastLogonTime = intLastLogonTime / (60 * 10000000)
    intLastLogonTime = intLastLogonTime / 1440

    dtmLastLogon = intLastLogonTime + #1/1/1601#
    dtmLastLogon = DateAdd("n", intTimeZoneBias, dtmLastLogon)
    dtmLastLogon = DateAdd("n", -intDaylightBias, dtmLastLogon)

    If dtmLastLogon >

    Requires Free Membership to View

    By submitting your registration information to SearchWindowsServer.com you agree to receive email communications from TechTarget and TechTarget partners. We encourage you to read our Privacy Policy which contains important disclosures about how we collect and use your registration and other information. If you reside outside of the United States, by submitting this registration information you consent to having your personal data transferred to and processed in the United States. Your use of SearchWindowsServer.com is governed by our Terms of Use. You may contact us at webmaster@TechTarget.com.

dtmLatestLogon Then dtmLatestLogon = dtmLastLogon End If objRecordSet.MoveNext Loop If dtmLatestLogon = "1/1/1601" Then wscript.Echo "Logon information not found for user: " & objUser.DisplayName & " Verify user exists and that OU is correct." Else Wscript.Echo "Last logon for " & objUser.DisplayName & ": " & dtmLatestLogon msgBox "Last logon for " & objUser.DisplayName & ": " & dtmLatestLogon End If 'Wscript.Quit '***** Check for Password Last Set and Password Expiration ***** Const ADS_UF_DONT_EXPIRE_PASSWD = &h10000 Const E_ADS_PROPERTY_NOT_FOUND = &h8000500D Const ONE_HUNDRED_NANOSECOND = .000000100 Const SECONDS_IN_DAY = 86400 intUserAccountControl = objUser.Get("userAccountControl") If intUserAccountControl And ADS_UF_DONT_EXPIRE_PASSWD Then ' LINE 11 WScript.Echo "The password does not expire." Else dtmValue = objUser.PasswordLastChanged If Err.Number = E_ADS_PROPERTY_NOT_FOUND Then ' LINE 16 WScript.Echo "The password has never been set." Else intTimeInterval = Int(Now - dtmValue) WScript.Echo "The password was last set on " & _ DateValue(dtmValue) & " at " & TimeValue(dtmValue) & vbCrLf & _ "The difference between when the password was last" & vbCrLf & _ "set and today is " & intTimeInterval & " days" End If Set objDomain = GetObject("LDAP://" & strDNSDomain) Set objMaxPwdAge = objDomain.Get("maxPwdAge") If objMaxPwdAge.LowPart = 0 Then WScript.Echo "The Maximum Password Age is set to 0 in the " & _ "domain. Therefore, the password does not expire." Else dblMaxPwdNano = _ Abs(objMaxPwdAge.HighPart * 2^32 + objMaxPwdAge.LowPart) dblMaxPwdSecs = dblMaxPwdNano * ONE_HUNDRED_NANOSECOND ' LINE 37 dblMaxPwdDays = Int(dblMaxPwdSecs / SECONDS_IN_DAY) ' LINE 38 WScript.Echo "Maximum password age is " & dblMaxPwdDays & " days" If intTimeInterval >= dblMaxPwdDays Then WScript.Echo "The password has expired." Else WScript.Echo "The password will expire on " & _ DateValue(dtmValue + dblMaxPwdDays) & " (" & _ Int((dtmValue + dblMaxPwdDays) - Now) & " days from today)." End If End If End If 'Wscript.Quit '***** Check to see if Account is Locked Out **** If objUser.IsAccountLocked = True Then WScript.Echo objUser.DisplayName & "'s account is locked out." Else WScript.Echo objUser.DisplayName & "'s account is NOT locked out." End If '***** Unlock the account ***** '##### -- Uncomment following lines to unlock account -- ##### 'Wscript.Echo "Unlocking " & objUser.DisplayName & "'s account...." 'objUser.IsAccountLocked=False 'objUser.SetInfo '##### -- End Section -- ##### 'Wscript.Quit '***** Check for Account Expiration ***** Wscript.Echo "Checking account expiration for " & objUser.DisplayName & "...." On Error Resume Next dtmAccountExpiration = objUser.AccountExpirationDate If Err.Number = -2147467259 OR dtmAccountExpiration = #1/1/1970# Then WScript.Echo "This account has no expiration date." Else WScript.Echo "Account expiration date: " & objUser.AccountExpirationDate End If 'Wscript.Quit '***** Set Account Expiration Date ***** '##### -- Uncomment the following lines to set account expiration -- ##### 'Wscript.Echo "Setting account expiration to 12/11/2020" 'objUser.AccountExpirationDate=#12/11/2020# 'objUser.SetInfo 'Wscript.Echo "Account Expiration is: " & objUser.AccountExpirationDate '##### -- End Section -- ##### 'Wscript.Quit '***** Set Account to never Expire ***** '##### -- Uncomment the following lines to remove account expiration -- ##### 'Wscript.Echo "Removing Account Expiration..." 'objUser.AccountExpires=-1 'objUser.SetInfo '##### -- End Section -- ##### 'Wscript.Quit '***** List All Groups in Active Directory ***** Wscript.Echo "Listing ALL AD Groups..." strQuery = ";(objectClass=group);distinguishedName;subtree" objCommand.CommandText = strQuery objCommand.Properties("Page Size") = 100 objCommand.Properties("Timeout") = 30 objCommand.Properties("Cache Results") = False Set objRecordSet = objCommand.Execute If objRecordSet.EOF Then Wscript.Echo "No groups found" objConnection.Close End If Do Until objRecordSet.EOF strDN = objRecordSet.Fields("distinguishedName") set objGroup = GetObject("LDAP://" & strDN) Wscript.Echo objGroup.SAMAccountName & " (" & objGroup.DistinguishedName & ")" objRecordSet.MoveNext Loop 'Wscript.Quit '***** List Groups that the user is a MemberOf ***** Dim UserGroupSid() objUser.GetInfoEx Array("TokenGroups"), 0 UserGroups = objUser.Get("TokenGroups") ReDim UserGroupSid(UBound(UserGroups)) Wscript.Echo objUser.DisplayName & " is a member of the following AD Groups..." For j = 0 To UBound(UserGroups) UserGroupSid(j) = OctetToHexStr(UserGroups(j)) Set oGroup = GetObject("LDAP://") Wscript.Echo oGroup.sAMAccountName 'Lists group names using friendly names Next Function OctetToHexStr(bOctet) Dim k OctetToHexStr = "" For k = 1 To Lenb(bOctet) OctetToHexStr = OctetToHexStr _ & Right("0" & Hex(Ascb(Midb(bOctet, k, 1))), 2) Next End Function 'Wscript.Quit '***** Add User to a Group ***** '##### -- Uncomment the following lines to add user to group defined above -- ##### 'Wscript.Echo "Adding " & objUser.DisplayName & " to the " & strGroup & " group..." 'set objGroup = GetObject("LDAP://" & strGroup & strOU & strDNSDomain) 'objGroup.add(objUser.ADSPath) '##### -- End Section-- #####

Please let us know how useful you find this tip by rating it below! If you have a useful Windows tip, timesaver or workaround to share, submit it to our tip contest and you could win a prize!

This was first published in September 2006

Join the conversationComment

Share
Comments

    Results

    Contribute to the conversation

    All fields are required. Comments will appear at the bottom of the article.

    Disclaimer: Our Tips Exchange is a forum for you to share technical advice and expertise with your peers and to learn from other enterprise IT professionals. TechTarget provides the infrastructure to facilitate this sharing of information. However, we cannot guarantee the accuracy or validity of the material submitted. You agree that your use of the Ask The Expert services and your reliance on any questions, answers, information or other materials received through this Web site is at your own risk.