NetTools Basics

NetTools has a number of common features which are used throughout the program. This post provides details on some of these features.

Where to start
The number of options in NetTools can make it confusing where to start.  The best approach is to start with the Search option under Users, this allows you to search the AD, be it at the Forest or Domain level for any object in the Active Directory, from there the context menu options allows you to then interrogate the returned objects.  See User Search.

Option or test Linking
For a number of the tests the output from one can be used as the input for other tests and options, by selecting the corresponding output entry and right clicking the context menu will display these options.  The Search option has a number of linking options that are displayed under the use with sub menu.

Copy and Paste
The outputs from the tests can be copied into other functions in NetTools or to external programs.  The Copy and Paste option are displayed in the right click context menus. For table views it's possible to copy the data in a single column, the line, or the entire table. When the copy column option is selected, mouse position when the right click is pressed is used to define which column will be selected.  For text based output fields it's possible to copy the text as with standard copy and pasting.  The Copy to new Window context menu option will copy the contains of the view to a new detached window, which provide additional sort and filtering options.  See Copy to new Windows

Server Lists
In most of the options there is a server or domain enter field, this is a dropdown list.  The right click context menu you save the current name and also manage the lists.  A separate list is used based on the enter field name, i.e. Server, Domain, LDAP filters etc.

Server and Domain Fields
The server and domain fields are optional, by default NetTools will use the domain information of the computer that is running NetTools.  By default the server name will use the name returned by the DsGetDcName API.  For the domain filed , the name of the domain that the machine running NetTools will be used.

By default NetTools will run in the context of the session that is running NetTools.  It's possible to use the RunAs option to use a different account with elevated permissions. Some of the option have an option to use the credentials that are provided in the LDAP Search option.  See Credentials

Messages\Results pane
On most options, there is a lower pane, this pane is used to display any errors or status report from the execution.

NetTools saved configuration
NetTools uses a single configuration file called NetTools.ini, this is used to save any user defined configuration or saved lists.  NetTools will try to read the configuration from the same location as the exe from executed from.

HowTo: Check that a user has actually changed their password

This is in response to a query raised on maillist about how to check if a user has actually changed their password and not just toggled the pwdlastset attribute to make it look like they have changed their password.   When a user changes their password a number of attributes are updated at a result of the password change, these include dbcspwd, lmpwdhistory, ntpwdhistory, pwdlastset, supplementalcredentials, and unicodepwd.  To be able to determine if the password has actually been changed, we have to look at the meta data for the object and check the last change date of the unicodepwd attribute, which contains the hash of the user’s password. 

NetTools provides a couple of ways to view the meta data of an object, via Meta data dialog, running an LDAP query, or in this use case the Last Logon, will display all the details required.

For a single user the Last Logon option will display both the pwdlastset and change date for the unicodepwd in the meta time column. This screenshot shows the results of a normal account password change, both the pwdlastset and meta time are the same.

For this user the pwdlastset has been toggled, and it shows that the pwdlastset and meta data times don't match

You can view the meta data on an object via the Meta Data Dialog, this option is provided throughout NetTools as a context menu option called Meta Data.  The easiest place to demonstrate this on the User Search option, search the account in question and then right click on the user and select Meta Data from the right click context menu.

This shows an account that has had it's password changed. 

This shows that the pwdlastset has changed but the other attributes have not changed, which is caused by the pwdlastset being toggled.

The above options are for single accounts, but it is also possible in to check multiple accounts at once.  The LDAP Search option includes an option to return meta data as if it's an attribute of the object.  This is done using the meta option in the attributes field.  We can use an Input Mode of the LDAP Search to provide a list of the samaccountnames to check.

In this example we are checking the details of the five user accounts, and it shows that user1 meta data doesn't match the pwdlastset date and time.

Here is the favorite for the above query, see Favorites on how to import 

[PwdLastSet Meta Data]
Attributes=meta.time.unicodepwd, pwdlastset

Related Articles
User Search
LDAP Search
LDAP Search Input Mode
Meta Data Dialog
Troubleshoot account lockouts

HowTo: Find Active Accounts

