ADSI Exposed Properties that Cannot Be Manipulated Using Standard GUI Tools

   

ADSI Exposed Properties that Cannot Be Manipulated Using Standard GUI Tools

There are several properties that were not directly implemented into the standard Windows NT GUI tools that can be accessed using ADSI. Many of these properties are used as internal counters, fail to yield useful information, or can be accessed by manipulating the properties of the parent container, but are interesting to examine nonetheless.

Querying the BadLoginCount Property Using Visual Basic

Using the BadLoginCount property of the IADsUser interface, you can examine the counter used to determine the number of bad logins encountered for any given user account on a specific domain controller or machine.

The system uses this counter to determine whether the account lockout threshold has been met for an account. Although there is little or no need in most environments to query this value, ADSI still exposes this read-only property for you to query upon. Use the following Visual Basic code to view the number of incorrect login attempts for a given user account:

 On Error Resume Next Dim User as IADsUser Dim UserName as String Dim UserDomain as String UserDomain = "  Target_User_Domain  " UserName = "  Target_User_Name  " Set User = GetObject("WinNT://" & UserDomain & "/" & UserName & ",user") Dim RetVal as Integer  RetVal = User.BadLoginCount Debug.Print RetVal 

Note

If this property does not contain an integer, an error will be returned by ADSI claiming that the property could not be found in the property cache. Once again, you can use VB's On Error Resume Next error handler to avoid fatal termination of your application .


Querying LastLogin for a Given Machine Using Visual Basic

This property can be very useful when querying a local machine account database, but can yield unexpected results when binding to domain controllers in large domains containing multiple Backup Domain Controllers (BDCs). This seemingly inaccurate data is derived from the fact that a user can be authenticated on any BDC in the Windows NT domain authentication architecture. Use the following code to determine a user's last login on a member server or workstation:

 On Error Resume Next Dim User as IADsUser Dim UserName as String Dim UserDomain as String UserDomain = "  Target_User_Domain  " UserName = "  Target_User_Name  " Set User = GetObject("WinNT://" & UserDomain & "/" & UserName & ",user") Dim RetVal as Date  RetVal = User.LastLogin Debug.Print RetVal 

Note

If the user has never logged into the domain (or on the domain controller servicing the request), ADSI will return an error, thus terminating the application or script .


Querying LastLogoff for a Given Machine Using Visual Basic

In addition to obtaining the date of a user's last login, you can also determine the date of a user's last logoff . Once again, this may not provide the expected result when used against a domain controller in enterprises with more than one domain controller.

Using similar Visual Basic code to what we used for LastLogin , you can also query a user's last logoff event, as follows :

 Dim User as IADsUser Dim UserName as String Dim UserDomain as String UserDomain = "  Target_User_Domain  " UserName = "  Target_User_Name  " Set User = GetObject("WinNT://" & UserDomain & "/" & UserName & ",user") Dim RetVal as Date  RetVal = User.LastLogoff Debug.Print RetVal 

Querying PasswordMinimumLength for a User Account Using Visual Basic

To query the minimum password length for an individual user account, simply display the value of the PasswordMinimumLength property, as follows:

 Dim User as IADsUser Dim UserName as String Dim UserDomain as String UserDomain = "  Target_User_Domain  " UserName = "  Target_User_Name  " Set User = GetObject("WinNT://" & UserDomain & "/" & UserName & ",user") Dim RetVal as Integer RetVal = User.PasswordMinimumLength Debug.Print RetVal 

Note

Although it may be desirable to set individual minimum lengths for user accounts, this is not permitted using the Windows NT service provider. Using the Windows NT provider, you can query only the minimum password length field

This value is actually derived from the parent container (in this case, the domain) and will violate the DS schema rules if you attempt to change this property on individual user accounts .

This property can be useful for eliminating a second binding to the domain container if you need to query the minimum password length during the course of manipulating a user object .


Querying PasswordRequired for a User Account Using Visual Basic

Unlike the PasswordMinimumLength property, you can selectively require a password for individual user accounts without violating the DS schema rules. This can be useful for overriding the domain account policy for this setting to create a guest or generic login.

To determine whether a password is required for an existing user account, use the following Visual Basic code:

 Dim User as IADsUser Dim UserName as String Dim UserDomain as String UserDomain = "  Target_User_Domain  " UserName = "  Target_User_Name  " Set User = GetObject("WinNT://" & UserDomain & "/" & UserName & ",user") Dim RetVal as Boolean RetVal = User.PasswordRequired Debug.Print RetVal 

Setting PasswordRequired for a User Account Using Visual Basic

Use the following Visual Basic code to permit an individual user account to use a blank password:

 Dim User as IADsUser Dim UserName as String Dim UserDomain as String UserDomain = "  Target_User_Domain  " UserName = "  Target_User_Name  " Set User = GetObject("WinNT://" & UserDomain & "/" & UserName & ",user") Dim NewValue as Boolean NewValue =  True  User.PasswordRequired = NewValue User.SetInfo 

Querying User Password Age Using Visual Basic

By default, Windows NT does not allow an administrator to specify a different maximum password age for privileged accounts. Programmatically, however, you can write a service or application that enumerates the members of a group, examines the password age for each user contained in the group , and then sets the PasswordExpired bit for each account with a password age longer than a specified value.

