Thursday, March 5, 2009

Splitting Log files

Here's how you can split any file into as many multiple parts as you need. This is good for when you need to read very large log files on windows machines.

Option Explicit

'variables for the text files
Dim sourcefile,target1,targetDir,basename,targetfile,strfilenum,filenumber,linenumber

'variables objects
Dim objfs, isnotsplit, WorkingFolder

'initialize arguments
Set objfs = CreateObject("Scripting.FileSystemObject")
Set WorkingFolder = objfs.GetFolder(".\")
sourcefile = WorkingFolder & "\source.txt"
basename = "splitlog"
targetDir = WorkingFolder & "\newfiles\"
filenumber = 1
linenumber = 1
' check the file exists
If objFS.FileExists( sourceFile ) Then
WScript.Echo ("input file exists...")
strfilenum = "" & filenumber & ""
targetfile = targetDir + "\" + basename + "_" + strfilenum + "." + objFS.GetExtensionName(sourceFile)
Set target1 = objFS.CreateTextFile(targetfile, True)
WScript.Echo "Creating file " & filenumber & "."

With objfs.OpenTextFile(sourceFile)

While Not .AtEndOfStream
' new files
If linenumber <>
target1.WriteLine .ReadLine
linenumber = linenumber + 1
target1.WriteLine .ReadLine
filenumber = filenumber + 1
strfilenum = "" & filenumber & ""
targetfile = targetDir + "\" + basename + "_" + strfilenum + "." + objFS.GetExtensionName(sourceFile)
Set target1 = objFS.CreateTextFile(targetfile, True)
linenumber = 1
WScript.Echo "Creating file " & filenumber & "."
End If
End With
If( strfilenum = 1 ) Then
WScript.Echo ("input file not split(Too Small)...")
WScript.Echo ("input file split...")
End If
WScript.Echo ("input file does not exist...")
End if
WScript.Echo ("finished!")

No matter how many resulting parts you need, this script will work. every 60,000 lines it just starts a new file with a new file name. I used this to split a log with over 1.2million lines.(180 meg txt file.)

Wednesday, February 11, 2009


An ado recordset(vbscript) does not iterate when you put it in a do while loop.

You have to tell it to iterate with the command


See? That wasn't hard. Too bad it took me 2 freaking hours to find and remember!!!!!!!

Thank you for your time. Have a good day. :)

Friday, February 6, 2009


I have searched high and I have searched low, but even though all M$ documentation claims that VB script can be used to work on any Version 3 Compliant LDAP Directory, I could not find any one or any documentation on how to do it.

After a time I figured out how to bind to LDAP using the DSObject binding and load the LDAP directory into a collection.

Set objDSO = GetObject(strProvider)
Set objDomain = objDSO.OpenDSObject (LDAP://,dc=domain,dc=com,CN=ADMIN USERID, Password, 0)

This will load the LDAP directory in it's entirety and allow you manipulate any user and make modifications or reports.

The down side is that it's very slow to manipulate and if you need to do a comparision between the LDAP collection and a csv (for example) you may end up reloading the collection several times and it can run very slowly.

Recently I have discovered another way to work with LDAP in VBscript. You can use an ADO search to query ldap and return only the attributes you want to work with. This is much faster than using the OpenDSObject and allows you do queries and comparisions and load the individual users if you need to do modifications.

To do an ADO search

' Use ADO to search Active Directory.
Set adoCommand = CreateObject("ADODB.Command")
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Properties("User ID") = "cn=ADMINID"
adoConnection.Properties("Password") = "PASSWORD"
adoConnection.Properties("Encrypt Password") = False
adoConnection.Open "Active Directory Provider"
adoCommand.ActiveConnection = adoConnection

'Search String
strBase = ""

' Filter on all user objects.
strFilter = "(objectClass=person)"

' Comma delimited list of attribute values to retrieve.
strAttributes = "cn,uid"

' Construct the LDAP syntax query.
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"

' Run the query.
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 60
adoCommand.Properties("Cache Results") = False
Set adoRecordset = adoCommand.Execute

' Enumerate resulting recordset.
Do Until adoRecordset.EOF
strUID= adoRecordset.Fields("uid").Value
WScript.Echo strDN(0)
strCN= adoRecordset.Fields("cn").Value
WScript.Echo struid(0)

There are some oddities I'm still working through. many values in LDAP seem to come up as arrays, rather htan string values, even though there are no other values in the array. Others do not. cn, and uid both came up as single value arrays, but the createtimestamp didn't.

If you need to get a users DN through this query, simply query the attribute, entryDN. yOu can use this to bind to the user and make modifications if needed, just as you would on AD.

One other great thing you can do is use this same code to query Oracle Iternet Directory. Unfortunately, OID does not have an ADSPATH (like AD) or an entryDN(LDAP) attribute so it may not help with searching users for the purposes of modifications, but you can use this method to run reports.


Tuesday, November 18, 2008


Quickly!!!! you must create 400 contacts in active directory and you must do it now otherwise users won't be able to mail these users in that other domain!!!!!!

So off I go to build a script that will load from a .csv file and create contact entries with an smtp email address and an x500 address.

All goes well. my script loads the user list. checks to make sure the user doesn't already have an AD account, or a contact entry. In fact it even removes duplicates if it finds a contact and a user object both exist. (I needed that after the first time I ran the script and I realized it wasn't checking the user objects correctly. I had a bunch of duplicates I created to remove)

