Problem

You want to configure forwarding to allow for name resolution outside of your corporate network.

Solution

Using a graphical user interface
  1. Open the DNS Management snap-in.

  2. Connect to the DNS Server you want to modify. In the left pane, right-click on DNS and select “Connect to DNS Server.” Select “The following computer” and enter the target server name. Click OK.

  3. Right-click on the server and select Properties.

  4. Click the Forwarders tab.

  5. To configure a global forwarder, make sure “All other DNS domains” is selected under DNS domain, type an IP under “Selected domain’s forwarder IP address list,” click Add, and then click Apply.

  6. To configure a conditional forwarder for a specific domain, click the New button.

  7. Enter the domain name and click OK.

  8. Add IPs as described for global forwarders in Step 5.

  9. From the Forwarders tab, you can also set the number of seconds that the server waits before forward queries time out. You can also disable the use of recursion for certain domains. Both of these can be set on a per-domain basis.

Using a command-line interface

The following command sets the default forwarders. Replace <IPsOfForwarders> with a space-separated list of IP addresses for the nameservers to forward requests to.

	>  
dnscmd <ServerName> /resetforwarders <IPsOfForwaders>

For example:

	> dnscmd dns01 /resetforwarders 10.22.3.4 10.22.3.5

The following command creates a domain-based forwarder:

	> dnscmd <ServerName> /zoneadd <DomainName> /forwarder <IPsOfForwarders>

The following command configures the default forwarder timeout:

	> dnscmd <ServerName> /config / 
forwardingtimeout <NumSeconds>

The following command configures the forwarder timeout for a specific domain:

	> dnscmd <ServerName> /config <DomainName> /forwardertimeout <NumSeconds>

Using VBScript
	' This code enumerates the default forwarders.
	' ------ SCRIPT CONFIGURATION ------
	strServer = "<ServerName> " ' e.g. dns1.rallencorp.com
	' ------ END CONFIGURATION --------

	set objDNS = GetObject("winMgmts:\\" & strServer & "\root\MicrosoftDNS")
	set objDNSServer = objDNS.Get("MicrosoftDNS_Server.Name="".""")
	for each strForwarder in objDNSServer.Forwarders
	   Wscript.Echo strForwarder
	Next

	' This code sets the default forwarders.
	' ------ SCRIPT CONFIGURATION ------
	strServer = "<ServerName>" ' e.g. dns1.rallencorp.com
	arrForwarders = Array("<IP1>","<IP2>")
	' ------ END CONFIGURATION --------

	set objDNS = GetObject("winMgmts:\\" & strServer & "\root\MicrosoftDNS")
	set objDNSServer = objDNS.Get("MicrosoftDNS_Server.Name="".""")
	objDNSServer.Forwarders = arrForwarders
	objDNSServer.Put_
	Wscript.Echo "Successfully set default forwarders"
	' This code sets the  
forwarders for a specific domain.
	' ------ SCRIPT CONFIGURATION ------
	strServer = "<ServerName>" ' e.g.  
dns01
	strNewZone = "<ZoneName>"  ' e.g. othercorp.com
	arrMasterIPs = Array("<IP1>","<IP2>") ' replace <IPx> with IPs of master server
	' ------ END CONFIGURATION --------
	on error resume next
	set objDNS = GetObject("winMgmts:\\" & strServer & "\root\MicrosoftDNS")
	set objDNSZone = objDNS.Get("MicrosoftDNS_Zone")
	strNull = objDNSZone.CreateZone(strNewZone,3,false,"",arrMasterIPs)
	if Err then
	   WScript.Echo "Error occurred creating zone: " & Err.Description
	else
	   WScript.Echo "Domain forwarder created."
	end if

Discussion

Nameservers have long supported the notion of forwarders. Rather than sending all unresolved queries to the root Internet nameservers, you can use forwarders to send queries to a specific server or set of servers, perhaps hosted by your ISP or by a partner corporation. This allows you to better control the name resolution process on your network.

Microsoft has extended this capability in Windows Server 2003 to support conditional forwarding. With conditional forwarding, you can forward unresolved queries for specific domains to different nameservers. The most common use of conditional forwarding is when you have two or more noncontiguous namespaces. Consider, for example, a merger between the rallencorp.com and othercorp.com corporations. Normally, for the nameservers of rallencorp.com to resolve queries for othercorp.com, the queries would have to first be forwarded to the root Internet nameservers. With conditional forwarding, you can configure the rallencorp.com DNS servers so that all requests for othercorp.com should be sent directly to the othercorp.com nameservers and all other unresolved queries should be sent to the Internet, and vice versa. The trade-off for this feature is the additional CPU processing that’s necessary to examine each query and forward it to the appropriate server, rather than just funneling all unresolved queries to a single external server.


