Hey, Scripting Guy! How can I get the GUID for a user account if all I know is the user’s logon name and domain?
— IU
Hey, IU. You know, one of the great things about the Scripting Guy who writes this column is – well, OK, right off the top of our head we can’t think of any great things about the Scripting Guy who writes this column. (Although, no doubt the Scripting Editor will chime in with a list of great things. Scripting Editor, you there?)
Nevertheless, the Scripting Guy who writes this column is pretty good at looking past outward appearances and getting right to the heart of a problem (admittedly, that’s due in large part to the fact that he typically is the heart of a problem). When you get right down to it, IU, you have a translation problem: you’re sitting there with a Windows NT-style domain name (e.g., fabrikam\kenmyer), and you need to translate that to a user GUID (e.g., {97614339-087d-4f26-9fc5-86e8e7425ce7}. So here’s a question for you: what do you need any time you have to translate something? That’s exactly right: you need a translator.
Note. You know, it’s amazing insights such as that one – in order to translate something you need a translator – that make this column what it is. It is hard to believe that we give this stuff away for free, isn’t it? |
Of course, there’s just one problem here: there’s simply now way to translate an NT 4 domain name to a GUID. No way at all.
Or is there? Take a peek at this:
Const ADS_NAME_INITTYPE_GC = 3 Const ADS_NAME_TYPE_NT4 = 3 Const ADS_NAME_TYPE_GUID = 7strUserName = “fabrikam\kenmyer”
Set objTranslator = CreateObject(“NameTranslate”)
objTranslator.Init ADS_NAME_INITTYPE_GC, “” objTranslator.Set ADS_NAME_TYPE_NT4, strUserName
strUserGUID = objTranslator.Get(ADS_NAME_TYPE_GUID)
Wscript.Echo strUserGUID
We have to admit that this was actually kind of a fun little script to write; that’s because it gave us a chance to use the IADsNameTranslate utility, an ADSI interface that’s built right into the operating system. As the name implies, the IADsNameTranslate interface can translate many of the different name types used in Active Directory. For example, give IADsNameTranslate a distinguished name and it can give you back a display name. Give IADsNameTranslate a canonical name and it can give you back a UPN name. Give IADsNameTranslate a Windows NT 4 domain name and it can give you back a GUID.
Or so we hope, anyway. Let’s find out.
Our script begins by defining three constants:
• |
ADS_NAME_INITTYPE_GC (with a value of 3) tells the script that we want to look up name information by contacting a global catalog server. |
• |
ADS_NAME_TYPE_NT4 (also with a value of 3) is used to specify an NT 4 domain name. |
• |
ADS_NAME_TYPE_GUID (with a value of 7) is used to specify an Active Directory GUID. |
After defining the constants we next assign the user name to a variable named strUserName, taking care to use the NT 4 domain naming convention domain\user name:
strUserName = “fabrikam\kenmyer”
Now we’re ready to roll. For starters we create an instance of the NameTranslate object, the ProgID for the IADsNameTranslate interface. We then call the Init method to bind us to Active Directory; in this case, Init binds us to a global catalog server because we passed the constant ADS_NAME_INITTYPE_GC as the method parameter. (Note, too, that we also passed an empty string as the second parameter. This second parameter gives you an opportunity to specify a computer or domain name. We don’t need to do that when we contact a global catalog server, but we do need to pass an empty string as this “optional” parameter. If we don’t, the script will fail.)
Incidentally, here’s what our call to the Init method looks like:
objTranslator.Init ADS_NAME_INITTYPE_GC, “”
And here’s what our call to the Set method looks like:
objTranslator.Set ADS_NAME_TYPE_NT4, strUserName
As you can see, we pass Set two parameters: the type of Active Directory name to be translated (represented by the constant ADS_NAME_TYPE_NT4) and the name itself (represented by the variable strUserName). After calling the Set method we then call the Get method. And what is it we want to get? That’s easy: we want to get the user’s GUID, something we indicate by passing the constant ADS_NAME_TYPE_GUID. The NameTranslate object will grab the GUID and stash it in a variable named strUserGUID:
strUserGUID = objTranslator.Get(ADS_NAME_TYPE_GUID)
So is that really going to work? Of course it is; here’s what we see when we echo back the value of strUserGUID:
{97614339-087d-4f26-9fc5-86e8e7425ce7}
Pretty cool, huh?
Like we said, there are other name formats you can work with as well, including the following:
Constant |
Value |
Description |
ADS_NAME_TYPE_1779 |
1 |
Name format as specified in RFC 1779. For example, “CN=Jeff Smith,CN=users,DC=Fabrikam,DC=com”. |
ADS_NAME_TYPE_CANONICAL |
2 |
Canonical name format. For example, “Fabrikam.com/Users/Jeff Smith”. |
ADS_NAME_TYPE_NT4 |
3 |
Account name format used in Windows NT 4.0. For example, “Fabrikam\JeffSmith”. |
ADS_NAME_TYPE_DISPLAY |
4 |
Display name format. For example, “Jeff Smith”. |
ADS_NAME_TYPE_DOMAIN_SIMPLE |
5 |
Simple domain name format. For example, “JeffSmith@Fabrikam.com”. |
ADS_NAME_TYPE_ENTERPRISE_SIMPLE |
6 |
Simple enterprise name format. For example, “JeffSmith@Fabrikam.com”. |
ADS_NAME_TYPE_GUID |
7 |
Global Unique Identifier format. For example, “{95ee9fff-3436-11d1-b2b0-d15ae3ac8436}”. |
ADS_NAME_TYPE_USER_PRINCIPAL_NAME |
9 |
User principal name format. For example, “JeffSmith@Fabrikam.com”. |
ADS_NAME_TYPE_CANONICAL_EX |
10 |
Extended canonical name format. For example, “Fabrikam.com/Users Jeff Smith”. |
ADS_NAME_TYPE_SERVICE_PRINCIPAL_NAME |
11 |
Service principal name format. For example, “www/www.fabrikam.com@fabrikam.com”. |
Give some of those a try and see what happens. We haven’t discussed the IADsNameTranslate interface much, but it’s a handy little thing to know about. On top of that, you can make a good case that this approach is a little faster and a little easier to use than an Active Directory search script, which would be an alternate method for looking up a specific user and then returning his or her GUID.
We hope that helps you with your translation problem, IU. Having recently returned from a trip to Italy, the Scripting Guy who writes this column knows all about translation issues. Not because of his trip to Italy: not only do a large number of Italians speak English, but the Scripting Guy who writes this column learned enough Italian to at least read menus and stuff. Instead, the Scripting Guy who writes this column needs a translator now that he’s back at Microsoft, listening to people say things like Web 2.0; strategic alignment; mission statements; empowerment and immersion; and proactive synergy.
Not to mention our all-time favorite: campus-wide infusion. (Which turns out to be the activity you engage in any time you hang up a poster in a Microsoft building.)
Ah, it’s good to be back!
0 comments