User accounts are some of the most frequently used objects in Active Directory; they create the means of authenticating and authorizing someone to access resources on your network. Because Windows server systems authenticate and authorize users primarily through Active Directory, many key issues that system administrators deal with are covered in this chapter. In particular, Active Directory manages information regarding user passwords; group membership; enabling, disabling, or expiring user accounts; and keeping track of when users have logged on to the network.
The default location for user
objects in a domain is the cn=Users
container directly off the domain root. You can, of course, create
user
objects in other containers and
organizational units in a domain, or move them to these containers after
they’ve been created. Table 6-1
contains a list of some of the interesting attributes that are available
on user
objects. This is by no means
a complete list. There are many other informational attributes that we
haven’t included.
Table 6-1. Attributes of user objects
Attribute | Description |
---|---|
| Large integer representing when the user’s account is going to expire. See Setting a User’s Account Options (userAccountControl) for more information. |
| Relative distinguished
name of |
| Typically the full name of a user. This attribute is used in administrative tools to display a user’s descriptive name. |
| First name of the user. |
| Local or UNC path of user’s home directory. See Setting a User’s Account Options (userAccountControl) for more information. |
| Defines the drive letter to map the user’s home directory to. See Setting a User’s Account Options (userAccountControl) for more information. |
| The last time that a user logged on to a particular DC. This information is not replicated among domain controllers. |
| Approximate last logon timestamp, which is replicated among domain controllers. See Creating a UPN Suffix for a Forest for more information. |
| Multivalued, linked
attribute (with |
| Large integer representation of the timestamp for when a user was locked out. See Finding Locked-Out Users for more information. |
| Backlink listing of DNs of the groups the user is a member of. See Viewing a User’s Group Membership for more information. |
| Octet string representing the SID of the user. |
| ID of the primary group for the user. See Changing a User’s Primary Group for more information. |
| UNC path to profile directory. See Setting a User’s Account Options (userAccountControl) for more information. |
| Large integer denoting the last time the user’s password was set. See Requiring a User to Change a Password at Next Logon for more information. |
| NetBIOS-style name of the user; limited to 20 characters to support legacy applications. |
| Multivalued attribute that contains a list of SIDs that are associated with the user. |
| Path and filename of logon script. See Determining a User’s Last Logon Time for more information. |
| Last name of user. |
| List of SIDs for the groups in the domain the user is a member of (both directly and via nesting). |
| Octet string that contains a hash of a user’s password. This attribute cannot be directly queried. |
| Account flags that define such things as account status and password change status. |
| Internet-style account name for a user, which the user can use to log on to a computer. In most cases this should map to the user’s email address, but this does not always need to be the case. |
| List of computers a user can log on to, stored as a Unicode string. |
| New since Windows Server
2008. A backlink that lists the Password Settings Objects that
are applied to a |
| New since Windows Server
2008. A constructed attribute that indicates which PSO is in
effect for a |
| New since Windows Server 2008. A constructed attribute that indicates when a user’s password is going to expire. |
| New since Windows Server 2008. Indicates the number of failed interactive logons for a user account since the Interactive Logon Count feature was enabled. |
| New since Windows Server 2008. Indicates the number of failed interactive logons for a user account since the last time the user successfully logged on interactively. |
| New since Windows Server 2008. Indicates the last time and date that the user performed an unsuccessful interactive logon. |
| New since Windows Server 2008. Indicates the last time and date that the user performed a successful interactive logon. |
| New since Windows Server 2008. A multivalued attribute listing the RODCs through which a user has successfully authenticated to a full DC. |
| New since Windows Server 2008. Backlink indicating which RODCs have cached a user’s password secrets. |
| New since Windows Server 2012. Contains password information for group-managed service accounts. |
You want to modify how the default display name gets generated when you create a new user through the ADUC snap-in or through the Active Directory Administrative Center.
In the Configuration Naming Context, browse to
DisplaySpecifiers→<Locale>
where
<Locale>
is the locale for your
language (e.g., the U.S. English locale is 409).
Double-click on cn=user-Display
.
Edit the createDialog
attribute with the value you want the new default to be (e.g.,
%<sn>,
%<givenName>
).
When you create a new user
object in ADUC or ADAC, it will automatically fill in the Full Name
field as you type in the First Name, Initials, and Last Name fields. As
a convenience, you may want to alter that behavior so that it
automatically fills in a different value. To do that, you need to modify
the User-Display
display specifier,
which has the following distinguished name:
cn=user-Display,cn=<Locale>
,cn=DisplaySpecifiers,cn=Configuration,<ForestRootDN>
<Locale>
should be replaced with
your language-specific locale, and
<ForestRootDN>
should contain the
distinguished name for your forest root domain. You need to modify the
createDialog
attribute, which by
default has no value. Replacement variables are presented by
%<attribute>
, where
attribute
is an attribute name. For example,
if you wanted the default to be “LastName, FirstName”, you would use the
following value:
%<sn
>, %<givenName
>
In the left pane, click to highlight the domain.
In the right pane, click New and then click User.
The two required fields are Full Name and sAMAccountName. The Full Name field will automatically be populated if you enter at least a first or a last name. Fill out any of the remaining fields and then click OK to complete the new-user creation.
You can create a user with the built-in DSAdd utility or by using AdMod. Use the following DSAdd syntax:
> dsadd user "<UserDN>
" -upn<UserUPN>
-fn "<UserFirstName>
"↵ -ln "<UserLastName>
" -display "<UserDisplayName>
" -pwd<UserPasswd>
To create a user account with AdMod, use the following syntax:
> admod -b "<UserDN>
" -add objectClass::user sAMAccountName::<SAMAccount>
To make a user account immediately available for a user, you’ll
need to make sure the account is enabled, which is accomplished by
setting userAccountControl
to 512
after you’ve set a password that follows any password complexity rules
in place for the user (order is important in this case). If you set only
the attributes shown in the command-line and PowerShell examples, then
the user accounts will be disabled by default.
You can also create user accounts using the inetOrgPerson
class, which is described in
Creating an inetOrgPerson User. inetOrgPerson
objects can be used for user
authentication and restricting access to resources in much the same way
as user
objects.
To set additional attributes, double-click on the user account after it has been created. There are several tabs to choose from that contain attributes that are grouped together based on function (e.g., Profile).
Several additional attributes can be set with the dsadd user
command. Run dsadd user /?
for the complete list. When
creating a user with AdMod, you must specify the objectClass
and sAMAccount
attributes at a minimum. You can
add additional attributes with the admod
command by using the
<attributename>::<value>
syntax.
When using the New-ADUser
cmdlet, there are about 50 common switches that can be used. In
addition, you can specify the –OtherAttributes
switch to set less common
attributes. Here is a list of some of the common switches:
-Name
-AccountPassword
-City
-Company
-Department
-Description
-DisplayName
-GivenName
-HomeDirectory
-HomeDrive
-Manager
-OfficePhone
-PostalCode
-SamAccountName
-State
-StreetAddress
-Surname
-Title
Creating a Large Number of Users for creating
users in bulk; Creating an inetOrgPerson User for
creating an inetOrgPerson
user; Setting a User’s Account Options (userAccountControl); MSDN:
ADS_USER_FLAG_ENUM
You want to create a large number of user
objects, either for testing purposes or
to initially populate Active Directory with your employee, customer, or
student user accounts.
The following example uses a for
do
loop in combination with dsadd
to create 1,000 users under the
bulk
OU in the
adatum.com domain with usernames following the
naming convention of User1,
User2, User3, etc. The
password is set, but other attributes are not configured. However, you
can modify the dsadd
command to
populate additional attributes, as well.
> for /L %i in (1,1,1000) do dsadd user "cn=User%i,ou=bulk,dc=adatum,dc=com" -samid User%i -pwd N78ie.%i
You can also use the ldifde utility to perform a bulk import of unique usernames. Create an .ldf file using the following syntax (separate multiple entries with a blank line in between):
dn: cn=Joe Richards, ou=Engineering, dc=adatum, dc=com changetype: add cn: Joe Richards objectClass: user samAccountName: jrichards
Once you’ve created the LDIF file containing your user records, import the file using the following command:
> ldifde -i -f<filename.ldf>
-s<servername>
You may notice that the LDIF file does not specify the user’s
password; this attribute must be modified after the user
object has been created.
You can also use admod
to
automate this task. The following code will create 4,000 users named
"TestUser_1"
, "TestUser_2"
, "TestUser_3"
, etc.:
> admod -sc adau:4000;MyPassword1!;cn=testuser,ou=testou,dc=adatum,dc=com
Using ADSI, PowerShell, and the command-line utilities, you can create hundreds and even thousands of users far more easily and quickly than you would be able to do through a graphical user interface. You can also modify the examples to pull real data from a data source, such as an employee database.
The AdMod syntax makes use of the -adau
shortcut, which will add
X
number of users with
Y
as their starting password, so that
"-adau:4000;MyPassword1"
will
create 4,000 users with a starting password of "MyPassword1"
. If the starting password is
not specified, a unique random complex password will be generated for
each user.
The PowerShell example contains multiple lines. After the
do
command, PowerShell will drop
down to a >>
prompt, which
indicates that the command is not complete. After entering the final
line of the script, you need to press the Enter key twice to execute
the script. Once complete, the configured PowerShell prompt will
return.
Creating a User for creating a user; MS KB 263911 (How to Set a User’s Password using LDIFDE)
You want to create an inetOrgPerson
object, which is the standard
LDAP object class to represent users.
If you need to change domains, right-click on Active Directory Users and Computers in the left pane, select Change Domain, enter the domain name, and click OK.
In the left pane, browse to the parent container of the new user, right-click on it, and select New→InetOrgPerson.
Enter text in the First Name, Last Name, and User Logon Name fields as appropriate and click Next.
Enter and confirm the password, set any of the password flags, and click Next.
DSAdd does not support creating inetOrgPerson
objects, so use
ldifde or AdMod instead. First, you need to
create an LDIF file called create_inetorgperson.ldf with the following
contents:
dn:<UserDN>
changetype: add objectclass: inetorgperson sAMAccountName:<UserName>
dn:<UserDN>
changetype: modify add: userAccountControl userAccountControl: 512
Be sure to replace <UserDN>
with the distinguished name of the user you want to add and
<UserName>
with the user’s username.
Then run the following command:
> ldifde -i -f create_inetorgperson.ldf
You can also use the admod utility to
create an inetOrgPerson
object, as
follows:
> admod -b "cn=inetOrgPerson,cn=Users,dc=adatum,dc=com" objectclass::inetOrgPerson sAMAccountName::inetOrgPerson -add
The inetOrgPerson
object class
was defined in RFC 2798. It is the closest thing in the LDAP world to a
standard representation of a user, and most LDAP vendors support the
inetOrgPerson
class. Unfortunately,
Microsoft did not support inetOrgPerson
with the initial release of
Active Directory. Even though it provided an add-on later to extend the
schema to support it, the damage had been done. Most Active Directory
implementations were already using the user
object class and were unlikely to
convert, which required vendors to build in support for the user
class.
You can create inetOrgPerson
objects for your users, who can use them to authenticate just like
accounts of the user
object class. If
you haven’t deployed Active Directory yet and you plan to integrate a
lot of third-party LDAP-based applications that rely on inetOrgPerson
, you may want to consider using
it instead of the user
class. You
won’t be losing any information or functionality because the inetOrgPerson
class inherits directly from the
user
class. For this reason, the
inetOrgPerson
class has even more
attributes than the Microsoft user
class.
The one potential downside is that some of the Microsoft tools,
such as the DS utilities, do not support modifying inetOrgPerson
objects. (You can, however, use
AdMod to perform these modifications.)
Creating a User for creating a user; MS KB 314649; RFC 2798 (Definition of the InetOrgPerson LDAP Object Class)
You want to convert one or more user
objects to inetOrgPerson
objects to improve
interoperability in a heterogeneous environment.
If an entry for the naming context you want to browse is not already displayed, do the following:
Right-click on ADSI Edit in the right pane and click “Connect to.”
Fill in the information for the domain naming context, container, or OU that contains the object you want to modify. Click the Advanced button if you need to enter alternate credentials.
In the left pane, browse to the naming context, container,
or OU containing the user
object that you want to view. Once you’ve found the object,
right-click on it and select Properties.
Scroll to objectClass
and
select Edit.
Under “Value to add,” enter inetOrgPerson
and click Add.
Click OK twice to save your changes.
In a heterogeneous environment, you may wish to convert one or
more Active Directory user
objects to
inetOrgPerson
objects. Since the
inetOrgPerson
class inherits from the
user
class, making this modification
is a simple matter of adding the "inetOrgPerson"
value to an object’s objectClass
attribute. It’s important to note
that this is the only instance in which you can modify structural
classes in this manner; you can’t simply modify a user
object with whatever class you wish, even
if that class inherits from the user
class.
You can easily modify the command-line and PowerShell solutions to
convert all user accounts in your domain (or just in a particular OU) to
inetOrgPerson
objects. For example,
the following combination of adfind
and admod
will search for all user
accounts in the Marketing OU and convert each one to an inetOrgPerson
object (the -unsafe
switch is necessary if you need to modify more than 10 objects at a
time; you can also use the -safety
X
switch and specify the actual number of
objects that you expect to modify for
X
):
adfind -default -rb "ou=Marketing" -f↵ "(&(objectcategory=person)(objectclass=User))" | admod↵ objectcategory:+:inetOrgPerson -unsafe
If you need to change domains, right-click on Active Directory Users and Computers in the left pane, select Change Domain, enter the domain name, and click OK.
In the left pane, browse to the parent container of the objects you want to modify.
In the right pane, highlight each object you want to modify, right-click, and select Properties.
Check the box beside the attribute(s) you want to modify and edit the fields for the attributes.
Click OK.
The following command sets the home directory of all users under
a parent container (<ParentDN>
) to be
on a particular fileserver
(<FileServer>
). The folder name is
automatically replaced with the sAMAccountName
for the user by using the
$username$
syntax:
> dsquery user "<ParentDN>
" -limit 0 -scope onelevel | dsmod user -hmdir↵ "\<FileServerName>
$username$"
It is often necessary to update several users at once due to an organizational, geographic, or fileserver change. In each solution, we showed how to modify all users within a parent container, but you may need to use different criteria for locating the users.
Within ADUC, it may appear that you are limited to modifying multiple users that reside in the same container. However, you can create a saved query that returns users based on any criteria you specify. You can then highlight those users and modify them as described in the GUI solution.
With the CLI solution, you can modify the dsquery user
command to search on whatever
criteria you want. The same applies in the PowerShell solution by using
a filter or an LDAP filter.
Searching for Objects in a Domain for more information on searching AD
In the right pane, enter the name of the user in the Global Search box, select the desired domain in the scope, and then click the search icon.
In the search results, right-click the name of the user and then click Delete.
Click Yes to confirm the deletion, which will complete the deletion process.
This recipe covers deleting individual users. If you want to delete a container or OU and all the objects in it, take a look at Deleting a Container That Has Child Objects.
Deleting a Container That Has Child Objects for deleting a container; MSDN: IADsContainer::Delete; MSDN: IADsDeleteOps:: DeletesObject
In the left pane, right-click on the domain and select Find.
Select the appropriate domain beside In.
Beside Name, type the name of the user and click Find Now.
In the Search Results window, double-click on the user.
Click the Profile tab.
Modify the various profile settings as necessary.
Click OK.
The four attributes that make up a user’s profile settings are:
When you set the homeDirectory
attribute, the folder being referenced needs to already exist. For an
example on creating shares for users, see MS KB 234746.
Modifying an Attribute for Several Users at Once for methods to modify the attributes for multiple users
If you need to change domains, right-click on Active Directory Users and Computers in the left pane, select Change Domain, enter the domain name, and click OK.
In the left pane, right-click on the domain and select Find.
Type the name of the user and click Find Now.
In the Search Results window, right-click on the user and select Move.
Browse to and select the new parent container or OU.
Click OK.
You can also drag and drop objects from one container or OU into another.
Moving a user
object between
OUs in the same domain has no direct impact on the actual user in terms
of any security or distribution groups that the user is a member of. The
things to be cautious of when moving the user to a new OU are different
security settings, different GPOs, and the possibility of breaking
applications that have the user’s DN hardcoded into them.
Moving an Object to a Different OU or Container for moving objects between OUs
You want to redirect all new users from the default location
(cn=Users
) into a different location
that you specify.
From the menu, select Connection→Connect.
For Server, enter the name of a domain controller (or leave it blank to do a serverless bind).
For Port, enter 389.
Click OK.
From the menu, select Connection→Bind.
Accepted the default and bind as the currently logged on user or select the option to bind with credentials and then enter the credentials.
Click OK.
From the menu, select Browse→Modify.
For DN, enter the distinguished name of the domainDNS
object of the domain you want
to modify.
For Attribute, type
.wellKnownObjects
For Values, enter the following:
B:32:A9D1CA15768811D1ADED00C04FD8D5CD:cn=Users,<DomainDN>
where <DomainDN>
is the
same as the DN you enter for the DN field.
Select Delete for the Operation and click the Enter button.
Go back to the Values field and enter the following:
B:32:A9D1CA15768811D1ADED00C04FD8D5CD:<NewUsersParent>,<DomainDN>
where <NewUsersParent>
is
the new parent container for new computer objects (e.g., "ou=Adatum Users"
).
Select Add for the Operation and click the Enter button.
Click the Run button.
The result of the operations will be displayed in the right pane of the main LDP window.
Most modern methods for creating user accounts, including the
Active Directory Administrative Center, ADUC MMC snap-in, AdFind, and
DSAdd, allow you to specify which OU a new user should be created in.
However, some utilities, such as net
user
or the WinNT ADSI provider, still rely on a legacy API
that will create a user only in its default location until an
administrator manually moves it to another OU. The default location is
the cn=Users
container; this can
create issues applying Group Policy to new user
objects since the Users
container cannot have a GPO linked to
it. To ensure that all newly created users receive the necessary Group
Policy settings as soon as they are created, use the redirusr.exe utility to redirect all new
users that are not otherwise placed into a designated OU into the
destination OU that you specify. You need to run this utility only once
per domain, and the destination OU needs to exist before you run the
utility.
In the left pane, right-click on the domain and select Find.
Type the name of the user and click Find Now.
In the Search Results window, right-click on the user and select Rename.
You can modify the Full Name, First Name, Last Name, Display Name, User Logon Name, and User Logon Name (pre-Windows 2000) fields.
Click OK after you are done.
The following command will rename the RDN of the user:
> dsmove "<UserDN>
" -newname "<NewUserName>
"
You can modify the UPN (-upn
), first name (-fn
), last name (-ln
), and display name (-display
) using the dsmod user
command. For example, the
following command will change the user’s UPN and last name:
> dsmod user "<UserDN>
" -upn "<NewUserUPN>
" -ln "<NewUserLastName>
"
You can also rename a user by using AdMod with the following syntax:
> admod -b "<UserDN>
" -rename "<NewUserName>
"
Renaming a user
object can have
a couple of different meanings in Active Directory. In the generic
object sense, renaming an object consists of changing the RDN for the
object to something else, as when cn=jsmith
becomes cn=joe
. Typically, though, you need to rename
more than that with users. For example, let’s say you had a username
naming convention of FirstInitialLastName, so Joe Smith’s username would
be jsmith
. Let’s pretend that Joe
decides one day that Smith is way too common and he wants to be unique
by changing his last name to Einstein. Now his username should be jeinstein
. The following attributes
would need to change to complete a rename of his object:
His userPrincipalName
(UPN)
should change to [email protected]
.
His mail
(email address)
attribute should change to [email protected]
.
While this example may be contrived, it shows that renaming Joe Smith to Joe Einstein can take up to five attribute changes in Active Directory, or more if you include updates to proxy addresses and other attributes that are typically tied to the user’s name. It is also important to note that if you change any of the first three in the bulleted list (RDN, SAM Account Name, or UPN), you should have the user log off and log back on after the changes have replicated. Since most applications and services rely on user GUID or SID, which doesn’t change during a user rename, the person should not be affected, but you want to have him log off and back on anyway, just in case.
Renaming an Object for renaming objects
You want to copy an existing user account, which may be serving as a template, to create a new account.
In the left pane, browse to the parent container of the
template user
object.
In the right pane, right-click on the user and select Copy.
Enter the name information for the new user and click Next.
Enter a password, check any options you want enabled, and click Next.
Click Finish.
To create a new user from a template with PowerShell, use the following syntax:
$user = Get-ADUser -Identity<TemplateUserDN>
-Properties department, co, title, l, c, st, countrycode New-ADUser -Instance $user -Name "<NewUserName>
" -DisplayName "<NewDisplayName>
" -GivenName "<NewGivenname>
" -Surname "<NewSuname>
" -UserPrincipalName "<NewUPN>
" -SamAccountName "<NewSamAccountName>
" -PasswordNotRequired $true -Enable $true
Copying a user consists of copying the attributes that are common among a certain user base, which can include department, address, and perhaps even organizational information. ADUC actually uses attributes that are marked in the schema as “Copied when duplicating a user” to determine which attributes to copy. If you are interested in finding the attributes that are configured in the schema to get copied, see Modifying the Attributes That Are Copied When Duplicating a User.
Modifying the Attributes That Are Copied When Duplicating a User for finding the attributes that should be copied when duplicating a user
Despite the deceptively simple commands just shown, finding the accounts that are currently locked out is a surprisingly complicated task. You would imagine that you could run a query using DSQuery or AdFind (similar to the one to find disabled users in Finding Disabled Users), but unfortunately, it is not that easy.
The lockoutTime
attribute is
populated with a timestamp when a user is locked. One way to find
locked-out users would be to find all users that have something
populated in lockoutTime
(i.e.,
lockoutTime=*
). That query would
definitely find all the currently locked users, but it would also find
all the users that subsequently became unlocked and have yet to log in
since being unlocked; the lockoutTime
attribute doesn’t get reset until the next time the user logs on
successfully. This is where the complexity comes into play.
To determine the users that are currently locked out, you have to
query the attribute lockoutDuration
stored on the domain object (e.g., dc=adatum,dc=com
). This attribute defines the
number of minutes that an account will stay locked before becoming
automatically unlocked. You need to take this value and subtract it from
the current time to derive a timestamp that would be the outer marker
for which users could still be locked. You can then compare this
timestamp with the lockoutTime
attribute of the user
object. The
search filter to find all locked users once you’ve determined the locked
timestamp would look something like this:
(&(objectcategory=Person)(objectclass=user)(lockoutTime>DerivedTimestamp
))
For any users that have a lockoutTime
that is less than the derived
timestamp, their account has already been automatically unlocked per the
lockoutDuration
setting.
None of the current standard GUI or CLI tools incorporates this kind of logic, but fortunately joe Richards wrote the unlock.exe utility, which does. And as its name implies, you can also unlock locked accounts with it. Thanks, joe!
In the left pane, right-click on the domain and select Find.
Select the appropriate domain.
Type the name of the user and click Find Now.
In the Search Results window, right-click on the user and select Properties.
Click the Account tab and then click Unlock account.
Click OK.
If you’ve enabled account lockouts for an Active Directory domain (see Finding Locked-Out Users), some users may eventually get locked out. A user can get locked out for a number of reasons, but generally it is because a user mistypes her password a number of times, changes her password and does not log off and log on again, or has services or scheduled tasks running under the security context of her individual user account rather than a service account.
You can use ADSI’s IADsUser::IsAccountLocked
method to determine
whether a user is locked out. You can set IsAccountLocked
to FALSE
to unlock a user. You can also query the
msDS-User-Account-Control-Computed
attribute of an object.
Finding Locked-Out Users for finding locked-out users; Troubleshooting Account Lockout Problems for viewing the account lockout policy; MSDN: Account Lockout
A user is having account lockout problems and you need to determine from where and how the account is getting locked out.
LockoutStatus is a program available for Windows that can help identify the domain controller that handled the lockout. It works by querying the lockout status of a user against all domain controllers in the user’s domain.
To determine the lockout status of a user:
Launch LockoutStatus and select File→Select Target from the menu.
Enter the target username and the domain of the user.
Click OK.
At this point, each domain controller in the domain will be queried and the results will be displayed. To dive deeper and figure out which computer the lockout occurred on, you need to use the EventCombMT utility and point it at the domain controller that handled the lockout. EventCombMT can query the domain controller with the specific lockout event IDs that will allow you to find the computer.
The lockoutstatus.exe utility is just one of many that is available in the Account Lockout and Management tool set provided by Microsoft. These lockout tools are intended to help administrators with account lockout problems that were very difficult to troubleshoot in the past. Along with the tool mentioned in , here are a few others that are included in the set:
A script that uses this DLL, called EnableKerbLog.vbs (included with the tool set), can be used to enable logging of application authentication. This can help identify applications that are using bad credentials and causing account lockouts.
This displays services and shares that are using a particular account name. It can also print all the users and their password ages.
This is a filter tool for the netlogon.log files. You can use it to extract just the lines that relate to account lockout information.
This utility parses event logs from multiple servers, either to collect all entries together or to search for individual events across multiple computers. This is extremely useful when troubleshooting user account lockouts, for example, by determining which computer is causing the account lockout.
All the Account Lockout tools are available for download from the Microsoft Download Center.
In the left pane, expand the forest, expand Domains, expand the desired domain, expand Group Policy Objects, and then click the Default Domain Policy.
In the right pane, click the Settings tab to generate a report of all of the GPO settings.
Click “show” to the right of Security Settings and then click “show” to the right of Accounts Policies/Password Policy to view the password policy.
Click “show” to the right of Account Policies/Account Lockout Policy to view the account lockout policy.
To retrieve the minimum password length, number of passwords remembered, password properties, and lockout threshold of the domain-wide password policy for the adatum.com domain using PowerShell, run the following command:
Get-ADObject "dc=adatum,dc=com" -Properties * | FL minPwdLength,pwdHistoryLength,pwdProperties,lockoutThreshold
To retrieve the maximum password age, minimum password age, lockout duration, and lockout observation of the domain-wide password policy for the adatum.com domain using PowerShell, use the following script:
$DOMAIN = Get-ADObject "dc=adatum,dc=com" -Properties * $MAXPWDAGE = [System.TimeSpan]::FromTicks([System.Math]::ABS($DOMAIN.maxPwdAge)).Days $MINPWDAGE = [System.TimeSpan]::FromTicks([System.Math]::ABS($DOMAIN.minPwdAge)).Days $LOCKOUTDURATION =; [System.TimeSpan]::FromTicks([System.Math]::ABS($DOMAIN.lockoutDuration)).Days $LOCKOUTOBSERVATION =; [System.TimeSpan]::FromTicks([System.Math]::;ABS($DOMAIN.lockoutObservationWindow)).Days Write-Host "Maximum password age:",;$MAXPWDAGE;Write-Host "Minimum password age:",;$MINPWDAGE;Write-Host "Lockout duration:",;$LOCKOUTDURATION;Write-Host "Lockout observation:",$LOCKOUTOBSERVATION
Several parameters controlling account lockout and password complexity can be set on a domain-linked Group Policy Object such as the Default Domain Policy. The properties that can be set for the password and account lockout policies include:
Number of minutes an account will be locked before being
automatically unlocked. A value of 0
indicates accounts will be locked out
indefinitely—that is, until an administrator manually unlocks
them.
Number of failed logon attempts after which an account will be locked.
Number of minutes after a failed logon attempt that the
failed logon counter for an account will be reset to 0
.
The properties that can be set for the Password Policy include:
Number of passwords to remember before a user can reuse a previous password.
Maximum number of days a password can be used before a user must change it.
Minimum number of days a password must be used before it can be changed.
Minimum number of characters a password must be.
If enabled, passwords must meet all of the following criteria:
Not contain all or part of the user’s account name
Be at least six characters in length
Contain characters from three of the following four categories:
English uppercase characters (A–Z)
English lowercase characters (a–z)
Base 10 digits (0–9)
Nonalphanumeric characters (e.g., !, $, #, %)
If enabled, passwords are stored in such a way that they can be retrieved and decrypted. This is essentially the same as storing passwords in plain text, and should be avoided unless it is absolutely necessary.
In Windows Server 2003 and legacy versions of Windows, administrators can configure only one password and account lockout policy for domain users, per domain. If a group of users requires a different policy, a separate domain (and all of the hardware requirements and administrative overhead associated with managing that separate domain) is needed. Windows Server 2008 and later versions of Windows allow for the creation of Fine-Grained Password Policies (FGPPs), which allow you to configure multiple password policies within a single domain.
On a domain controller or any computer that has the Remote Server Administration Tools (RSAT) installed, the Group Policy Management snap-in is available from the Start menu under Administrative Tools.
In the first example, the pwdProperties
attribute returns a value that
indicates some of the general settings of the password policy. For
example, a 1 indicates that password complexity is enabled. A 0
indicates that password complexity is disabled. The number 16
indicates that passwords are stored using reversible
encryption.
In the second example, we have to deal with conversion from 100-nanosecond intervals, which is how the values are stored.
“Account Lockout Best Practices White Paper”; MSDN: DOMAIN_PASSWORD_INFORMATION; “Pwd–Properties attribute (Windows)”
In the top-left pane, click the tree view icon.
Expand the System
container.
Scroll down and right-click Password Settings
Container, expand the
New menu, and then click Password Settings.
Fill in the desired password settings in the top pane. Note that the fields with a red asterisk are required fields.
In the Directly Applies To section, click the Add button to
add a user
object that will be
the target of the FGPP.
Click OK to create the FGPP.
Once an FGPP has been created, you can modify the password and
account lockout settings controlled by the object, as well as the users
and groups that it should apply to. Since the PasswordSettingsObject
is an Active Directory
object class, these modifications can be made using any interface that
can modify objects. When working from the command line, the
psomgr tool from joeware allows you to
modify one or multiple PSOs at a time, and can also create “starter”
PSOs using the -quickstart
command-line switch. The full syntax for
psomgr.exe can be obtained by
typing psomgr.exe /?
at a command
prompt, or by visiting the joeware
website.
Open Active Directory Users and Computers. Click View and confirm that there is a checkmark next to Advanced Features.
Browse to the user or group in question; right-click on the object and click Properties.
Click on the Attribute Editor tab. Click Filter and confirm that there is a checkmark next to “Show read-only attributes: Constructed and Backlinks.”
Scroll to the msDS-PSOApplied
attribute. If an FGPP is
applied directly to the user, it will be shown in the
value.
Scroll to the msDS-ResultantPSO
attribute. If an FGPP
is applied to a group that the user is a member of, it will be
shown in the value.
Within a domain, each user
object contains a constructed backlink attribute called msDS-ResultantPSO
that indicates which
PasswordSettingsObject
is in effect
for that user. The precedence rules for PasswordSettingsObjects
are as
follows:
If a PSO has been applied directly to the user
object, this PSO will take
precedence. If multiple PSOs have been applied to a single user, the
following tiebreakers will be used:
A PSO with a lower-numbered Precedence attribute (e.g.,
5
) will be applied over a
higher-numbered one (e.g., 50
).
If multiple PSOs have been configured with the same Precedence attribute, the PSO with the lowest GUID will take final precedence.
If no PSOs have been applied directly to the user, any PSO that has been applied to a group that the user is a member of, whether directly or indirectly, will be applied. The same tiebreakers will be used here as in rule 1.
If no PSOs have been applied to the user or any groups that the user is a member of, the default domain PSO will be applied.
In the left pane, right-click on the domain and select Find.
Select the appropriate domain.
Type the name of the user beside Name and click Find Now.
In the Search Results window, right-click on the user and select Enable Account to enable, or Disable Account to disable.
Click OK.
Account status is used to control whether a user is allowed to log
on or not. When an account is disabled, the user is not allowed to log
on to his workstation with the account or to access AD controlled
resources. Much like the lockout status, the account status is stored as
a flag in the userAccountControl
attribute (see Setting a User’s Account Options (userAccountControl)).
There is an IADsUser::AccountDisabled
property that allows
you to determine and change the status. Set the method to FALSE
to enable the account or to TRUE
to disable
it.
Finding Disabled Users for finding disabled
users; Setting a User’s Account Options (userAccountControl) for more
on the attribute userAccountControl
You can enumerate all disabled user
objects in your domain by using the
built-in DSQuery utility, as follows:
> dsquery user <DomainDN>
-disabled
You can also use a bitwise query in AdFind to produce the same output, using the following syntax:
> adfind -bit -b <DomainDN>
-f↵
"&(objectcategory=person)(objectclass=user)(useraccountcontrol:AND:=2)"
You can replace <DomainDN>
with the DN of a specific organizational unit if you wish to
restrict the results of your AdFind query.
Users in Active Directory can be either enabled or disabled. A disabled user cannot log in to the domain. Unlike account lockout, which is an automatic process that is based on the number of times a user incorrectly enters a password, an account has to be manually enabled or disabled.
All disabled user accounts have the bit that represents 2
(0010 base 2
) set in their userAccountControl
attribute. This doesn’t
mean that the attribute will be equal to 2, it just means that the bit
that equals 2 will be enabled—other bits may also be set. See Searching with a Bitwise Filter and Modifying a Bit-Flag Attribute for a more detailed
explanation of bit flags.
Searching with a Bitwise Filter; Modifying a Bit-Flag Attribute; Enabling and Disabling a User for enabling and disabling users
In the left pane, right-click on the domain and select Find.
Select the appropriate domain.
Type the name of the user beside Name and click Find Now.
In the Search Results window, double-click on the user.
Click the Member Of tab.
To view all indirect group membership (from nested groups), you’ll need to double-click on each group.
The following command displays the groups that
<UserDN>
is a member of. Use the
-expand
switch to list nested group
membership as well:
> dsget user <UserDN>
-memberof [-expand]
You can also use the GetUserInfo tool with the following syntax:
> getuserinfo \<Domain>
<Username>
A third option would be to use the whoami tool, as follows:
> whoami /groups
To round out the command-line options for viewing group memberships, you can use the MemberOf joeware utility with the following syntax:
> memberof -u<Domain>
<User>
The memberOf
attribute on
user
objects is multivalued and
contains the list of distinguished names for groups of which the user is
a member. memberOf
is actually linked
with the member
attribute on group
objects, which holds the distinguished
names of its members. For this reason, you cannot directly modify the
memberOf
attribute; you must instead
modify the member
attribute on the
group.
The primary group of a user, which the user is technically a
member of, will not be shown in the CLI or solutions except in the case
of the MemberOf utility. This is due to the fact that the primary group
is not stored in the memberOf
attribute like the rest of the groups. See Recipes and for more on finding the primary group
of a user.
Changing a User’s Primary Group; Viewing the Nested Members of a Group for more on viewing the nested members of a group; Resolving a Primary Group ID; Finding the Linked Attributes for more information on linked attributes
In the left pane, right-click on the domain and select Find.
Select the appropriate domain.
Type the name of the user beside Name and click Find Now.
In the Search Results window, double-click on the user.
Click the Member Of tab.
Highlight all groups listed in the Member Of tab and select Remove. Click Yes to confirm.
Click OK.
The example command filters out the Domain Users group. By
default, the Domain Users group is the primary group for user
objects. You can’t remove a user from
her primary group. In some cases, a different group may be the primary
group and, in such situations, should be substituted for Domain Users
in the command.
In the left pane, right-click on the domain and select Find.
Select the appropriate domain.
Type the name of the user beside Name and click Find Now.
In the Search Results window, double-click on the user.
Click the Member Of tab.
Click on the name of the group you want to set as the primary group.
Click the Set Primary Group button.
Click OK.
First, obtain the primarygroupToken
of the desired primary
group by using the following syntax:
Get-ADGroup -Identity "<GroupDN>
" -Properties primarygroupToken | FL primarygroupToken
Next, use the following syntax to replace the primaryGroupID
attribute on a user back to
the Domain Users group (change the ID to the desired group ID based on
the first PowerShell command if the goal is to change the primary
group to something else):
Set-ADObject "<UserDN>
" -Replace @{PrimaryGroupID="513"}
The primary group is a holdover from Windows NT that was used to support Macintosh and POSIX clients. That being said, you might have some legacy applications that depend on the primary group, and therefore you may have to change some users’ primary groups.
Changing the primary group is not difficult, but it is not
straightforward, either. The primary group is stored on user
objects in the primaryGroupID
attribute, which contains the
RID of the primary group. You can obtain this value by querying the
primaryGroupToken
attribute on the
target group
object. Before you can
set the primaryGroupID
on the
user
object, you have to first make
sure the user is a member of the group. If you try to set the primaryGroupID
for a group in which the user
is not a member, you will get an error.
The default primaryGroupID
is
set to 513 (Domain Users) for all users.
Resolving a Primary Group ID for determining the group name given a group ID; MS KB 297951 (How to Use the PrimaryGroupID Attribute to Find the Primary Group for a User)
In the left pane, right-click on the domain and select Find.
Select the appropriate domain.
Beside Name, type the name of the user you want to transfer groups from and click Find Now.
In the Search Results window, double-click on the user.
Click the Member Of tab.
For each group you want to add another user in, do the following:
Double-click on the group.
Click the Members tab.
Click the Add button.
Find the user you want to add in the object picker and click OK.
Click OK.
The following command line will add
<NewUserDN>
to all of the groups that
<CurrentUserDN>
is a member
of:
> for /F "usebackq delims=""" %i in ('dsget user"<CurrentUserDN>
" -memberof') do dsmod group %i -addmbr "<NewUserDN>
"
If you want to get fancy and remove
<CurrentUserDN>
from each of the
groups in the same operation, simply add an -rmmbr
option on the end:
> for /F "usebackq delims=""" %i in ('dsget user"<CurrentUserDN>
" -memberof') do dsmod group %i -addmbr "<NewUserDN>
"-rmmbr "<CurrentUserDN>
"
You can also add <NewUserDN>
to
all of the groups that
<CurrentUserDN>
is a member of by
using a combination of AdFind and AdMod, as follows:
> adfind -b<DomainDN>
-f member=<Source User DN>
-dsq | admod member:+:<Dest. UserDN>
-unsafe
Employees come and go; people take on new responsibilities and move on to new jobs. It is common to have movement within an organization. When this happens, typically someone is replacing the person who is moving on. The administrator needs to get the new person up to speed as quickly as possible, including setting up accounts and granting access to any necessary resources. A big part of this process includes adding the new user to the correct groups. You can help facilitate this by using one of the processes outlined in the “Solution” section to help the user gain access to the exact same groups that the former employee was a member of.
One important issue to point out is that the memberOf
attribute, which was used in the
command-line solutions to determine a user’s group membership, contains
only the groups that are visible to the DC that’s being queried; this
can vary depending on whether the DC in question is a global catalog and
whether the user belongs to any universal groups. Any groups the user is
a member of outside of the user’s domain will not be transferred. To
transfer universal group membership outside of a domain, you will need
to perform a query against the global catalog for all group objects that
have a member attribute that contains the DN of the user. You can also
search the global catalog for the memberOf
attribute for a given user to
determine a user’s universal group memberships.
Adding and Removing Members of a Group for adding and removing members of a group
In the left pane, right-click on the domain and select Find.
Select the appropriate domain.
Type the name of the user beside Name and click Find Now.
In the Search Results window, right-click on the user and select Reset Password.
Enter and confirm the new password.
This command changes the password for the user specified by
<UserDN>
. Using *
after the -pwd
option prompts you for the new
password. You can replace *
with
the password you want to set, but it is not a good security practice
since other users that are logged in to the machine may be able to see
it:
> dsmod user <UserDN>
-pwd *
You can modify the unicodepwd
attribute directly by encrypting the admod
connection using the -kerbenc
switch:
> admod -b "<UserDN>
" unicodepwd::<Password>
-kerbenc
You can also use admod
with
the #setpwd#
switch:
> admod -b "<UserDN>
" #setpwd#::<NewPassword>
The PowerShell solution follows the command-line solution model,
which prompts for the password instead of entering the password in plain
text in the command. PowerShell supports converting a plain text string
as part of the command, but that method isn’t considered as secure. You
can use a plain text password in the password reset by using the
ConvertTo-SecureString -AsPlainText
"
<NewPassword>
"
option in place of the password prompt. The
following example shows the full command:
Set-ADAccountPassword -Identity "<UserDN>
" -Reset -NewPassword (ConvertTo-SecureString -AsPlainText "<NewPassword>
" -Force)
In the left pane, right-click on the domain and select Find.
Select the appropriate domain.
Beside Name, type the name of the user you want to modify and click Find Now.
In the Search Results window, double-click on the user.
Click the Account tab.
Under Account options, check the box beside “User cannot change password.”
Even though in the GUI solution you check and uncheck the “User
cannot change password” setting, actually making the change in Active
Directory is a little more complicated. Not allowing a user to change
his password consists of setting two deny Change Password ACEs on the
target user
object. One deny ACE is
for the Everyone
account and the
other is for Self
.
To perform this change across multiple users, you can multiselect users in Active Directory Users and Computers and then perform the remaining steps in the GUI solution.
In the left pane, right-click on the domain and select Find.
Select the appropriate domain.
Beside Name, type the name of the user you want to modify and click Find Now.
In the Search Results window, double-click on the user.
Click the Account tab.
Under Account options, check the box beside “User must change password at next logon.”
Be careful when forcing users to change their password at next logon by using the PowerShell solution. Active Directory Users and Computers will not allow you to force a user to change her password at next logon if the user is already configured not to be able to change her password. However, you can set both of those options by using PowerShell. In such a situation, the user would not be able to log on.
In the left pane, right-click on the domain and select Find.
Select the appropriate domain.
Beside Name, type the name of the user you want to modify and click Find Now.
In the Search Results window, double-click on the user.
Click the Account tab.
Under Account options, check the box beside “Password never expires.”
Setting a user’s password to never expire overrides any
password-aging policy you’ve defined in the domain. To disable password
expiration, you need to set the bit equivalent of 65,536 (i.e.,
10000000000000000) in the userAccountControl
attribute of the target
user.
Modifying a Bit-Flag Attribute for more on
modifying a bit flag attribute; Setting a User’s Account Options (userAccountControl) for more on setting
the userAccountControl
attribute
> dsquery user -stalepwd <NumDaysSinceLastPwdChange>
You can also use the FindExpAcc joeware tool with the following syntax:
> findexpacc -pwd -days <NumDaysUntilExpiration>
The following script finds users whose passwords will expire within seven days:
$Policy = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge.days $DaysUntil = 7 Get-ADUser -Filter {(Enabled -eq "True") -and (PasswordNeverExpires -eq "False")} -Properties * | Select Name,@{Name="Expires";Expression={$Policy - ((Get-Date) - ($_.PasswordLastSet)).days}} | Where-Object {$_.Expires -gt 0 -AND $_.Expires -le $DaysUntil}
When a Windows-based client logs on to Active Directory, a check
is done against the effective password policy and the user’s pwdLastSet
attribute to determine whether the
user’s password has expired. If it has, the user is prompted to change
it. In a pure Windows-based environment, this notification process may
be adequate, but if you have a lot of non-Windows-based computers that
are joined to an Active Directory domain (e.g., Kerberos-enabled Unix
clients), or you have a lot of application and service accounts, you’ll need to develop your own
user password expiration notification process. Even in a pure Windows
environment, cached logins present a problem because when a user logs in
to the domain with cached credentials (i.e., when the client is not able
to reach a domain controller), this password expiration notification
check is not done.
The process of finding users whose passwords are about to expire
is a little complicated. Fortunately, the dsquery user
command helps by providing an
option for searching for users that haven’t changed their password for a
number of days (-stalepwd
). The
downside to the dsquery user
command
is that it will find users whose passwords are about to expire, users
who are configured so that their passwords never expire, and users that
must change their passwords at next logon (i.e., pwdLastSet = 0
).
You can use the FindExpAcc tool to query Active Directory for
expired user or computer accounts, as well as active accounts with
expired passwords. It also includes switches that are familiar from
AdFind and AdMod, such as -b
to
specify the Base DN, -f
to specify
an LDAP filter, and so on.
The findexpacc utility can also be used to query for user accounts that are about to expire, in addition to accounts with expiring passwords.
Viewing the Domain-Wide Account Lockout and Password Policies for more on the password policy for a domain; Finding Disabled Users; Setting a User’s Password for how to set a user’s password; Preventing a User’s Password from Expiring for how to set a user’s password to never expire
In the left pane, navigate to the container or the OU that
contains the user
object.
In the right pane, right-click the user and click Properties.
Scroll down the list of attributes until you find the
msDS-RevealedDSAs
attribute.
View the value of msDS-RevealedDSAs
to view the RODCs that
have cached the user’s password.
Read-Only Domain Controllers (RODCs) improve the security of
branch offices and other remote environments. One of the security
measures introduced by the RODC is the Password Replication Policy
(PRP), which specifies a list of users and groups that can and cannot
have their password secrets cached on one or more DCs. Each RODC
maintains a forward-link attribute called msDS-RevealedUsers
, which lists the user
accounts for whom each RODC has cached password secrets. Each user
account, in turn, maintains a backlink called msDS-RevealedDSAs
. This backlink can be
queried to determine which RODCs have stored password information for a
particular user account; however, like all backlinks, this attribute
cannot be modified directly.
You want to view or update the userAccountControl
attribute for a user. This
attribute controls various account options, such as whether the user
must change her password at next logon and whether the account is
disabled.
In the left pane, right-click on the domain and select Find.
Select the appropriate domain.
Beside Name, type the name of the user and click Find Now.
In the Search Results window, double-click on the user.
Select the Account tab.
Many of the userAccountControl
flags can be set
under Account options.
Click OK when you’re done.
The dsmod user
command has
several options for setting various userAccountControl
flags, as shown in Table 6-2. Each switch
accepts yes
or no
as a parameter to either enable or
disable the setting.
Table 6-2. dsmod user options for setting userAccountControl
| Description |
---|---|
| Sets whether the user must change his password at next logon. |
| Sets whether the user can change his password. |
| Sets account status to enabled or disabled. |
| Sets whether the user’s password is stored using reversible encryption. |
| Sets whether the user’s password never expires. |
To modify user properties associated with the userAccountControl
attribute, you have
several switches available through the set-ADUser
cmdlet, including the
following:
Set-ADUser -Identity<UserDN>
-PasswordNeverExpires Set-ADUser -Identity<UserDN>
-ChangePasswordAtLogon Set-ADUser -Identity<UserDN>
-Enabled
To see all of the available properties that can be modified, run the following command:
Get-Command Set-ADUser -Syntax
The userAccountControl
attribute on user
(and computer
) objects could be considered the
kitchen sink of miscellaneous and sometimes completely unrelated user
account properties. If you have to work with creating and managing
user
objects very much, you’ll need
to become intimately familiar with this attribute.
The userAccountControl
attribute is a bit flag, which means you have to take a couple of extra
steps to search against it or modify it. See Searching with a Bitwise Filter for more on searching with
a bitwise filter and Modifying a Bit-Flag Attribute
for modifying a bit flag attribute.
The dsmod user
command can be
used to modify a subset of userAccountControl
properties, as shown in
Table 6-2, and Table 6-3 contains the
complete list of userAccountControl
properties as defined in the ADS_USER_FLAG_ENUM
enumeration.
Table 6-3. ADS_USER_FLAG_ENUM values
Name | Value | Description |
---|---|---|
| 1 | Logon script is executed. |
| 2 | Account is disabled. |
| 8 | View-only attribute. Indicates that Home Directory is required. |
| 16 | Account is locked out. |
| 32 | A password is not required. |
| 64 | Read-only flag that indicates if the user cannot change her password. |
| 128 | Store password using reversible encryption. |
| 512 | Enabled user account. |
| 2048 | A permit to trust account for a system domain that trusts other domains. |
| 4096 | Enabled computer account. |
| 8192 | Computer account for backup domain controller. |
| 65536 | Password will not expire. |
| 131072 | MNS logon account. |
| 262144 | Smart card is required for logon. |
| 524288 | Allow Kerberos delegation. |
| 1048576 | Do not allow Kerberos
delegation even if |
| 2097152 | Requires DES encryption for keys. |
| 4194304 | Account does not require Kerberos preauthentication for logon. |
| 8388608 | Read-only flag indicating account’s password has expired. Only used with the WinNT provider. |
| 16777216 | Account is enabled for delegation. |
| 67108864 | Account is an RODC. |
Searching with a Bitwise Filter; Modifying a Bit-Flag Attribute for setting a bit flag attribute; “How to use the UserAccountControl flags to manipulate user account properties”
In the left pane, right-click on the domain and select Find.
Select the appropriate domain.
Beside Name, type the name of the user you want to modify and click Find Now.
In the Search Results window, double-click on the user.
Click the Account tab.
Under “Account expires,” select the radio button beside “End of.”
Select the date the account should expire.
Click OK.
User accounts can be configured to expire on a certain date.
Account expiration is stored in the accountExpires
attribute on a user
object. This attribute contains a large
integer representation of the date on which the account expires,
expressed in 100-nanosecond intervals since January 1, 1601. If you set
this attribute to 0, it disables account expiration for the user (i.e.,
the account will never expire). Note that this is different from the
dsmod user
command, where a value of
0
with -acctexpires
will cause the account to expire
at the end of the day.
To view the last logon timestamp in ADUC, do the following:
Open the ADUC snap-in (dsa.msc).
Click View and confirm that Advanced Features has a checkmark next to it.
Right-click on the domain and select Find.
Select the appropriate domain.
Beside Name, type the name of the user you want to locate and click Find Now.
In the Search Results window, double-click on the user.
Click the Attribute Editor tab.
Trying to determine when a user last logged on has always been a
challenge in the Microsoft NOS environment. In Windows NT, you could
retrieve a user’s last logon timestamp from a PDC or BDC, but this
timestamp was the last time the user logged on to the individual PDC or
BDC itself. That means to determine the actual last logon, you’d have to
query every domain controller in the domain. In large environments, this
wasn’t practical. With Windows 2000 Active Directory, things did not
improve. A lastLogon
attribute is
used to store the last logon timestamp, but unfortunately, this
attribute isn’t replicated. So again, to get an accurate picture, you’d
have to query every domain controller in the domain for the user’s last
logon attribute and keep track of the most recent one.
Since the Windows Server 2003 forest functional level became
available, we have had a viable solution. A new attribute called
lastLogonTimestamp
was added to the
schema for user
objects. This
attribute is similar to the lastLogon
attribute that was available previously, with two distinct differences.
First, and most importantly, this attribute is replicated. That means
when a user logs in, the lastLogonTimestamp
attribute will get
populated and then replicate to all domain controllers in the
domain.
The second difference is that since lastLogonTimestamp
is replicated, special
safeguards needed to be put in place so that users who logged in
repeatedly over a short period of time did not cause unnecessary
replication traffic. So, the lastLogonTimestamp
is updated only if the last
update occurred between 9 and 14 days ago by default. (This window is
configurable by modifying the msDS-LogonTimeSyncInterval
on the domain NC.)
This means that the lastLogonTimestamp
attribute could be more
than a week off in terms of accuracy with a user’s actual last logon.
Ultimately, this shouldn’t be a problem for most situations because
lastLogonTimestamp
is intended to
address the common problem where administrators want to run a query and
determine which users have not logged in over the past month or
more.
Finding Users Who Have Not Logged On Recently for finding users who have not logged on recently; “The LastLogonTimeStamp Attribute—What it was designed for and how it works”
You can locate users who have not logged on for a certain amount of time using either the built-in DSQuery tool or the OldCmp utility from joeware:
> dsquery user -inactive <NumWeeks>
OldCmp can create a report of all user
objects based on several criteria. To
create a report of all users in the adatum.com
domain who haven’t logged on in more than 90 days, for example, use
the following syntax:
> oldcmp -report -users -b dc=adatum,dc=com -llts -age 90 -sh
You can also locate users who have not logged on for a certain amount of time using PowerShell, as shown in the following command that finds users that have not logged on in 60 days:
$DaysSince = (Get-Date).AddDays(-60) Get-ADUser -Filter * -Properties LastLogonDate | Where-Object {($_.LastLogonDate -le $DaysSince) -and ($_.Enabled -eq $True) -and ($_.LastLogonDate -ne $NULL)} | Select Name,LastLogonDate
An attribute on user
objects
called lastLogonTimestamp
contains
the approximate last time the user logged on. However, the lastLogonTimestamp
attribute has a certain
amount of latency associated with it to cut down on replication traffic;
the date contained in this attribute can be anywhere from nine to 14
days off in a default domain. This latency can be made longer or shorter
by modifying the attribute msDS-LogonTimeSyncInterval
of the Domain
NC.
Finding Users Whose Passwords Are About to Expire for more on computing large integer timestamps; Determining a User’s Last Logon Time for more on finding a user’s last logon timestamp
If you need to change domains, right-click on Active Directory Users and Computers in the left pane, select Connect to Domain, enter the domain name, and click OK.
Right-click on the user and select Properties. From the Account tab, click on Logon Hours.
Select the hours that you want to allow or disallow, and click Logon Permitted or Logon Denied. Click OK.
## user DN
$userDN = "LDAP://<UserDN>
"
## powers of two in a single byte
## can use [System.Math]::Pow(), but this is faster
$pow2 = @(1, 2, 4, 8, 16, 32, 64, 128)
## bit-state - a bit is either off (0) or on (1)
$onoff = @("0", "1")
function dump($byte)
{
$result = ""
for ($i = 0; $i -lt 8; $i++)
{
$result += $onoff[($byte -band $pow2[$i]) -ne 0]
}
return $result
}
# days of the week, zero based
$days = @("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",↵
"Friday", "Saturday")
$day = 0
# main
$obj = [ADSI]$userDN
$arr = $obj.logonHours.Value
for ($i = 0; $i -lt $arr.Length; $i += 3)
{
$days[$day]
(dump $arr[$i]) + " " + (dump $arr[$i+1]) + " " + (dump $arr[$i+2])
$day += 1
}
The logonHours
attribute of a
user
object is represented as an
octet string, rather than a simple string like most of the other
attributes we’ve discussed. As a result, manipulating it directly is a
bit trickier than simply inserting a new string in place of an old
one. An octet string is just another name for an array of bytes
containing arbitrary binary data. For the logonHours
attribute, each hour of a day is
represented as a single bit within a byte. Each byte contains eight
(8) bits, so it takes three bytes to represent all of the hours in a
day. It goes from low-order to high-order (i.e., the low-order bit in
the lowest byte for a given day is midnight to 1:00 a.m.). The
information is stored in the logonHours
attribute in UTC and translated
by the user interface into local time. Finally, since there are seven
days in a week, and each day takes three bytes of information, the
attribute will have 21 elements.
In the PowerShell example, we pregenerate an array containing
the powers-of-2 contained with a byte and process each day as a
subarray of the entire attribute. Using the bitwise and
function in PowerShell allows us to map
binary values directly into array subscripts, which reduces the
complexity of the routine.
If an entry for the naming context you want to browse is not already displayed, do the following:
Right-click on ADSI Edit in the right pane and click “Connect to.”
Fill in the information for the naming context, container, or OU you want to add an object to. Click on the Advanced button if you need to enter alternate credentials.
In the left pane, browse to the naming context, container, or OU of the object you want to view. Once you’ve found the object, right-click on it and select Properties.
The managedObjects
attribute is
linked to the managedBy
attribute
that can be set on certain objects in Active Directory, such as
computers, OUs, and groups. Setting the managedBy
attribute provides a quick way to
define who owns an object. If you do use it, you can use the managedObjects
attribute on user, contact, or
group objects to get the list of objects for which the user has been
configured in the managedBy
attribute.
The UPN allows users to log on with a friendly name that may even correspond to their email address. UPN logons also do not require the domain to be known so that it can be abstracted away from the user. You may need to create an additional UPN suffix (e.g., @adatum.com) if you want UPNs to map to email addresses, but your AD forest is rooted at a different domain name (e.g., ad.adatum.com) from the domain name used in email addresses (e.g., treyresearch.com).
MS KB 243280 (Users Can Log On Using User Name or User Principal Name); “Add User Principal Name Suffixes”; MS KB 269441 (How to Use ADSI to List the UPN Suffixes that Are Defined in Active Directory)
You want to restore a user
object that has been inadvertently deleted.
This recipe assumes that the Active Directory Recycle Bin was enabled prior to the deletion. If you have not enabled the AD Recycle Bin, you can do so from the Tasks pane in the Active Directory Administrative Center.
In most cases, it is sufficient when restoring a deleted object
within Active Directory to simply perform an
authoritative restore of the individual object.
Performing this authoritative restore will allow the restored user
object to be replicated to other DCs
within the domain along with all attributes that were present at the
time that the System State backup was taken.
MS KB 216993 (Useful Shelf Life of a System-State Backup of Active Directory); MS KB 840001 (How to Restore Deleted User Accounts and Their Group Memberships in Active Directory); Chapter 16 for more on recovering and restoring Active Directory
You want to prevent a user
object from being accidentally deleted by an administrator who selects
the incorrect option in Active Directory Users and Computers.
Open Active Directory Users and Computers. Click on View and confirm that Advanced Features is selected.
Drill down to the current domain. To connect to a different domain, right-click on the top-level node and click “Change domain”; select the appropriate domain and then drill down to it.
Right-click on the object that you want to modify and click Properties.
Click on the Object tab.
Place a checkmark next to “Protect object from accidental deletion.”
By default, all new OUs that are created in Windows Server 2008 and later will have this protection enabled; however, no other object types are configured with this default protection. If you attempt to delete a group that is protected using this option, even when signed on as a Domain Admin or other similarly elevated account, you will receive an “Access Denied” message until you manually remove the checkbox or manually remove the deny ACE associated with it.
By using the command-line or PowerShell method, you can apply this protection to group objects in all versions of Windows Server, even though the GUI checkbox is available only in Windows Server 2008 and later.
3.15.29.146