Problem

You want to enable zone transfers to specific secondary nameservers.

Solution

Using a graphical user interface

  1. Open the DNS snap-in.
  2. In the left pane, expand the server node and expand either Forward Lookup Zone or Reverse Lookup Zone depending on the type of zone you want to manage.
  3. Right-click on the zone and select Properties.
  4. Select the Zone Transfers tab.
  5. Select either the option to restrict zone transfers to those servers listed on the Name Servers tab or the option to restrict zone transfers to specific IP addresses. See the “Discussion” section for more on these two options.

Using a command-line interface

The following command enables zone transfers for the test.local zone and specifies they can only occur with servers that have NS records in the zone (i.e., servers listed within the Name Servers tab of the DNS snap-in):

> dnscmd <ServerName> /ZoneResetSecondaries test.local /SecureNs

The next command enables zone transfers for same zone, but specifies they can only occur with hosts whose IP addresses are 172.16.22.33 and 172.16.22.34:

> dnscmd <ServerName> /ZoneResetSecondaries test.local /SecureList 172.16.22.33

172.16.22.34

Using VBScript

‘ This code creates a nameserver (NS) record on a DNS server.

strDNSServer = “<servername>

strContainer = “<containername>

strOwner = “<ownername>

intRecordClass = 1

intTTL = 600

strNSHost = “<nameservername>

strComputer = “.”

set objWMIService = GetObject _

(“winmgmts:\\” & strComputer & “\root\MicrosoftDNS”)

set objItem = objWMIService.Get(“MicrosoftDNS_NSType”)

errResult = objItem.CreateInstanceFromPropertyData _

(strDNSServer, strContainer, strOwner, intRecordClass, intTTL, strNSHost)

‘ This code configures the allowed secondaries for zone transfer and notify

‘ XFR constants

const ZONE_SECSECURE_NO_SECURITY = 0

const ZONE_SECSECURE_NS_ONLY = 1

const ZONE_SECSECURE_LIST_ONLY = 2

const ZONE_SECSECURE_NO_XFR = 3

‘ NOTIFY constants

const ZONE_NOTIFY_OFF = 0

const ZONE_NOTIFY_ALL_SECONDARIES = 1

const ZONE_NOTIFY_LIST_ONLY = 2

‘ —— SCRIPT CONFIGURATION ——-

strZone = “<ZoneName>” ‘ e.g. rallencorp.com

strServer = “<ServerName>” ‘ e.g. dc1.rallencorp.com

‘ use one of the above XFR constants

intSecureSecondaries = ZONE_SECSECURE_LIST_ONLY

arrSecondaries = Array(“1.1.1.2″,”1.1.1.3”)

‘ use one of the above NOTIFY constants

intNotify = ZONE_NOTIFY_LIST_ONLY

arrNotify = Array(“<IP1>“,”<IP2>“)

‘ —— END CONFIGURATION ———

set objDNS = GetObject(“winMgmts:\\” & strServer & “\root\MicrosoftDNS”)

set objDNSServer = objDNS.Get(“MicrosoftDNS_Server.Name=””.”””)

set objDNSZone = objDNS.Get(“MicrosoftDNS_Zone.ContainerName=””” & _

strZone & “””,DnsServerName=””” & _

objDNSServer.Name & “””,Name=””” & strZone & “”””)

strNull = objDNSZone.ResetSecondaries(arrSecondaries,intSecureSecondaries, _

arrNotify,intNotify)

objDNSZone.Put_

WScript.Echo “Updated secondaries for zone transfer and notify”

Discussion

Depending on your environment, your DNS implementation may require that you create secondary zones to allow for load balancing for busy DNS servers or remote sites connected by slow links. In this situation, you want to allow zone transfers to occur between your AD-integrated DNS servers and your secondary servers, but you want to restrict which hosts can initiate zone transfers with your AD-integrated nameservers. Allowing anyone to initiate a zone transfer with your domain controllers could provide an attacker with information for mapping out your network; it is therefore critical that you limit which hosts can pull zone transfers from your servers.