Finding which accounts are active should be simple, however, there are numerous ways to define if an account is active or not.  There is the simple method of checking if the accounts are enable or not, however, things get more complicated quickly after that, i.e. when was the account last used, has the account expired, has the account ever been used.

This article provides a number of sample LDAP queries that can be used to determine if accounts are active or not, or you can combine these queries to generate a more complex query to meet your requirements.  The first part of the article shows fragment of the query and the last section shows how to combine these to create the final query.

Account Enabled
With AD an account is active based on a value stored in UserAccountControl attribute, however, the attribute uses bit logic to represent a number of different values, so you can't check for a specific value.  Details of the attribute can be here. The second bit of the UserAccountControl indicates if the account is enabled or not,  when not set (0) the account is active, when set (2) the account is disabled.  Using Matching Rule OID we can check the status of the individual bits in the attribute.  i.e. (useraccountcontrol:1.2.840.113556.1.4.802:=2).  The NetTools substitutions simplifies the entry of matching rules with a single character. See Substitutions.

Account is disabled          (useraccountcontrol|=2)    
Account is enabled           (!useraccountcontrol|=2)

Account Expired
Accounts can be set to automatically expire after a specified date, after which point the user will no longer be able to logon.  The date is stored in the AccountExpires attribute, this attribute uses a 64 bit integer to store the date.  To add to the complexity the attribute can contain more than just a date, it might not be set, or contains a 0 (zero), or 9223372036854775807 then account is not set to expire.  So a query check for expiry has to check for all the possible values to confirm if the account is active or not. Again the use of substitutions can simplify the entry of the Int64 date. 

Account Expired            (&(!accountExpires={-1:})(!accountExpires=0)(accountExpires<={idate:now})) 
Account not Expired     (|(!accountExpires=*)(accountExpires={-1:})(accountExpires=0)(accountExpires>={idate:now}))  

Last Logon
Most account audits state that if an account has not been used to a set period of time, the account should be consider inactive.  The last time the user logs on is stored in the LastLogon attribute, however this attribute is not replicated between domain controllers, so using this attribute you have to collect the LastLogon attribute from all domain controllers to determine the last logon.  There is another attribute that is replicated between domain controllers called LastLogonTimeStamp, however this attribute has a specific replication cycle which means that it may not contain the most recent logon date (more details here), but is usually close enough for most cases.  Again this attribute uses a 64 bit integer to store the date.

Not logged on for 60 days        (lastlogontimestamp<={idate:now-60})
Logged on in the last 30 days   (lastlogontimestamp>={idate:now-30})

Password Changes
In some cases the logonTime or the LastLogonTimeStamp will not be updated when a users logs on, these are normally associated to LDAP Simple binds or access through SharePoint.  another method to determine if an account is still being used to check the last time the user's password was changed, this assumes that an account password expires.

Password change in the last 60 days     (pwdlastset>={idate:now-60})

Unused New Accounts
In this scenario an account is created but has not used since it was created.  The queries that is used to find these accounts depends on user provisioning process and which query should be used, if the user is required to change their password at first logon (scenario 1), or not (scenario 2).  If the user is required to change their password, then we check to see when the password was changed, if not, we check if the lastlogontimestamp has been set.

Scenario 1
Not used in the last 60 days            (&(whencreated>={zdate:now-60})(pwdlastset=0))
has been used in the last 60 days    (&(whencreated>={zdate:now-60})(pwdlastset>={idate:now-60}))

Scenario 2
Not used in the last 60 days                          (&(whencreated>={zdate:now-60})(!lastlogontimestamp=*))
Created in the last 60 days and been used    (&(whencreated>={zdate:now-60})(lastlogontimestamp=*))

Type of Accounts and indices
When creating queries it's best to create a query that limits the number of object that need to be searched and the number of attributes that are returned.  Building a query using attributes that are indexed will increase the performance of the query, reduce the load on the server executing the query, and reduce the amount of network traffic generated (See this Microsoft article for details). Some of the queries shown above use attributes that are not indexed, so using these queries in the format show could be very inefficient.  Limiting the queries to only search for specific object types will significantly increase the performance of the query, i.e only look at user account or computer accounts and the more indices that are used the better. 