Although some security organizations allow 60- to 90-day password ages (or more) for business users, this exposes the organization to greater risk from the use of password-cracking utilities on administrative accounts.

Using the following code, you can effortlessly enforce a 30-day maximum password age for all users in the "Domain Admins" group:

 Dim Group As IADsGroup Dim GroupName As String Dim GroupDomain As String GroupDomain = "  Target_Domain  " GroupName = "Domain Admins" Set Group = GetObject("WinNT://" & GroupDomain & "/" & GroupName & ",group") Dim Member As Variant Dim User As IADsUser For Each Member In Group.Members      Set User = GetObject("WinNT://" & GroupDomain & "/" & Member.Name & ",user")      If User.Get("PasswordAge") > 2592000 Then           If (User.Get("UserFlags") And &H10000) = 0 Then                Debug.Print Member.Name                'If you wish to perform a query only, comment out the following two lines:                User.Put "PasswordExpired", CLng(1)                User.SetInfo           End If      End If Next 

Note

As with most values in the SAM, the time unit used for the PasswordAge custom property is in seconds .


Querying Machine Password Age

Chapter 3 examined the creation of a computer account. This process involved multiple bindings ”one to create the object in the computer container, another to the newly created computer object so it could be written to the directory, and a third to a user object to manipulate the user flags and password value .

The fact that computer accounts are actually just hidden user accounts opens up a wide variety of interesting possibilities for storing additional data about a machine. You can use the unpopulated string fields for a machine account to store data about the primary user of the machine or the physical location of the machine. More importantly, however, you can find out when the machine last authenticated with the domain, which can be valuable data for those tasked with cleaning up a resource domain SAM .

Most administrators are good at placing files into directories. When it to removing these items, however, these same administrators often wait until catastrophe strikes (such as running out of disk space) on the off chance that the data might be required for future reference .

Just like file servers, Server Manager in most enterprise resource domains lists computer accounts that have been off the network for months. Administrators are usually reluctant to remove these accounts for fear that the removal might cause a user (and thus the administrator) significant hardship by doing so .

When you created the computer account initially, recall that you set an initial password. As part of the secure channel that is set up between the domain controller and the workstation, this password will be changed on a regular basis. By combining this bit of knowledge with a query on the PasswordAge property for a computer account, you can programmatically determine which machines have not been on the network for a specified period of time .

As referenced in Microsoft KB article Q197478, machine account passwords are changed every seven days by default. If your enterprise has not disabled this functionality, (see Q154501 for more information about how to disable this security feature) you can use the following code to determine which machines have not changed their passwords in the last seven days. In theory, any machine that has a password older than seven days can be considered to be off the network. To be safe, a more reasonable value should be chosen (perhaps 90 or 180 days) to accommodate mobile users who may not utilize network connectivity on a regular basis .

Consider the following code to determine which computer accounts have not been on the network in over 180 days:

 Dim Container As IADsContainer Dim TargetDomain as String TargetDomain = "  Domain_In_Which_To_Find_Old_Machine_Accounts  " Set Container = GetObject("WinNT://" & TargetDomain) Dim Member As Variant Dim Computer As IADsUser Container.Filter = Array("Computer") For Each Member In Container      Set Computer = GetObject("WinNT://" & TargetDomain & "/" & Member.Name & "$,user")      If Computer.Get("PasswordAge") > 15552000 Then           Debug.Print Computer.ADsPath & " " & Computer.Get("PasswordAge")      End If Next 

If you change the Debug.Print statement to call Container.Delete, use care to ensure that only workstation/member server accounts are removed .

Wrapping the call to Container.Delete with a conditional testing for the ADS_UF_WORKSTATION_TRUST_ACCOUNT user flag, as follows, can perform this safely:

 Dim Container As IADsContainer Dim TargetDomain as String TargetDomain = "  Domain_In_Which_To_Find_Old_Machine_Accounts  " Set Container = GetObject("WinNT://" & TargetDomain) Dim Member As Variant Dim Computer As IADsUser Dim Flags as Variant Container.Filter = Array("Computer") For Each Member In Container      Set Computer = GetObject("WinNT://" & TargetDomain & "/" & Member.Name & "$,user")      If Computer.Get("PasswordAge") > 15552000 Then           Flags = Computer.Get("UserFlags")           If (Flags And &H1000) <> 0 Then                Call Container.Delete("computer", graphics/ccc.gif Member.Name)           End If      End If Next 

Warning

The PDC does not change passwords every seven days; do not delete the PDC account!

The preceding code will permanently delete old machine accounts in the domain. If you are not careful (omitting the user flag conditional, for instance), you can delete the account for the PDC, which does not change passwords every seven days .


Make sure you use a Debug.Print statement before actually deleting the old accounts to be sure you are not eliminating valid workstations or servers from the domain. Although workstation accounts can simply be re-created, domain controller accounts cannot without significant difficulty.


   
Top


Windows NT. 2000 ADSI Scripting for System Administration
Windows NT/2000 ADSI Scripting for System Administration
ISBN: 1578702194
EAN: 2147483647
Year: 2000
Pages: 194
Authors: Thomas Eck

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net