Novell is now a part of Micro Focus

The Novell Controls for ActiveX and Visual Basic: Reading and Writing NDS Stream Fields

Articles and Tips: article

Morgan B. Adair
Software Engineer
Novell DeveloperNet University

01 Mar 2000

This article is the seventh installment in a series on Novell Directory Services (NDS) programming, using the Novell Controls for ActiveX and Visual Basic. So far, we've talked about setting up your development environment, logging in to a directory, reading and searching NDS field values, writing data values to NDS fields, and creating directory entries. This article tells how to read and write stream field values.

Catching Up

If you're jumping into the middle of this series of articles, you may need to review a few NDS concepts and programming techniques. For a quick review of the structures that comprise the NDS directory: fields, entries, and layouts, see "The Novell Controls for ActiveX and Visual Basic: Searching NDS Field Values," in Novell Developer Notes, October 1999, which is on the DeveloperNet Web site,

You may also want to review the articles on reading and writing NDS field values, in the September and December 1999 issues of Novell Developer Notes, respectively.

The example program in this article is a slight modification of the CreateEntry program we developed in the last article, "The Novell Controls for ActiveX and Visual Basic: Creating Directory Entries," in the January 2000 issue.


Streams are binary data with no prescribed syntax. Stream attributes are usually used to store large data objects, like login scripts or images. There are applications that use streams to store pictures of users, fingerprint and retinal scan images, and application passwords to implement single-sign-on security.

As mentioned in previous articles, your programs use the Novell Directory Control's GetFieldValue and SetFieldValue methods to read and write data in the fields of directory entries. Stream fields are an exception; the Directory Control has separate methods for reading and writing stream data. SaveFieldValueToFile reads data out of a stream field and saves it to a file. LoadFieldValueFromFile copies data from a file to a stream field in a directory entry. After calling LoadFieldValueFromFile, your program must call the entry's Update method to make changes to the field permanent, or the Abort method to discard changes.

Example Program: StreamExample

StreamExample is a simple modification of the CreateEntry program in the previous article, with an added feature that it can add a login script when creating a user entry. As with CreateEntry, StreamExample creates organization, organizational unit, and user entries, based on specifications given in a text file. StreamExample looks for one additional field in user entries--the name of a file containing the user's login script.

Examples of organization, organizational unit, and user specifications are shown below.

USER~VerySmallCompany\George Smith~Smith~President~555-1212~LoginScript.txt
USER~VerySmallCompany\Veronica Smith~Smith~VP Mktg~555-6318~LoginScript.txt
USER~VerySmallCompany\Jedd Smith~Smith~VP Eng~555-6051~LoginScript.txt
USER~VerySmallCompany\Samuel Smith~Smith~VP Acct~555-3694~LoginScript.txt
USER~VerySmallCompany\Emma Jones~Jones~Pres Sec~555-3056~LoginScript.txt

When StreamExample is executed, it allows the user to specify which directory the program is to operate on. The user can either select a directory to which the client is already logged in to, or log in to another directory. After the directory is specified, StreamExample allows the user to select the file that contains specifications of the directory entries to be created. Figure 1 shows StreamExample's user interface.

To build the StreamExample program:

  1. Start Visual Basic and create a new "Standard EXE" project.

  2. Add the Novell Directory and Session controls and the Microsoft Common Dialog Control to your project:

  3. Open the Components dialog by selecting "Components" from the Project menu, or by right-clicking the Toolbox and selecting "Components" from the pop-up menu.

  4. Scroll down the list of components and check the boxes next to "Novell Directory Control," "Novell Session Control," and "Microsoft Common Dialog Control 6.0."

  5. Click "OK."

StreamExample consists of 3 forms and one code module. As mentioned previously, the program is just a slight modification of the CreateEntry program.

Figure 1: StreamExampleuser interface.

ConnectionsForm, LoginForm, and Module1

The previous article in this series, "The Novell Controls for ActiveX and Visual Basic: Creating Directory Entries" (January 2000), had instructions for designing and writing the associated code for three forms, ConnectionsForm, LoginForm, and CreateEntryForm and one code module, Module1. Create a new directory for the SearchField program and copy ConnectionsForm.frm, LoginForm.frm, CreateEntryForm.frm, and Module1.bas to this new directory.