If you are using only Active Directoryintegrated zones, the Name Servers tab will be automatically populated with a list of all nameservers that are authoritative for the selected zone, and this is the recommended choice when you have a large network with many nameservers deployed. If any of your nameservers are using standard zone files, however, you will need to populate this tab manually for any secondary nameservers you deploy.

Specifying a list of IP addresses for hosts that can initiate zone transfers may be more secure since it is more specific, but this approach has the trade-off of adding the additional management overhead of keeping track of the IP addresses of all nameservers on your network, so you should follow this approach only if your network is small and you have relatively few nameservers deployed. Another disadvantage of this approach is that if you forget to add some IP addresses of nameservers to your list, zone information stored on those servers could become stale, causing name resolution to fail for some of your clients. This could result in some of your users experiencing difficulties in accessing network resources.

Note that on Windows 2000 nameservers, the default setting is to allow zone transfers with any host that requests them. This setting is inherently insecure as it allows attackers to use nslookup to display all resource records on your servers, so be sure to use the steps outlined in this recipe to change the setting on your servers to one of the two settings described here. Windows Server 2003 DNS is more secure by default because in the case of file-based zones, it is configured to allow zone transfers only with servers listed on the Name Servers tab of a zone. In the case of Active Directoryintegrated zones, it is configured to disallow zone transfers entirely since they generally aren’t needed in an Active Directory environment.


Problem

You want to convert a standard primary zone to an AD-integrated zone. This causes the contents of the zone to be stored and replicated in Active Directory instead of in a text file on the local server.

Solution

Using a graphical user interface

  1. Open the DNS Management snap-in.
  2. Right-click on DNS in the left pane and select “Connect to DNS Server.”
  3. Enter the server you want to connect to and click Enter.
  4. If you want to convert a forward zone, expand the Forward Lookup Zone folder. If you want to convert a reverse zone, expand the Reverse Lookup Zone folder.
  5. Right-click on the zone you want to convert and select Properties.
  6. Beside Type, click the Change button.
  7. Check the box beside “Store the zone in Active Directory.”
  8. Click OK twice.

Using a command-line interface

> dnscmd <ServerName> /zoneresettype <ZoneName> /DsPrimary

Using VBScript

‘ This code converts a zone to AD-integrated.

‘ —— SCRIPT CONFIGURATION ——

strZone = “<ZoneName>”     ‘ e.g. rallencorp.com

strServer = “<ServerName>” ‘ e.g. dc1.rallencorp.com

‘ —— END CONFIGURATION ——–

set objDNS = GetObject(“winMgmts:\\” & strServer & “\root\MicrosoftDNS”)

set objDNSServer = objDNS.Get(“MicrosoftDNS_Server.Name=””.”””)

set objDNSZone = objDNS.Get(“MicrosoftDNS_Zone.ContainerName=””” & _

strZone & “””,DnsServerName=””” & _

objDNSServer.Name & “””,Name=””” & strZone & “”””)

strNull = objDNSZone.ChangeZoneType(0, True)

objDNSZone.Put_

WScript.Echo “Converted ” & strZone & ” to

AD-Integrated”

Problem

You want to view the zones on a server.

Solution

Using a graphical user interface

  1. Open the DNS Management snap-in.
  2. Right-click on DNS in the left pane and select “Connect to DNS Server.”
  3. Enter the server you want to connect to and click Enter.
  4. In the left pane, expand the server and click Forward Lookup Zones and Reverse Lookup Zones to view the hosted zones.

Using a command-line interface

> dnscmd <DNSServerName> /enumzones

Using VBScript

‘ This code lists the zones that are hosted by the specified server.

‘ —— SCRIPT CONFIGURATION ——

strServer = “<DNSServerName>” ‘ e.g. dc1.rallencorp.com

‘ —— END CONFIGURATION ——–

set objDNS = GetObject(“winMgmts:\\” & strServer & “\root\MicrosoftDNS”)

set objDNSServer = objDNS.Get(“MicrosoftDNS_Server.Name=””.”””)

set objZones = objDNS.ExecQuery(“Select * from MicrosoftDNS_Zone ” & _

“Where DnsServerName = ‘” & _

objDNSServer.Name & “‘”)

WScript.Echo “Zones on ” & objDNSServer.Name

for each objZone in objZones

WScript.Echo ” ” & objZOne.Name

next

Discussion

Using a graphical user interface

When you click on either the Forward Lookup Zones or Reverse Lookup Zones in the lefthand pane of the DMS MMC, the right pane contains a Type column that displays the zone type for each zone.

