No Excuse For Ignorance

Saturday, 18 July 2009
We should feel privileged to be alive but feel disappointed that we are going to miss out on so much.

Admittedly, some people's lives are very tough indeed and for many people around the world, hardship, suffering, poverty and hunger dominate.

But I am privileged. I live in the UK with a reasonable job and I have access to things that my parents couldn't have dreamed of. I live on the information super-highway; I have access to knowledge at my finger-tips which means I no longer need to retain the information in my own head. I just need to know where to look for the information.

As an example... I have been watching the latest Virgin Mobile advertisement on television in awe. I say watching, but I really mean listening. The accompanying song is one of the most beautiful sounds I think I've ever heard. I "need" to hear it again. And by the power that I have at my finger tips, I can search for "Virgin Mobile train advertisement song" and the first hit I get back from Google tells me that Mazzy Star performed the song which is called "Into Dust". I fired up Spotify and searched for Mazzy Star and within ~2 minutes of the advert being aired on television, I'm listening to the track.

Just a handful of years ago, the track would've been lost. I would never have found it. I went from having no knowledge of Mazzy Star to elevating "Into Dust" into my Top 10 songs of all time within minutes. The internet has allowed me to no longer feel ignorant.

All of this leads me to my next point. There is no excuse for ignorance anymore. All the information that the lay-person could ever hope to acquire is available. When someone asks me a "how do I" type of question, I'm more inclined to ask them why don't they already know the answer - especially if they are asking me the question over some form of instant messaging tool. Surely asking the question of Google would've been just as easy as asking me the question?

However, I guess the fact that people aren't capable of finding the information they are seeking is the thing that keeps me (and other IT consultants) employed.

BTW: I really do recommend "Into Dust" by Mazzy Star. It's a joy.

ADSI Guru

Wednesday, 1 July 2009
So the past few days were spent struggling to write a binary attribute into my Active Directory instance. Java isn't too clever when it comes to binary objects yet I seemed to be capable of generating a perfect binary object which I could write into ANY other LDAP compliant repository. Of course, Active Directory is merely LDAPpy - as I christened it yesterday.

Most of my efforts were probably in vain as the IBM Tivoli Identity Manager Active Directory Adapter does not support binary objects. Generating such an object an assigning it to a person record within ITIM would have been futile as would trying to generate the object on the fly during workflow.

The fact still remains that I absolutely must get this binary attribute into Active Directory as part of the provisioning process. And to that end, I wrote my first complete ADSI script today. I've spent years working on unix boxes and working with "real" LDAPs. To be scripting in VBScript and attempting to update AD was rather alien. I learned a thing or too on the way. VBScript desperately needs to know the precise size of your arrays, for example. Java, as we know, is fairly tolerant to lazy coding. VBScript desperately needs object types to be precisely as it expects whereas Java is quite tolerant when it comes to determining the difference between 1, "1" and "one"!

Design
I decided that I could write an ADSI script that would commit these binary objects to my accounts after they had been created with the AD Adapter. But I don't merely want to call this process as part of workflow. I've decided to take it a step further and create a separate service and adapter which will perform this function. ITIM, calling ITDI to write these attributes (which are based on attributes assigned to person objects as strings anyway) and ITDI calling a VBScript to commit the write.

Args
My ADSI script take command line arguments, of course. Things like the bind DN & password; the target AD instance; the target user; the raw data to be converted into binary. I'm pleased with the args processing. Not quite the way I would do it in shell scripting, but easy enough:

Dim args
Dim sBindUID

Set args = WScript.Arguments.Named
sBindUID = args.Item("bindUID")


I can now call the script as such:

cscript myscript.vbs /bindUID:Administrator

Binding
Next, I bound to the AD instance using scripting methods I found by Googling:

Dim oDS
Dim oAuth
Dim oConn
Set oDS = GetObject("LDAP:")
Set oAuth = oDS.OpenDSObject(sServer, sBindDN, sPassword, &H0200)
Set oConn = CreateObject("ADODB.Connection")
oConn.Provider = "ADsDSOObject"
oConn.Open "Active Directory Provider", sBindDN, sPassword


And then attempted to find the target for my update:

sSearchObject = "<" & sServer & ">;(" & sTarget & ");name,ADsPath;subtree"
set oRS = oConn.Execute(sSearchObject)
Set oUser = GetObject(oRS.Fields(1).Value)
oUser.GetInfo


Updating
Then came the tricky bit. I had a multi-valued attribute which required each attribute to be converted into a binary stream. I shan't bore you with the binary conversion as it is convoluted in the extreme. However, the multi-valued issue required use of the PutEx method:

oUser.PutEx ADS_PROPERTY_UPDATE, "mybinaryattribute", aEntityGUIDs

And, of course, my aEntityGUIDs object need to be an array of a size equal to the number of values in the array. Time for some Redim. Redim, of course, is not something I've ever had to do in Java! A goodly two hours were spent pondering my failure to commit my values to AD before it dawned on me that the size of the array may have an impact.

I tarted up the code to add a logging mechanism. ERROR, FATAL, WARN, INFO and DEBUG messages are written to a log file by calling a little function that includes this code:

Stuff = dateStamp & ": " & loggedString
Set myFSO = CreateObject("Scripting.FileSystemObject")
Set WriteStuff = myFSO.OpenTextFile("myvbs.log", 8, True)
WriteStuff.WriteLine(Stuff)
WriteStuff.Close

I'm not 100% sure but I'm fairly convinced that others would be fit to declare themselves VBScript/ADSI gurus. I shan't do likewise but I now have a better understanding of the pitfulls of VBScripting AD access.

NOTES
I haven't shown all the Dim statements for the objects defined in the code above - I'm sure you can work that out for yourself.