After copying the files, do the following:

  1. Add Module1 to the project by selecting "Add Module" from the Project menu, clicking on the "Existing" tab, and selecting the Module1.bas file that you just copied.

  2. Add the forms to the project by selecting "Add Form" from the Project menu, clicking on the "Existing" tab, and selecting the ConnectionsForm.frm, LoginForm.frm, and CreateEntryForm.frm files that you just copied.

  3. Make ConnectionsForm the project's startup form by opening the project's property sheet from the Project menu, then selecting "ConnectionsForm" from the Startup Object drop-down menu.


CreateEntryForm contains the procedures that parse the file of directory entry specifications and create the appropriate organization, organizational unit, and user entries. You will need to add or change just a few lines in the ParseScriptFile procedure. Those lines are shown in bold in the code fragment below.

'is it a User?
ElseIf Left$(lineStr, 5) = "USER~" Then
      'copy to temporary string, strip off USER~
      tempStr = Right$(lineStr, Len(lineStr) - 5)

      'copy name to nameStr, then strip it off
      nameStr = Left$(tempStr, InStr(1, tempStr, "~", vbTextCompare))
      tempStr = Right$(tempStr, Len(tempStr) - Len(nameStr))
      nameStr = Left$(nameStr, Len(nameStr) - 1)

      'copy surname to surnameStr, then strip it off
      surnameStr = Left$(tempStr, InStr(1, tempStr, "~", vbTextCompare))
      tempStr = Right$(tempStr, Len(tempStr) - Len(surnameStr))
      surnameStr = Left$(surnameStr, Len(surnameStr) - 1)

      'copy title to titleStr, then strip it off
      titleStr = Left$(tempStr, InStr(1, tempStr, "~", vbTextCompare))
      tempStr = Right$(tempStr, Len(tempStr) - Len(titleStr))
      titleStr = Left$(titleStr, Len(titleStr) - 1)

      'copy phone to phoneStr, then strip it off
      phoneStr = Left$(tempStr, InStr(1, tempStr, "~", vbTextCompare))
      tempStr = Right$(tempStr, Len(tempStr) - Len(phoneStr))
      phoneStr = Left$(phoneStr, Len(phoneStr) - 1)

      'loginScript is everything left, copy it to loginScriptStr
      loginScriptStr = tempStr

      If CreateDeleteOpt(0).Value Then
          DisplayLine ("Creating User: " + nameStr)
          If (CreateUser(nameStr, surnameStr, titleStr, phoneStr, _
                             loginScriptStr) = False) Then
               DisplayLine ("*** Error creating user. Script file line:")
               DisplayLine (lineStr)
           End If
           On Error GoTo DeleteError
           DisplayLine ("Deleting User: " + nameStr)
           NWDir1.Entries.Remove (nameStr)
      End If

You will also need to modify the CreateUser procedure to handle login script files. Again, the modifications to the procedure are shown in bold.

Private Function CreateUser(name As String, surname As String, _
         title As String, phone As String, loginScriptFile As String) As Boolean
      Dim newEntry As NWEntry
      On Error GoTo AddError
      Set newEntry = NWDir1.Entries.Add("User", name)
      'set attributes for the new User
      If (newEntry.SetFieldValue("Surname", surname) = True) And _
          (newEntry.SetFieldValue("Title", title) = True) And _
          (newEntry.SetFieldValue("Telephone Number", phone) = True) And _
          (newEntry.LoadFieldValueFromFile("Login Script", loginScriptFile) _
                  = True) Then

          DisplayLine ("   Surname = " + surname)
          DisplayLine ("   Title = " + title)
          DisplayLine ("   Phone = " + phone)
          DisplayLine ("   Login Script File = " + loginScriptFile)

          CreateUser = True
          CreateUser = False
      End If
      Exit Function
      CreateUser = False
End Function

One More Time

The next article in this series will show how to add new layouts to the NDS directory, a process known as "extending the directory schema."

* Originally published in Novell AppNotes


The origin of this information may be internal or external to Novell. While Novell makes all reasonable efforts to verify this information, Novell does not make explicit or implied claims to its validity.

© Copyright Micro Focus or one of its affiliates