Using a command-line interface

When using the /enumzones switch without any more parameters, it displays all zones on the server. You can specify additional filters that limit the types of zones returned. With the Windows 2000 version of dnscmd, you can specify up to two filters (for example, using the /enumzones / primary / forward switch combination will display all primary forward zones on the server):

Filter1:

/Primary

/Secondary

/Cache

/Auto-Created

Filter2:

/Forward

/Reverse

With the Windows Server 2003 version of dnscmd, the filter behavior has changed. Instead of having two levels of criteria, you can specify one or more of the following:

/Primary

Lists both standard and Active Directoryintegrated primary zones

/Secondary

Lists all standard secondary zones

/Forwarder

Lists all zones that forward unresolvable queries to another DNS server

/Stub

Lists all stub zones hosted on a server

/Cache

Lists zones that are loaded into cache on the server

/Auto-Created

Lists zones that were created automatically during the DNS server installation

/Forward

Lists all forward lookup zones

/Reverse

Lists all reverse lookup zones

/Ds

Lists all Active Directoryintegrated zones

/File

Lists zones that are stored in text files

/DomainDirectoryPartition

Lists zones that are stored in the DomainDNSZones partition

/ForestDirectoryPartition

Lists zones that are stored in the ForestDNSZones partition

/CustomDirectoryPartition

Lists zones that are stored in a user-created directory partition

/LegacyDirectoryPartition

Lists zones that are stored in the domain NC

/DirectoryPartition <PartitionName>

Lists zones that are stored in a particular application partition

Using VBScript

A WQL query was used to find all MicrosoftDNS_Zone objects. You can add additional criteria to the WQL Select statement to return a subset of zones supported on the server.

Creating a Reverse Lookup Zone

Problem

You want to create a reverse lookup zone. A reverse lookup zone maps IP addresses to names.

Solution

Using a graphical user interface

  1. Open the DNS Management snap-in.
  2. If an entry for the DNS server you want to connect to does not exist, right-click on DNS in the left pane and select “Connect to DNS Server.” Select “This computer” or “The following computer,” then enter the server you want to connect to (if applicable) and click OK.
  3. Expand the server in the left pane and click on Reverse Lookup Zones.
  4. Right-click on Reverse Lookup Zones and select New Zone.
  5. Click Next.
  6. Select the zone type (Primary, Secondary, or Stub zone). To AD-integrate the zone, place a check mark next to “Store the zone in Active Directory (available only if DNS server is a domain controller)” and click Next.
  7. If you selected to store the zone data in Active Directory, next you will be asked which servers you want to replicate the DNS data to: all DNS servers in the forest, all DNS servers in the domain, all domain controllers in the domain, or all DCs that are hosting a particular application partition. Click Next after you make your selection.
Step 7 applies only to DNS servers that are installed on Windows Server 2003 domain controllers. If you still have Windows 2000 DNS servers in your environment, choose the option of replicate the zone to all domain controllers in your domain.
  1. Type the Network ID for the reverse zone or enter a reverse zone name to use.
  2. Fill out the information for the remaining screens. They will vary depending on if you are creating a primary, secondary, or stub zone.

Using a command-line interface

The following command creates an AD-integrated reverse zone:

> dnscmd <DNSServerName> /zoneadd <ZoneName> /DsPrimary

Using VBScript

‘ This code creates an

AD-integrated reverse zone.

‘ —— SCRIPT CONFIGURATION ——

strServer = “<DNSServerName>” ‘ e.g. dc1.rallencorp.com

strNewZone = “<ZoneName>” ‘ e.g. 8.10.192.in-addr.arpa.

‘ —— END CONFIGURATION ——–

set objDNS = GetObject(“winMgmts:\\” & strServer & “\root\MicrosoftDNS”)

set objDNSZone = objDNS.Get(“MicrosoftDNS_Zone”)

strNull = objDNSZone.CreateZone(strNewZone, 0 , True)

WScript.Echo “Created zone ” & strNewZone

Discussion

Creating a reverse zone is very similar to creating a forward zone.

Creating a Forward Lookup Zone

Problem

You want to create a forward lookup zone. A forward lookup zone maps FQDNs to IP addresses or other names.

Solution

