7

I am a programmer with an application that needs to be integrated into the new company wide Active Directory login scheme. This means changing all the usernames in our system to use the new scheme. The new scheme is "first initial, last name", so Joe Smith would have a username of jsmith. If John Smith now gets hired, he'll get jsmith2. BUT as soon as Joe leaves the company, his AD account is deleted, and jsmith is available again. So if Jill Smith now is hired, she would get jsmith. From an applications standpoint this causes problems in my view, because I could now have records relating to Joe and records relating to Jill that are indistinguishable, because they were both created by "jsmith".

I am therefore left to wonder if there is a standard or best practice that addresses this issue of reusing usernames in an organization wide directory, especially in larger companies. When bringing up my concerns at a meeting I was told that "there's no way [big company name] still has a record of every user that's left the company", and that struck me as crazy. So, is there a generally accepted solution to handling usernames? Or does every company make it up as they go?

Peter
  • 396

8 Answers8

7

Windows copes with this by using a GUID to identify every account. The username is just decoration. You'll find that the old jsmith and new jsmith have different GUIDs even though the usernames are the same.

Can you associate a GUID with each account in your app? If I think about it I can probably tell you how to get at the GUID for a user. It will be an attribute of the user in active directory.

JR

John Rennie
  • 7,806
5

Yes we keep every user ever hired. I usually reccommend a first initial,middle initial,lastname to minimize the number of JQPublic1 accounts but it happens, however from an AD perspective users are just numbers. You can see the number for any account with this script:

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set objAccount = objWMIService.Get ("Win32_UserAccount.Name='myusername',Domain='mydomain'")
Wscript.Echo objAccount.SID

as a free bonus here's how to turn a sid into a username:

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set objAccount = objWMIService.Get ("Win32_SID.SID='S-1-5-21-1454471165-1004336348-1606980848-5555'")
Wscript.Echo objAccount.AccountName
Wscript.Echo objAccount.ReferencedDomainName
Jim B
  • 24,276
3

As others have mentioned, using the GUID attribute of the user's Active Directory account is a great idea. If you want human-readability, though, you should have a look at the docs for the iADsNameTranslate interface. You can get a lot of mileage out of it for dealing translating the various possible names of an AD account (GUID, SID, samAccountName, displayName, DN, etc).

Example:

Option Explicit

' Constants for the iADsNameTranslate object. (from http://msdn.microsoft.com/en-us/library/aa772267(VS.85).aspx)
Const ADS_NAME_TYPE_NT4 = 3
Const ADS_NAME_TYPE_GUID = 7

Const ADS_NAME_INITTYPE_GC = 3

Dim objNameTranslate 
Dim strUserGUID

' Create a nametranslate object and init to talk to a global catalog server
Set objNameTranslate = CreateObject("NameTranslate")
objNameTranslate.Init ADS_NAME_INITTYPE_GC, ""

' We're looking for an "NT 4" account name type-- aka a samAccountName
objNameTranslate.Set ADS_NAME_TYPE_NT4, "DOMAIN\username"

' Translate into the user's GUID
strUserGUID = objNameTranslate.Get(ADS_NAME_TYPE_GUID)

WScript.Echo strUserGUID

This isn't just for user accounts. Every object in AD has a GUID, so if you need to "remember" a DN for, say, an LDAP search base (or a group, or anything) you can use the GUID such that if it gets moved around in AD (think about some admin going off and re-organizing OU's, or renaming groups) your "pointer" to it won't break (because the GUID never changes).

Evan Anderson
  • 142,957
1

There are several naming attributes in Active Directory:

  • sAMAccountName: This is the up to 20 character name that must be unique within the Domain but not within the forest.
  • userPrinicipalName: This is usually in the form of sAMAccountName@domain.name and I believe needs to be unique within the forest, but since the first part is unique within the domain, then @domain.name that should just happen.
  • displayName: What you see in ADUC MMC when you look at users.
  • DN: The actual LDAP DN of the user in the AD tree. This is how you would identify the user from an LDAP perspective, usually.

DN is a bad one to key off of, since it will change if the user is moved or renamed. Sane is possible for userPrincipalName/sAMAccountName (if they get renamed).

As another poster suggested, the really truly unique attribute of users is probably GUID, and is not nice and human readable, alas.

geoffc
  • 2,185
1

GUID is definitely the way to go. If you really need to present the person's name in a human-friendly format just do an AD lookup in code.

0

Other have already posted script snippets and you'll find plenty of code snippets, for a variety of languages at the usual coding sites. Try searching those for things like "user to guid", "user to id", etc.

0

IMO, good practice is to never delete accounts, just disable them. that way they can't be re-used.

cas
  • 6,841
0

Peter, my own experience with this is - don't expect the username to be unique, unless you have a way to guarantee username uniqueness. As you say, it never really works out.

The app, whatever it is, needs to use other relevant data to determine what makes the user unique within the context of whatever the app is doing. If you're doing an app to generate mail flyers, for instance, you probably don't want to send more than one flyer per unique postal address.

quux
  • 5,388