How to import hierarchy data into AD

M

Marcus

Hi all!

I need to know how to import via script hierarchy data to the AD. This means
I have an export from our hierarchy in a plain text file, so how is the
manager of whom.
This data I need to import to create a hierarchy structure within the AD.
(the fields "Manager" & "Direct Reports")

Does anybody knows how to do this?

Thanks in advance,
Marcus
 
R

Richard Mueller [MVP]

Marcus said:
I need to know how to import via script hierarchy data to the AD. This
means
I have an export from our hierarchy in a plain text file, so how is the
manager of whom.
This data I need to import to create a hierarchy structure within the AD.
(the fields "Manager" & "Direct Reports")

Does anybody knows how to do this?

What is the format of you export file? For example, it could be:

manager1,report1
manager1,report2
manager1,report3
manager2,report4

or, perhaps:

manager1,report1,report2,report3
manager2,report4

Also, are all values Distinguished Names (DN's) or sAMAccountNames
(pre-Windows 2000 logon names)? Is the file comma delimited? If so and the
values are DN's, then the DN's must be enclosed in quotes.

A VBScript program can use the FileSystemObject to read the text file, bind
to each direct report user object, and assign the manager DN.
 
R

Richard Mueller [MVP]

Richard Mueller said:
What is the format of you export file? For example, it could be:

manager1,report1
manager1,report2
manager1,report3
manager2,report4

or, perhaps:

manager1,report1,report2,report3
manager2,report4

Also, are all values Distinguished Names (DN's) or sAMAccountNames
(pre-Windows 2000 logon names)? Is the file comma delimited? If so and the
values are DN's, then the DN's must be enclosed in quotes.

A VBScript program can use the FileSystemObject to read the text file,
bind to each direct report user object, and assign the manager DN.

For example, if the text file is similar to (one typical line, watch line
wrapping):

"cn=Jim Smith,ou=West,dc=MyDomain,dc=com","cn=Roger
Wilson,ou=West,dc=MyDomain,dc=com","cn=Jane
Jones,ou=East,dc=MyDomain,dc=com"

where the first DN is that of the manager and the remaining DN's are direct
reports, then the VBScript program could be similar to below. Comma
delimited files can be difficult to read in VBScript, but the function used
below handles all situations.
==============
Option Explicit

Dim strFile, objFSO, objFile, strLine, strItem, strManager, objReport

Const ForReading = 1

' Specify the text file.
strFile = "c:\scripts\organization.csv"

' Open the text file for read access.
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(strFile, ForReading)

' Read each line of the file.
Do Until objFile.AtEndOfStream
strLine = Trim(objFile.ReadLine)
' Skip blank lines.
If (strLine <> "") Then
' First determine the manager DN.
strManager = ""
For Each strItem In CSVParse(strLine)
' The first DN on the line is that of the manager.
If (strManager = "") Then
strManager = strItem
Else
' All subsequent DN's are of direct reports.
' Bind to direct report user object.
Set objReport = GetObject("LDAP://" & strItem)
' Assign manager DN.
objReport.manager = strManager
' Save changes.
objReport.SetInfo
End If
Next
End If
Loop

' Clean up.
objFile.Close

Function CSVParse(ByVal strLine)
' Function to parse comma delimited line and return array
' of field values.

Dim arrFields
Dim blnIgnore
Dim intFieldCount
Dim intCursor
Dim intStart
Dim strChar
Dim strValue

Const QUOTE = """"
Const QUOTE2 = """"""

' Check for empty string and return empty array.
If (Len(Trim(strLine)) = 0) then
CSVParse = Array()
Exit Function
End If

' Initialize.
blnIgnore = False
intFieldCount = 0
intStart = 1
arrFields = Array()

' Add "," to delimit the last field.
strLine = strLine & ","

' Walk the string.
For intCursor = 1 To Len(strLine)
' Get a character.
strChar = Mid(strLine, intCursor, 1)
Select Case strChar
Case QUOTE
' Toggle the ignore flag.
blnIgnore = Not blnIgnore
Case ","
If Not blnIgnore Then
' Add element to the array.
ReDim Preserve arrFields(intFieldCount)
' Makes sure the "field" has a non-zero length.
If (intCursor - intStart > 0) Then
' Extract the field value.
strValue = Mid(strLine, intStart, _
intCursor - intStart)
' If it's a quoted string, use Mid to
' remove outer quotes and replace inner
' doubled quotes with single.
If (Left(strValue, 1) = QUOTE) Then
arrFields(intFieldCount) = _
Replace(Mid(strValue, 2, _
Len(strValue) - 2), QUOTE2, QUOTE)
Else
arrFields(intFieldCount) = strValue
End If
Else
' An empty field is an empty array element.
arrFields(intFieldCount) = Empty
End If
' increment for next field.
intFieldCount = intFieldCount + 1
intStart = intCursor + 1
End If
End Select
Next
' Return the array.
CSVParse = arrFields
End Function
 
M

Marcus

Great!

My file would be like this:

Manager; Report 1; Report 2;

Is it possible to use the User ID (Pre-Windows 2000) instead of the DN?
 
M

Marcus

Richard,

I found a script to convert the samid to dn:

#####
Const ForAppending = 2
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile (".\results.txt", ForAppending, True)
'Opens existing file for reading list of target names
Const INPUT_FILE_NAME = ".\users.txt"
Const FOR_READING = 1
'Opens file and reads all data in file
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(INPUT_FILE_NAME, FOR_READING)
strNames = objFile.ReadAll
objFile.Close
'Separates file by carriage return/line feed
strNTName = Split(strNames, vbCrLf)
' Determine DNS domain name from RootDSE object.
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")
' Use the NameTranslate object to find the NetBIOS domain name from the
' DNS domain name.
Set objTrans = CreateObject("NameTranslate")
objTrans.Init 3, strDNSDomain
objTrans.Set 1, strDNSDomain
strNetBIOSDomain = objTrans.Get(3)
' Remove trailing backslash.
strNetBIOSDomain = Left(strNetBIOSDomain, Len(strNetBIOSDomain) - 1)
' Use the NameTranslate object to convert the NT user name to the
' Distinguished Name required for the LDAP provider.
For Each strName In strNTName
objTrans.Init 1, strNetBIOSDomain
objTrans.Set 3, strNetBIOSDomain & "\" & strName
strUserDN = objTrans.Get(1)
objTextFile.WriteLine "User DN: " & strUserDN
Next
objTextFile.Close
####

So the issue in having samid's and not DN's should be no problem at all.

I do not have knowledge to mount a script, but let me tell you what I have
in mind, to see if it is possible to script:

- Reads organization file with format (manager;report1;report2) as samid's
- Converts the samid's to DN's maintaing the format showed above
- Imports the data into AD

It seems quite easy, but I imagine it isn't. Can you help me please on this
issue?

Thanks a lot!
 
R

Richard Mueller [MVP]

Marcus said:
Great!

My file would be like this:

Manager; Report 1; Report 2;

Is it possible to use the User ID (Pre-Windows 2000) instead of the DN?

You can use the NameTranslate object to convert pre-Windows 2000 names to
DN's. Also with semicolon delimiters it will be much easier to parse each
line, assuming no values have embedded semicolons. My earlier program
becomes:
============
Option Explicit

Dim strFile, objFSO, objFile, strLine, strItem, strManager, objReport
Dim objTrans, strNetBIOSDomain, objRootDSE, strDNSDomain, strReport
Dim arrValues

Const ForReading = 1

' Constants for the NameTranslate object.
Const ADS_NAME_INITTYPE_GC = 3
Const ADS_NAME_TYPE_NT4 = 3
Const ADS_NAME_TYPE_1779 = 1

' Specify the text file.
strFile = "c:\scripts\organization.csv"

' Determine DNS name of domain from RootDSE.
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")

' Use the NameTranslate object to find the NetBIOS domain name from the
' DNS domain name.
Set objTrans = CreateObject("NameTranslate")
objTrans.Init ADS_NAME_INITTYPE_GC, ""
objTrans.Set ADS_NAME_TYPE_1779, strDNSDomain
strNetBIOSDomain = objTrans.Get(ADS_NAME_TYPE_NT4)
' Remove trailing backslash.
strNetBIOSDomain = Left(strNetBIOSDomain, Len(strNetBIOSDomain) - 1)

' Open the text file for read access.
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(strFile, ForReading)

' Read each line of the file.
Do Until objFile.AtEndOfStream
strLine = Trim(objFile.ReadLine)
' Skip blank lines.
If (strLine <> "") Then
' First determine the manager DN.
strManager = ""
arrValues = Split(strLine, ";")
For Each strItem In arrValues
' The first DN on the line is that of the manager.
If (strManager = "") Then
' Use the Set method to specify the NT format of the manager
name.
' Trap error if user does not exist.
On Error Resume Next
objTrans.Set ADS_NAME_TYPE_NT4, strNetBIOSDomain & "\" &
strItem
If (Err.Number <> 0) Then
On Error GoTo 0
Wscript.Echo "Manager " & strItem & " not found."
' No need to deal with reports if manager unknown.
Exit For
Else
On Error GoTo 0
' Use the Get method to retrieve the RPC 1779
Distinguished Name.
strManager = objTrans.Get(ADS_NAME_TYPE_1779)
End If
Else
' All subsequent DN's are of direct reports.
' Use the Set method to specify the NT format of the
report's name.
' Trap error if user does not exist.
On Error Resume Next
objTrans.Set ADS_NAME_TYPE_NT4, strNetBIOSDomain & "\" &
strItem
If (Err.Number <> 0) Then
On Error GoTo 0
Wscript.Echo "Direct report " & strItem & " not found."
Else
On Error GoTo 0
' Use the Get method to retrieve the RPC 1779
Distinguished Name.
strReport = objTrans.Get(ADS_NAME_TYPE_1779)
' Bind to direct report user object.
Set objReport = GetObject("LDAP://" & strReport)
' Assign manager DN.
objReport.manager = strManager
' Save changes.
objReport.SetInfo
End If
End If
Next
End If
Loop

' Clean up.
objFile.Close
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top