So now I'm at the meat of my script. create contact. check. Make first name this. Check. Make Last name that. Check. Make the email address. Check. Add Proxy address. WRONG!!

You see, proxy Address in Active Directory is an Array not a single valued attribute. So when I set the addresses I need,



X500: /o=company/ou=container/cn=Worldwide Address List/cn=smtp-john-smith-company-com

only one address ends up in the user record. This, of course is because my script is trying to add a proxy address like this

objUser.Put "proxyAddresses", "X500:" & proxyAddressvariable
objUser.Put "proxyAddresses", "SMTP:" & proxyAddressvariable

So I did a search on the net for the best way to do this and what do I find?


Manipulating the e-mail addresses list of an Exchange recipient requires some array manipulation functions.

The UBound function retrieves the number of objects stored in an array. In order to add an e-mail address to athe proxyAddresses array of a recipient you would need to expand the number of objects stored in the array.

The Redim Preserve function allows you to expand an array while preserving its contents.

Set oUser = GetObject ("LDAP://CN=Buffy Summers,OU=Scoobies,DC=sunnydale,DC=muni")
Set objRecip = oUser
sAddress = "smtp:slayer@sunnydale.muni"
bIsFound = False
vProxyAddresses = objRecip.ProxyAddresses
nProxyAddresses = UBound(vProxyAddresses)
i = 0
Do While i <= nProxyAddresses
If vProxyAddresses(i) = sAddress Then
bIsFound = True
Exit Do
End If
i = i + 1
If Not bIsFound Then
ReDim Preserve vProxyAddresses(nProxyAddresses + 1)
vProxyAddresses(nProxyAddresses + 1) = sAddress
objRecip.ProxyAddresses = vProxyAddresses
End If


Now I like at all this. create an array and go through each contact and get the array of proxy addresses then redim the array variable to keep the data in the array but add a place for more data then add the new piece of data and save the whole thing back. It's kind of interesting, but waaay more complex than needed. This piece of script assumes you don't know what proxy addresses your users use. Now, it won't be true for everyone, but in the case of the work I'm doing I just want to add the appropriate proxy addresses. So after spending a chunk of time trying to adapt the piece of script above to my needs and realizing that I can't use it at all as the contacts I'm manipulating don't have ANYTHING in their proxy address as I'm still creating them I resumed my search of the net until I found this.

objUser.PutEx ADS_PROPERTY_APPEND, "proxyAddresses", Array (proxyAddress1,proxyAddress2)

To be fair this one line has several varialbes that had to be defined.

ADS_PROPERTY_APPEND = 2 (this is so the PutEX method knows to append rather than overwrite)
proxyaddress1 = "SMTP:" & proxyAddressvariable
proxyaddress2 = "X500:" & proxyAddressvariable

I just can't help but notice how many times I search the web for code and find vastly interesting and complex scripts and scriptlets for things that can be done in 2 or 3 lines. Now I'm not claiming to be better than anyone else when it comes to coding. I'm not. I'm very new and this rant alone seems long drawn out and overly complex. But it does all lead to the point I laid out in the title of this rant. Something I constantly need to remind myself both in my work and in my life.

Keep It Simple Stupid

Thursday, November 6, 2008

On your own

Yes!!! No!!! Yes!!! No!!! Yes!!! No!!! Yes!!! No!!! Yes!!! No!!!


This is how it's been for about 3 months now, but I think we finally have our firm no.

On the plus side this means I'm going to build an identity management solution from the ground up however we want. (we being the core tech team who are involved) We do not have to build on someone else schedule. We can build the pieces we benefit from most first and build the pieces that everyone else will benefit from last. This is going to be GREAT.

Of course, we have to build it all ourselves and we have NEVER done this before. And if we fail, it's going to be bad. But thankfully no one will notice for a while. :)

The glamor is gone. it's time for hard work. And lots of Service Requests to Oracle. LOTS OF THEM.

Tuesday, October 28, 2008

My first blog

Hello all. This is my first blog...ever. Today's topic is ORACLE IDENTITY MANAGER. This topic will come up a lot.

I would blog about how ridiculous it is to recover objects from the OIM database after they are deleted but you will find that on my masters site at

So instead, I'll blog about Oracle support. What can I say. today i have spent the ENTIRE day working with Oracle support on 4 separate Service requests regarding OIM. I've had 2 bugs filed on my behalf. (though I am told that unless we are going live soon, they won't escalate the bugs to have them fixed soon) I have been told to upload screen shots/logs and asked where THEIR OWN documentation is on THEIR SITE.

On the plus side when we asked how to recover a deleted object we got an answer. rename it and then create a new one. And when i asked, but can we recover? I was told it's a complicated process, just use this for now. And that is a very short version, of my day with oracle support.