Using a graphical user interface

  1. Open the DNS Management snap-in.
  2. If an entry for the DNS server you want to connect to do not exist, right-click on DNS in the left pane and select “Connect to DNS Server.” Select “This computer” or “The following computer,” enter the server you want to connect to (if applicable), and click OK.
  3. Expand the server in the left pane and click on Forward Lookup Zones.
  4. Right-click on Forward Lookup Zones and select New Zone.
  5. Click Next.
  6. Select the zone type and click Next.
  7. If you selected to store the zone data in Active Directory, next you will be asked which servers you want to replicate the DNS data to. Click Next after you make your selection.
Step 7 applies only to DNS servers that are installed on Windows Server 2003 domain controllers. If you still have Windows 2000 DNS servers in your environment, choose the option to replicate the zone to all domain controllers in your domain.
  1. Enter the zone name and click Next.
  2. Fill out the information for the remaining screens. They will vary depending on whether you are creating a primary, secondary, or stub zone.

Using a command-line interface

The following command creates an AD-integrated zone:

> dnscmd <DNSServerName> /zoneadd <ZoneName> /DsPrimary

Using VBScript

‘ This code creates an AD-integrated forward zone.

‘ —— SCRIPT CONFIGURATION ——

strServer = “<DNSServerName>” ‘ e.g. dc1.rallencorp.com

strNewZone = “<ZoneName>”     ‘ e.g. othercorp.com

‘ —— END CONFIGURATION ——–

set objDNS = GetObject(“winMgmts:\\” & strServer & “\root\MicrosoftDNS”)

set objDNSZone = objDNS.Get(“MicrosoftDNS_Zone”)

strNull = objDNSZone.CreateZone(strNewZone, 0 , True)

WScript.Echo “Created zone ” & strNewZone

Discussion

Using a command-line interface

When you create an AD-integrated zone with the /DsPrimary switch, you can additionally include a /dp switch and specify an application partition to add the zone to. Here is an example:

> dnscmd /zoneadd <ZoneName> /DsPrimary /dp domaindnszones.rallencorp.com

Using VBScript

The DNS WMI Provider is Microsoft’s first comprehensive DNS API. You can create and modify zones, query and manage resource records, and manipulate DNS server configuration. In the VBScript solution, the CreateZone method of the MicrosoftDNS_Zone class was used to create the forward zone. The DNS WMI Provider is available only for Windows Server 2003 DNS; it cannot be used on Windows 2000 DNS servers.


Problem

You want to view the objects that are owned by a user.

Solution

Using a graphical user interface

  1. Open ADSI Edit.
  2. If an entry for the naming context you want to browse is not already displayed, do the following:
    1. Right-click on ADSI Edit in the right pane and click “Connect to….”
    2. 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.
  3. 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.
  4. View the managedObjects attribute.

Using a command-line interface

> adfind b “<UserDN>” managedObjects

Using VBScript

‘ This code displays the

managed objects for a user

‘ —— SCRIPT CONFIGURATION ——

strUserDN = “<UserDN>” ‘ e.g. cn=jsmith,cn=Users,dc=rallencorp,dc=com

‘ —— END CONFIGURATION ———

on error resume next