Users account               (&(objectCategory=user)(&objectclass=user))
Computer Accounts      (&(objectCategory=computer)(&(objectclass=computer))

Combined Queries
This section shows a number of the above query fragments combination to create the full query:

Find active user accounts:

Find disabled user accounts

Find active accounts, that have not expired

Find all inactive accounts, including expired, password not changed or logon in the last 60 days
(&(objectCategory=user)(objectclass=user) (!useraccountcontrol|=2)(lastlogontimestamp<={idate:now-60})(pwdlastset>={idate:now-60})(&(!accountExpires={-1:})(!accountExpires=0)(accountExpires<={idate:now})))

See Favorites for more examples

Sites DC List

This option will display the list of Domain Controllers in the forest, and which sites that DCs are allocated.  Additional information is also provided, the default context for the DC, the FSMO roles installed, dns hostname, and IP address, if the Perform DC DNS resolution option is selected.

The FSMO Roles uses the following abbreviations:

G - Global Catalog
D - Domain Master
I - Infrastructure Master
P - PDC Master
R - RID Master
S - Schema Master

RID Pool

This option will display information about the current RID pool allocations in the selected domain, if no domain is specified, it will report on the domain of the computer running NetTools.  The current RID Master is displayed with the overall allocation size and the current RID pool allocation for each of the domain controllers in the domain.

RID Master


This is a simple logon test using the LogonUser API to test if a set of credentials are valid.  If the logon is successful then the account's groups and privileges are displayed.  There are number of options to select the type of logon to be performed, this can be used to confirm that user rights have been configured correctly on the local computer.

Logon - Groups
Logon - Privileges

User Rights

This option will display the the groups and privileges for the user context under which NetTools is running.  This information is retrieved from by calling GetTokenInformation against the current process, and then displays the contents of the access token.  The groups tab has all the groups in the access token, the Privileges tab contains all the rights that have been assigned to the current user.  There is an context menu option on the Privileges tab to request a privilege

The Attributes column has the following meaning:

M - Mandatory
ED - Enabled by Default
E - Enabled
O - Owner
ID - Logon ID
IE - Integrity Enabled
I - Integrity
L - Local Group
D - Deny Only

User Rights - Groups
User Rights - Privileges

UNC Check

The UNC Check option provides the ability to confirm accessibility of a UNC share.  The entered UNC is broken down into it's elements and each element is test separately and the results of each test is displayed.  The path of the UNC path is displayed and colour coded based on the results of the tests


Name Resolution
Ping IP Address
Portqry against Endpoint mapper port 135
Retrieve a complete list of shares
Check the share exists
Checks the permissions to read the share
then checks that the full path is accessible

UNC Check Passed
UNC Check - Failed path
UNC Check - Failed share
UNC Check - Shares


The NetGroupEnum option uses the API from the legacy Network Management API to display the groups and group membership.  This option uses the NetGroupEnum API to get the list of local groups on the specified server, and then by selecting the group, the members are then displayed.  This provide a quick method to check the local group membership on a local or remote server.

Token Size

This option shows an indicative number of SIDs that will be added to a user's or computer's access token when they authenticate against the the domain. The Base DN defined the start point for the search, if left blank, the entire directory is searched.  There are also a number of options that can be used to limit the items that are returned, by default only the the top 100 entries are displayed, however this can be changed.

Limiting the search to only Groups is a method to determine if there are any groups which have a high number of nested groups, which could impact the size of a user's access token if users are added to the group.

The size column is for reference only, this is the size of the data returned by TokenGroups attribute for the corresponding object, while it can be used as an indication of the resulting token size it is not exact, see the Microsoft article for the formula for calculating the token size.

The right click context menu provides a number of options to investigate the token size further, the Display SID Inheritance option allows you to drill down into the access token to see which items are causing the token bloat.

Background: Windows use a buffer to hold the user's access access token, the size of this buffer varies in size between different versions of Windows, see:  While you can increase the size of the token supported by the OS, there is no way to increase the maximum size supported by IIS prior to version 6.  User who is a member of 100+ groups thy may experience intermittent access to resources, over 300 they will have IIS\Sharepoint issues, over 1015 and the user will not be able to logon.  The use of SID History for migration or consolidations only makes the token size issue worse.  This is quite a good white paper on the issue