Hey, Scripting Guy! As part of a logon script, I need to determine the distinguished name of the OU for the user logging on. How can I do that?
— LK
Hey, LK. Today is May 12th, which might not mean much to you. But, then again, maybe it does; after all, May 12this the birthday of Cosimo II de’ Medici, Grand Duke of Tuscany, born May 12, 1590, died February 28, 1621.
Note. If you do the math, you’ll see that Cosimo was only 30 years old when he died, by which time he was already the father of 8 children. Which may also explain why he was only 30 years old when he died. |
Today’s a meaningful day for the Scripting Guys, however: if today is May 12th (and it is) that means that we have less than a month before we’re supposed to present an instructor-led lab (Windows PowerShell for VBScripters) at TechEd 2008 in Orlando. How’s the lab coming so far? Actually it’s coming along quite nicely, provided that you overlook the fact that we have no idea what we’re going to be talking about. But, then again, that’s not entirely our fault. After all, we thought we were going to present a three-hour, pre-conference tutorial on PowerShell. Granted, three hours isn’t really enough time to teach anyone PowerShell, but it would at last let us show people a few things, and give everyone a chance to play around with the software.
Unfortunately, though, the people who do the scheduling came up with a better idea: instead of giving us one three-hour session we were given a pair of 75-minute sessions. That wouldn’t be so bad, except for one thing: session 2 isn’t supposed to be a continuation of session 1. Instead, it’s simply a repeat of session 1. (Did you enjoy the 10:00 showing? Then come back for the 1:00 matinee!) What that means, of course, is that we have just one hour and 15 minutes to try to teach people PowerShell, and to give them a chance to play around with the software as well. Is that going to work? Shoot, don’t ask us; ask someone who’s managed to put together an instructor-led lab that’s supposed to be presented in less than a month.
Note. So we asked for three hours and they gave one hour and 15 minutes. Interestingly enough, in the 7 years that the Scripting Guy has worked at Microsoft, this is the first time he’s ever failed to get everything he asked for. More or less. |
Anyway, as you might expect, the Scripting Guys are now totally immersed in Windows PowerShell; if it doesn’t use Windows PowerShell, we won’t have anything to do with it these days.
Unless, of course, it’s a VBScript script that can report back the distinguished name of the OU where the logged-on user’s Active Directory user account resides:
Set objSysInfo = CreateObject("ADSystemInfo") strUserName = objSysInfo.UserName Set objUser = GetObject("LDAP://" & strUserName) strOUName = objUser.Parent Set objOU = GetObject(strOUName) Wscript.Echo objOU.distinguishedName
As you can see, we start things off by creating an instance of the ADSystemInfo object, an object that returns some very useful information about the logged-on user, the local computer, and the local domain. We don’t know for sure if this is how LK is retrieving the distinguished name of the logged-on user; if not, LK, you might want to consider it, especially when you see how easy it is to carry out that task.
So just how easy is it to return the distinguished name for the logged-on user? As it turns out, all we have to do is grab the value of the UserName property and store it in a variable, in this case a variable we named strName:
strName = objSysInfo.UserName
Do that, and strName is going to have a value similar to this:
CN=Ken Myer,OU=Finance,OU=North America,OU=Pacific Coast,dc=fabrikam,dc=com
As you can see, the distinguished name of the user’s OU is embedded inside his or her distinguished name; in this case, that’s OU=Finance,OU=North America,OU=PacificCoast;dc=fabrikam,dc=com. The question is: how do we extract just the OU portion from the user’s distinguished name?
Note. You’re right: the easiest way to do that would just be to retrieve the value of the user’s OU property. That’s a good idea, but there is one slight problem with that approach: there’s no such thing as an OU property. Any time you need to determine the OU where a user account resides you have to start with something like the user’s distinguished name, then try to tease out the OU name. |
When we read LK’s question our first thought was to simply create an array by splitting the user’s DN on the comma; after we did that we could toss out the first item in the array (the user’s CN), then rejoin all the remaining items in the array. In this case, that would work perfectly, and give us the distinguished name of the user’s OU:
OU=Finance,OU=North America,OU=Pacific Coast,dc=fabrikam,dc=com
Unfortunately, though, there’s a potential problem with that approach, a problem revolving around the fact that it’s perfectly permissible to use a comma as part of a user’s CN. Suppose our user has this distinguished name:
CN=Ken Myer, Jr.,OU=Finance,OU=North America,OU=Pacific Coast,dc=fabrikam,dc=com
Splitting that name on the comma would give us an array with the following items:
• |
CN=Ken Myer |
• |
Jr. |
• |
OU=Finance |
• |
OU=North America |
• |
OU=Pacific Coast |
• |
dc=fabrikam |
• |
dc=com |
And when we tossed out item one and then rejoined the remaining items we’d get a distinguished name that looked like this:
Jr.,OU=Finance,OU=North America,OU=Pacific Coast,dc=fabrikam,dc=com
Not exactly what we had in mind.
Because of that, we turned to Plan B, which is actually a way better plan anyway: we connect to the user’s account in Active Directory, retrieve the value of the Parent attribute, then connect to the OU and grab the value of the object’s distinguished name.
If you aren’t familiar with it, the Parent attribute refers to the container one level “above” the user account in Active Directory. Suppose we have a user account like this one (which we do):
CN=Ken Myer,OU=Finance,OU=North America,OU=Pacific Coast,dc=fabrikam,dc=com
The Parent for this account is determined by removing the first item in the name: CN=Ken Myer. And what does that leave us with? That leaves us with the OU where the account can be found:
OU=Finance,OU=North America,OU=Pacific Coast,dc=fabrikam,dc=com
Much better than creating and then uncreating arrays, eh?
In order to retrieve the Parent attribute we use these two lines of code:
Set objUser = GetObject("LDAP://" & strUserName) strOUName = objUser.Parent
In the first line we’re simply binding to the user account in Active Directory, using the variable strUserName to represent the user’s distinguished name. In the second line, we grab the value of the Parent attribute and store that data in a variable named strOUName. That’s easy enough.
With one slight catch. As it turns out, the Parent attribute stores the complete ADsPath for the object in question. In other words, strOUName currently looks like this:
LDAP://OU=Finance,OU=North America,OU=Pacific Coast,dc=fabrikam,dc=com
That’s close to the value we’re looking for, except for the LDAP:// at the beginning of the string. (Removing the LDAP:// from an ADsPath leaves you with the distinguished name.) We could do some sort of string manipulation to get rid of the LDAP://. Or, we could do this:
Set objOU = GetObject(strOUName) Wscript.Echo objOU.distinguishedName
Here we’re simply binding to the OU itself, using the variable strOUName to represent the ADsPath of that object. After we make that connection, we then echo back the distinguished name of the OU, something that’s going to look like this:
OU=Finance,OU=North America,OU=Pacific Coast,dc=fabrikam,dc=com
That’s all we have to do.
Well, that and get ready for TechEd. Again, if you’re going to be at TechEd, and if you’re a newcomer to Windows PowerShell, we’d love to have you drop in for one of our two sessions.
Hint. Try to pick the session that Greg delivers; that will be the good one. Unless you’re in a hurry. If you’re in a hurry, pick the session that Jean delivers: she talks so fast that you should be in and out there is about 10 minutes, tops. During Windows PowerShell Week Jean delivered a 90-minute Webcast in about 45 minutes, a record that might never be broken. |
As we whined – um, as we noted earlier, we’ll be a little pressed for time. But that’s OK; we’ll have some fun, and we guarantee that you’ll learn a few things. In addition, we’ll be available to answer questions, and we’ll have some very nice handouts for you. Are we giving away prizes? Well, maybe. Guess you’ll just have to sign up for the session and see for yourself.
0 comments