set objUser = GetObject(“LDAP://” & strUserDN)

Wscript.Echo objUser.Get(“cn”) & “‘s

Managed Objects:”

colObjects = objUser.GetEx(“managedObjects”)

if Err.Number = -2147463155 then

Wscript.Echo ” none”

else

for each strObjectDN in colObjects

Wscript.Echo ” ” & strObjectDN

next

end if

Discussion

The managedObjects attribute is linked to the managedBy attribute that can be set on certain objects in Active Directory like 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.


Problem

You want to see the hours that a user is permitted to log onto the network.

Solution

Using a graphical user interface

  1. Open the ADUC snap-in.
  2. 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.
  3. Right-click on the user and select Properties. From the Account tab, click on Logon Hours.
  4. Select the hours that you want to allow or disallow, and click Logon Permitted or Logon Denied. Click OK.
  5. Click Apply, followed by OK.

Using VBScript

Days = Array _

(“Sunday”, “Monday”, “Tuesday”, “Wednesday”, “Thursday”, “Friday”, “Saturday”)

Set objUser = GetObject(“LDAP://<UserDN>“)

arrHours = objUser.Get(”

logonHours”)

For i = 1 To LenB(arrHours)

arrHoursBytes(i-1) = AscB(MidB(arrHours, i, 1))

WScript.Echo “MidB returns: ” & MidB(arrHours, i, 1)

WScript.Echo “arrHoursBytes: ” & arrHoursBytes(i-1)

wscript.echo vbcrlf

Next

intCounter = 0

intLoopCounter = 0

WScript.echo “Day Byte 1 Byte 2 Byte 3”

For Each HourByte In arrHoursBytes

arrHourBits = DisplayLogonHourBits(HourByte)

If intCounter = 0 Then

WScript.STDOUT.Write Days(intLoopCounter) & Space(2)

intLoopCounter = intLoopCounter + 1

End If

For Each HourBit In arrHourBits

WScript.STDOUT.Write HourBit

intCounter = 1 + intCounter

If intCounter = 8 or intCounter = 16 Then

Wscript.STDOUT.Write Space(1)

End If

If intCounter = 24 Then

WScript.echo vbCr

intCounter = 0

End If

Next

Next

Function DisplayLogonHourBits(x)

Dim arrBits(7)

For i = 7 to 0 Step -1

If x And 2^i Then

arrBits(i) = 1

Else

arrBits(i) = 0

End If

Next

DisplayLogonHourBits = arrBits

End Function

Discussion

Using VBScript

The logonHours attribute of a user object is represented as a binary number, rather than a simple string like most of the other attributes we’ve discussed. Because of this, manipulating it directly is a bit trickier than simply inserting a new string in place of an old one. In the VBScript example shown in this recipe, we use a VBScript function that manipulates the various bits of the attribute to produce the correct values.

This recipe requires the Windows Server 2003 forest functional level.

Problem

You want to determine the last time a user logged into a domain.

Solution

Using a graphical user interface

If you install the AcctInfo.dll extension to ADUC, you can view the last logon timestamp:

  1. Open the ADUC snap-in.
  2. In the left pane, right-click on the domain and select Find.
  3. Select the appropriate domain beside In.
  4. Beside Name, type the name of the user you want to modify and click Find Now.
  5. In the Search Results window, double-click on the user.
  6. Click the Additional Account Info tab.
  7. View the value for Last-Logon-Timestamp.
AcctInfo.dll can be downloaded from the Microsoft download site as a part of the Account Lockout and Management Tools:

http://microsoft.com/downloads/details.aspx?FamilyId=7AF2E69C-91F3-4E63-8629-B999ADDE0B9E&displaylang=en

Discussion

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 much. 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.

Now with Windows Server 2003 there is finally a viable solution. A new attribute was added to the schema for user objects called lastLogonTimestamp.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 that logged in repeatedly over a short period of time did not cause unnecessary replication traffic. For this reason, the lastLogonTimestamp is updated only if the last update occurred a week or more ago by default.(This window is configurable by modifying the msDS-LogonTimeSyncInterval on the domain NC.) This means that the lastLogonTimestamp attribute could be up to 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.


Problem

You want a user’s account to expire at some point in the future.

Solution

Using a graphical user interface

  1. Open the ADUC snap-in.
  2. In the left pane, right-click on the domain and select Find.
  3. Select the appropriate domain beside In.
  4. Beside Name, type the name of the user you want to modify and click Find Now.
  5. In the Search Results window, double-click on the user.
  6. Click the Account tab.
  7. Under Account expires, select the radio button beside End of.
  8. Select the date the account should expire.
  9. Click OK.

Using a command-line interface

Valid values for the -acctexpires flag include a positive number of days in the future when the account should expire, to expire the account at the end of the day, or to never expire the account.

> dsmod user “<UserDN>” -acctexpires <NumDays>

Using VBScript

‘ This code sets the

account expiration date for a user.

‘ —— SCRIPT CONFIGURATION ——

strExpireDate = “<Date>” ‘ e.g. “07/10/2004”

strUserDN = “<UserDN>” ‘ e.g. cn=rallen,ou=Sales,dc=rallencorp,dc=com

‘ —— END CONFIGURATION ——–

set objUser = GetObject(“LDAP://” & strUserDN)

objUser.AccountExpirationDate = strExpireDate

objUser.SetInfo

WScript.Echo “Set user ” & strUserDN & ” to expire on ” & strExpireDate

‘ These two lines would disable

account expiration for the user

‘ objUser.Put ”

accountExpires”, 0

‘ objUser.SetInfo

Discussion

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 in 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 than the dsmod user command where a value of 0 with -acctexpires will cause the account to expire at the end of the day. Why does it differ from how the accountExpires attribute works? Great question. The accountExpires attribute itself will be updated whenever the existing expiration date passes.