This is a PowerShell version 2.0 script to check proposed values for user "pre-Windows 2000 logon name" in bulk. This is the value of the sAMAccountName attribute, sometimes referred to as the NT name of the user. Sometimes an organization decides to change their standard for naming users (or any class of objects). Note, this script only considers modifying the sAMAccountName, not the Relative Distinguished Name (the common name of users), which would require a rename.

If the changes are to made in bulk using a script, several issues must be addressed. This script is designed to check the new names and consider the following:

  1. sAMAccountNames must be unique in the domain. This uniqueness is not just among user objects, but all classes of objects that have the sAMAccountName attribute, such as groups and computers.
  2. The value (for users) must be no more than 20 characters in length.
  3. The attributes of the user upon which the new value will be based, such as the first name (givenName) and last name (sn), must have values (not be missing).
  4. The following characters are not allowed in sAMAccountNames: " [ ] : ; | = + * ? < > / \ ,
  5. The new sAMAccountName value should not have any leading spaces.

The last point is to avoid having a sAMAccountName that begins with a space character. This is allowed, but makes the object very difficult to find.

This script works best if you can create a function that will return the new value for sAMAccountName for each user. This function will have input parameters for any attribute values of the user object required to determine the new value. In the script here, the new sAMAccountName is based on the values assigned to the givenName and sn attributes of the user. In particular, the new sAMAccountName will be the first letter of the givenName, followed by a period (the "." character), followed by the last name. The function Get-Name1 is used for this purpose. As an alternative, another function, Get-Name2, is provided which constructs a new name from the first initial of the first name, the middle initial, and the last name. As you can imagine, either standard could easily result in duplicates, or even names longer than 20 characters. Also, there may be users with no first and/or last name assigned in Active Directory.

This script first retrieves all existing sAMAccountName values in the domain, regardless of the class of object. The Get-ADObject cmdlet is used for this. The hash table $Names is populated with these names. A hash table is very efficient for checking uniqueness. We know the initial values in the table are unique, because Active Directory requires it. This hash table will be used to check each of the new proposed names for uniqueness.

Next the script retrieves all users in the domain, using the Get-ADUser cmdlet. Then the script considers each user in turn and performs the checks described above.

If the new sAMAccountName value passes all of these checks, then the new value is added to the hash table to prevent duplicates. The script can be used to actually update the user object with the new value. If the user object is updated, any possible error is trapped, so the problem can be logged but the script can continue.

The script documents everything in a specified log file. There can be several lines for every user considered by the script. If updating the user raised an error, the corresponding line in the log file begins with the string "## Error:". This allows you to search for errors in the log file even if it is very large.

The script is designed to be run first without updating users, so you can check the log file for problems. You may be able to fix the problems. Or, you may need to adjust the Get-Name function to prevent the problems.

When a duplicate name is detected, the script adds the distinguished name of the user to an array. After all users have been processed, the script loops through the array of users that had conflicts and checks again to see if the new name is still a duplicate. At the same time, the script also considers 3 variations of the new name, with the digits "2", "3", and "4" appended. If any of these is available, it is used to update the user sAMAccountName. You might want to adjust this. When the script completes, it appends information similar to the following to the log file:

Finished: 10/17/2016 10:40:33 AM
New Name Truncated:                      5
Invalid Characters Removed:              7
                                    ------------
Users Can be Renamed:                  902
Users no Change Needed (Skipped):       16
Users with Missing Values (Skipped):    70
New Name not Unique (Skipped):          12
                                    ------------
Total Number of Users Processed:     1,000

You can search the log file for the labels in the following list to find details about the problems.

## OK:
## Error:
## Truncated:
## Invalid Characters Removed:
## Missing Values:
## Not Unique:
## Not Unique (Second Attempt):
## More Than 10 Errors

Suggested steps to use the script:

  1. Update the Get-Name function (Get-Name1 or Get-Name2 or your own function) to meet your needs.
  2. Modify the script to use your function, if it is not Get-Name1. The function is called in two places.
  3. Modify the Get-ADUser command (two places), if necessary, to retrieve the attributes needed by your Get-Name function.
  4. Add -SearchBase to the Get-ADUser cmdlets (two places) if you want to only consider users in an organizational unit.
  5. Run the script with $Update = $False.
  6. Check the log file for problems. The totals at the bottom of the log will show the number of problems. You can search the log for the labels in the table above for details.
  7. Modify user values (such as first and last names) or your Get-Name function if necessary to fix problems (if possible). Otherwise, the script will skip problems and you can deal with them manually.
  8. Rename the log file each time you run the script, or it will append to the same file.
  9. Run the script with $Update = $True to actually update the users.

CheckNTNames.txt <<-- Click here to view or download the program