help with script 
Author Message
 help with script

I would appreciate some assistance with the script below.  I wrote this
to update user accounts in AD using a CSV file.  It works, but errors
out if there are spaces in certain fields, such as the 'display name'.
Any help/comments is appreciated.

TIA
-------------------------
On Error Resume Next
Const OpenAsDefault = -2
Const OpenAsASCII = 0
Const OpenAsUnicode = -1
Const CreateIfNotExist = -1
Const ForReading = 1
Const FailIfNotExist = 0
Const ForWriting = 2
Const ForAppending = 8

Dim strNTPath, strQuery
Dim oDirObject, oUser
Dim aCSVargs, test

Set aCon = CreateObject("ADODB.Connection")
Set aCmd = CreateObject("ADODB.Command")
Set oFS = CreateObject("Scripting.FileSystemObject")
Set oRootDSE = GetObject("LDAP://RootDSE")
Set oMyDomain = GetObject("LDAP://" & oRootDSE.Get("defaultNamingContext"))

aCon.Provider = "ADsDSOObject"
aCon.Open
aCmd.ActiveConnection = aCon

Set oFSO = CreateObject("Scripting.FileSystemObject")

sCSVFile = wscript.arguments.item(0)

if oFSO.FileExists(sCSVFile) then
        err.clear
        set fCSVfile =
oFSO.OpenTextFile(sCSVFile,ForReading,FailIfNotExist,TristateUseDefault)

        If Err Then
                WScript.Echo(Err.Number & " - " & Err.Description)
                WScript.Quit
        End If

Else
        WScript.Echo("File: " & sCSVFile & " does not exist.")
        WScript.Quit
end if

do until fCSVfile.AtEndOfStream
        sLine = fCSVfile.ReadLine
        aCSVargs = split(sLine, ",")
        aCmd.CommandText = "<LDAP://" & oMyDomain.distinguishedname &
">;(&(objectClass=user)(SamAccountName=" & aCSVArgs(0) &
"));distinguishedName;subTree"
        aCmd.Properties("Page Size") = 500

        Err.Clear
        Set aRst = aCmd.Execute()

        If Err Then
                wscript.echo( "Error: Couldn't execute query in AD.")
                wscript.echo( "Error: " & Err.Number & " " & Err.Description)
                WScript.Quit(2)
        End If

     Err.Clear
     Set oUser = GetObject("LDAP://" & aRst.Fields("distinguishedName"))

     If Err Then
         wscript.echo( "Error: Couldn't find username in AD.")
         wscript.echo( "Error: " & Err.Number & " " & Err.Description)
         WScript.Quit(2)
     End If

     oUser.GetInfo

        If aCSVargs(1) = "" Then
                oUser.put "givenName", Chr(32)
        else
        oUser.PutEx 2, "givenName", Array(aCSVArgs(1))
     End If

     oUser.SetInfo

     If aCSVargs(2) = "" Then
        oUser.Put "initials", Chr(32)
     else
        oUser.PutEx 2, "initials", Array(aCSVArgs(2))
     end If

     oUser.SetInfo

     If aCSVargs(3) = "" Then
        oUser.Put "sn", Chr(32)
     else
        oUser.PutEx 2, "sn", Array(aCSVArgs(3))
     End If

     oUser.SetInfo

        If aCSVargs(4) = "" Then
                oUser.Put "displayName", Chr(32)
        else
        'oUser.PutEx 2, "displayName", Array(aCSVArgs(4))
                set oContainer = GetObject(oUser.Parent)
                oContainer.MoveHere oUser.AdsPath, "cn=" & aCSVArgs(4)
     End If

     oUser.SetInfo

        If aCSVargs(5) = "" Then
                oUser.Put "physicalDeliveryOfficeName", Chr(32)
        else
        oUser.PutEx 2, "physicalDeliveryOfficeName", Array(aCSVArgs(5))
     End If

     oUser.SetInfo

        If aCSVargs(6) = "" Then
                oUser.put "telephoneNumber", Chr(32)
        else
        oUser.PutEx 2, "telephoneNumber", Array(aCSVArgs(6))
     End If

     oUser.SetInfo
Loop

fCSVfile.Close
----------------------------



Tue, 29 Nov 2005 05:33:50 GMT  
 help with script
What error?  What line?

Ray at work


Quote:
> I would appreciate some assistance with the script below.  I wrote this
> to update user accounts in AD using a CSV file.  It works, but errors
> out if there are spaces in certain fields, such as the 'display name'.
> Any help/comments is appreciated.

> TIA
> -------------------------
> On Error Resume Next
> Const OpenAsDefault = -2
> Const OpenAsASCII = 0
> Const OpenAsUnicode = -1
> Const CreateIfNotExist = -1
> Const ForReading = 1
> Const FailIfNotExist = 0
> Const ForWriting = 2
> Const ForAppending = 8

> Dim strNTPath, strQuery
> Dim oDirObject, oUser
> Dim aCSVargs, test

> Set aCon = CreateObject("ADODB.Connection")
> Set aCmd = CreateObject("ADODB.Command")
> Set oFS = CreateObject("Scripting.FileSystemObject")
> Set oRootDSE = GetObject("LDAP://RootDSE")
> Set oMyDomain = GetObject("LDAP://" &

oRootDSE.Get("defaultNamingContext"))

- Show quoted text -

Quote:

> aCon.Provider = "ADsDSOObject"
> aCon.Open
> aCmd.ActiveConnection = aCon

> Set oFSO = CreateObject("Scripting.FileSystemObject")

> sCSVFile = wscript.arguments.item(0)

> if oFSO.FileExists(sCSVFile) then
> err.clear
> set fCSVfile =
> oFSO.OpenTextFile(sCSVFile,ForReading,FailIfNotExist,TristateUseDefault)

> If Err Then
> WScript.Echo(Err.Number & " - " & Err.Description)
> WScript.Quit
> End If

> Else
> WScript.Echo("File: " & sCSVFile & " does not exist.")
> WScript.Quit
> end if

> do until fCSVfile.AtEndOfStream
> sLine = fCSVfile.ReadLine
> aCSVargs = split(sLine, ",")
> aCmd.CommandText = "<LDAP://" & oMyDomain.distinguishedname &
> ">;(&(objectClass=user)(SamAccountName=" & aCSVArgs(0) &
> "));distinguishedName;subTree"
>     aCmd.Properties("Page Size") = 500

>     Err.Clear
>     Set aRst = aCmd.Execute()

>     If Err Then
>         wscript.echo( "Error: Couldn't execute query in AD.")
>         wscript.echo( "Error: " & Err.Number & " " & Err.Description)
>         WScript.Quit(2)
>     End If

>      Err.Clear
>      Set oUser = GetObject("LDAP://" & aRst.Fields("distinguishedName"))

>      If Err Then
>          wscript.echo( "Error: Couldn't find username in AD.")
>          wscript.echo( "Error: " & Err.Number & " " & Err.Description)
>          WScript.Quit(2)
>      End If

>      oUser.GetInfo

> If aCSVargs(1) = "" Then
> oUser.put "givenName", Chr(32)
> else
>      oUser.PutEx 2, "givenName", Array(aCSVArgs(1))
>      End If

>      oUser.SetInfo

>      If aCSVargs(2) = "" Then
>      oUser.Put "initials", Chr(32)
>      else
>      oUser.PutEx 2, "initials", Array(aCSVArgs(2))
>      end If

>      oUser.SetInfo

>      If aCSVargs(3) = "" Then
>      oUser.Put "sn", Chr(32)
>      else
>      oUser.PutEx 2, "sn", Array(aCSVArgs(3))
>      End If

>      oUser.SetInfo

> If aCSVargs(4) = "" Then
> oUser.Put "displayName", Chr(32)
> else
>      'oUser.PutEx 2, "displayName", Array(aCSVArgs(4))
>    set oContainer = GetObject(oUser.Parent)
> oContainer.MoveHere oUser.AdsPath, "cn=" & aCSVArgs(4)
>      End If

>      oUser.SetInfo

> If aCSVargs(5) = "" Then
> oUser.Put "physicalDeliveryOfficeName", Chr(32)
> else
>      oUser.PutEx 2, "physicalDeliveryOfficeName", Array(aCSVArgs(5))
>      End If

>      oUser.SetInfo

> If aCSVargs(6) = "" Then
> oUser.put "telephoneNumber", Chr(32)
> else
>      oUser.PutEx 2, "telephoneNumber", Array(aCSVArgs(6))
>      End If

>      oUser.SetInfo
> Loop

> fCSVfile.Close
> ----------------------------



Tue, 29 Nov 2005 06:58:09 GMT  
 help with script
Hi,

You should not be using the PutEx method to set attribute values (unless the
attribute is multi-valued, and none of the ones you deal with are). You
should use the Put method. Replace:

oUser.PutEx 2, "displayName", Array(aCSVArgs(4))

with:

oUser.Put "displayName", aCSVArgs(4)

When displayName has a space, the Array function converts it to two entries,
and there cannot be two entries for the displayName attribute. I'm surprised
it works when there are no spaces.

If no value is specified for an attribute, why not just skip it? I don't
think it would be wise to set the value to Chr(34). If you want to "blank"
out an attribute, use this instead:

Const ADS_PROPERTY_DELETE = 4
oUser.PutEx ADS_PROPERTY_DELETE, "displayName", 0

In fact, I often use code like this:

If UCase(Trim(aCSVargs(4))) = ".DELETE" Then
  oUser.PutEx ADS_PROPERTY_DELETE, "displayName", 0
Else if Trim(aCSVArgs(4)) <> "" Then
  oUser.Put "displayName", Trim(aCSVArgs(4))
End If

Next, you have a lot of SetInfo statements. There is a tradeoff here.
Everytime you do a SetInfo it takes time to flush the cache and update AD
over the network. It is much faster to make many changes and then SetInfo at
the end. The downside is that if there is an error, you don't know which
attribute caused it - it could be any attribute updated since the last
SetInfo. I generally compromise and update several attributes at a time,
then SetInfo.

Finally, you are going to a lot of trouble to retrieve the distinguishedName
of each user from the sAMAccountName. One ADO search to find the DN of one
user is one thing, but to repeat it many times seems inefficient. You might
want to use the NameTranslate object instead:

strNetBIOSDomain = "MyDomain"
Set objTrans = CreateObject("NameTranslate")
strNTName = "TestUser"                       ' sAMAccountName of user
objTrans.Init 1, strNetBIOSDomain
objTrans.Set 3, strNetBIOSDomain & "\" & strNTName
strUserDN = objTrans.Get(1)
Set oUser = GetObject("LDAP://" & strUserDN)

In your script, this might look like this:

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)
strNetBIOSDomain = Left(strNetBIOSDomain, Len(strNetBIOSDomain) - 1)

objTrans.Init 1, strNetBIOSDomain

do until fCSVfile.AtEndOfStream
  sLine = fCSVfile.ReadLine
  aCSVargs = split(sLine, ",")
  objTrans.Set 3, strNetBIOSDomain & "\" & aCSVArgs(0)
  strUserDN = objTrans.Get(1)
  Set oUser = GetObject("LDAP://" & strUserDN)
...

I hope this helps.

--
Richard
Microsoft MVP Scripting and ADSI
http://www.rlmueller.net
--


Quote:
> I would appreciate some assistance with the script below.  I wrote this
> to update user accounts in AD using a CSV file.  It works, but errors
> out if there are spaces in certain fields, such as the 'display name'.
> Any help/comments is appreciated.

> TIA
> -------------------------
> On Error Resume Next
> Const OpenAsDefault = -2
> Const OpenAsASCII = 0
> Const OpenAsUnicode = -1
> Const CreateIfNotExist = -1
> Const ForReading = 1
> Const FailIfNotExist = 0
> Const ForWriting = 2
> Const ForAppending = 8

> Dim strNTPath, strQuery
> Dim oDirObject, oUser
> Dim aCSVargs, test

> Set aCon = CreateObject("ADODB.Connection")
> Set aCmd = CreateObject("ADODB.Command")
> Set oFS = CreateObject("Scripting.FileSystemObject")
> Set oRootDSE = GetObject("LDAP://RootDSE")
> Set oMyDomain = GetObject("LDAP://" &

oRootDSE.Get("defaultNamingContext"))

- Show quoted text -

Quote:

> aCon.Provider = "ADsDSOObject"
> aCon.Open
> aCmd.ActiveConnection = aCon

> Set oFSO = CreateObject("Scripting.FileSystemObject")

> sCSVFile = wscript.arguments.item(0)

> if oFSO.FileExists(sCSVFile) then
> err.clear
> set fCSVfile =
> oFSO.OpenTextFile(sCSVFile,ForReading,FailIfNotExist,TristateUseDefault)

> If Err Then
> WScript.Echo(Err.Number & " - " & Err.Description)
> WScript.Quit
> End If

> Else
> WScript.Echo("File: " & sCSVFile & " does not exist.")
> WScript.Quit
> end if

> do until fCSVfile.AtEndOfStream
> sLine = fCSVfile.ReadLine
> aCSVargs = split(sLine, ",")
> aCmd.CommandText = "<LDAP://" & oMyDomain.distinguishedname &
> ">;(&(objectClass=user)(SamAccountName=" & aCSVArgs(0) &
> "));distinguishedName;subTree"
>     aCmd.Properties("Page Size") = 500

>     Err.Clear
>     Set aRst = aCmd.Execute()

>     If Err Then
>         wscript.echo( "Error: Couldn't execute query in AD.")
>         wscript.echo( "Error: " & Err.Number & " " & Err.Description)
>         WScript.Quit(2)
>     End If

>      Err.Clear
>      Set oUser = GetObject("LDAP://" & aRst.Fields("distinguishedName"))

>      If Err Then
>          wscript.echo( "Error: Couldn't find username in AD.")
>          wscript.echo( "Error: " & Err.Number & " " & Err.Description)
>          WScript.Quit(2)
>      End If

>      oUser.GetInfo

> If aCSVargs(1) = "" Then
> oUser.put "givenName", Chr(32)
> else
>      oUser.PutEx 2, "givenName", Array(aCSVArgs(1))
>      End If

>      oUser.SetInfo

>      If aCSVargs(2) = "" Then
>      oUser.Put "initials", Chr(32)
>      else
>      oUser.PutEx 2, "initials", Array(aCSVArgs(2))
>      end If

>      oUser.SetInfo

>      If aCSVargs(3) = "" Then
>      oUser.Put "sn", Chr(32)
>      else
>      oUser.PutEx 2, "sn", Array(aCSVArgs(3))
>      End If

>      oUser.SetInfo

> If aCSVargs(4) = "" Then
> oUser.Put "displayName", Chr(32)
> else
>      'oUser.PutEx 2, "displayName", Array(aCSVArgs(4))
>    set oContainer = GetObject(oUser.Parent)
> oContainer.MoveHere oUser.AdsPath, "cn=" & aCSVArgs(4)
>      End If

>      oUser.SetInfo

> If aCSVargs(5) = "" Then
> oUser.Put "physicalDeliveryOfficeName", Chr(32)
> else
>      oUser.PutEx 2, "physicalDeliveryOfficeName", Array(aCSVArgs(5))
>      End If

>      oUser.SetInfo

> If aCSVargs(6) = "" Then
> oUser.put "telephoneNumber", Chr(32)
> else
>      oUser.PutEx 2, "telephoneNumber", Array(aCSVArgs(6))
>      End If

>      oUser.SetInfo
> Loop

> fCSVfile.Close
> ----------------------------



Tue, 29 Nov 2005 09:37:41 GMT  
 help with script
Thanks, that really helped.
Quote:

> Hi,

> You should not be using the PutEx method to set attribute values (unless the
> attribute is multi-valued, and none of the ones you deal with are). You
> should use the Put method. Replace:

> oUser.PutEx 2, "displayName", Array(aCSVArgs(4))

> with:

> oUser.Put "displayName", aCSVArgs(4)

> When displayName has a space, the Array function converts it to two entries,
> and there cannot be two entries for the displayName attribute. I'm surprised
> it works when there are no spaces.

> If no value is specified for an attribute, why not just skip it? I don't
> think it would be wise to set the value to Chr(34). If you want to "blank"
> out an attribute, use this instead:

> Const ADS_PROPERTY_DELETE = 4
> oUser.PutEx ADS_PROPERTY_DELETE, "displayName", 0

> In fact, I often use code like this:

> If UCase(Trim(aCSVargs(4))) = ".DELETE" Then
>   oUser.PutEx ADS_PROPERTY_DELETE, "displayName", 0
> Else if Trim(aCSVArgs(4)) <> "" Then
>   oUser.Put "displayName", Trim(aCSVArgs(4))
> End If

> Next, you have a lot of SetInfo statements. There is a tradeoff here.
> Everytime you do a SetInfo it takes time to flush the cache and update AD
> over the network. It is much faster to make many changes and then SetInfo at
> the end. The downside is that if there is an error, you don't know which
> attribute caused it - it could be any attribute updated since the last
> SetInfo. I generally compromise and update several attributes at a time,
> then SetInfo.

> Finally, you are going to a lot of trouble to retrieve the distinguishedName
> of each user from the sAMAccountName. One ADO search to find the DN of one
> user is one thing, but to repeat it many times seems inefficient. You might
> want to use the NameTranslate object instead:

> strNetBIOSDomain = "MyDomain"
> Set objTrans = CreateObject("NameTranslate")
> strNTName = "TestUser"                       ' sAMAccountName of user
> objTrans.Init 1, strNetBIOSDomain
> objTrans.Set 3, strNetBIOSDomain & "\" & strNTName
> strUserDN = objTrans.Get(1)
> Set oUser = GetObject("LDAP://" & strUserDN)

> In your script, this might look like this:

> 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)
> strNetBIOSDomain = Left(strNetBIOSDomain, Len(strNetBIOSDomain) - 1)

> objTrans.Init 1, strNetBIOSDomain

> do until fCSVfile.AtEndOfStream
>   sLine = fCSVfile.ReadLine
>   aCSVargs = split(sLine, ",")
>   objTrans.Set 3, strNetBIOSDomain & "\" & aCSVArgs(0)
>   strUserDN = objTrans.Get(1)
>   Set oUser = GetObject("LDAP://" & strUserDN)
> ...

> I hope this helps.

> --
> Richard
> Microsoft MVP Scripting and ADSI
> http://www.rlmueller.net
> --



>>I would appreciate some assistance with the script below.  I wrote this
>>to update user accounts in AD using a CSV file.  It works, but errors
>>out if there are spaces in certain fields, such as the 'display name'.
>>Any help/comments is appreciated.

>>TIA
>>-------------------------
>>On Error Resume Next
>>Const OpenAsDefault = -2
>>Const OpenAsASCII = 0
>>Const OpenAsUnicode = -1
>>Const CreateIfNotExist = -1
>>Const ForReading = 1
>>Const FailIfNotExist = 0
>>Const ForWriting = 2
>>Const ForAppending = 8

>>Dim strNTPath, strQuery
>>Dim oDirObject, oUser
>>Dim aCSVargs, test

>>Set aCon = CreateObject("ADODB.Connection")
>>Set aCmd = CreateObject("ADODB.Command")
>>Set oFS = CreateObject("Scripting.FileSystemObject")
>>Set oRootDSE = GetObject("LDAP://RootDSE")
>>Set oMyDomain = GetObject("LDAP://" &

> oRootDSE.Get("defaultNamingContext"))

>>aCon.Provider = "ADsDSOObject"
>>aCon.Open
>>aCmd.ActiveConnection = aCon

>>Set oFSO = CreateObject("Scripting.FileSystemObject")

>>sCSVFile = wscript.arguments.item(0)

>>if oFSO.FileExists(sCSVFile) then
>>err.clear
>>set fCSVfile =
>>oFSO.OpenTextFile(sCSVFile,ForReading,FailIfNotExist,TristateUseDefault)

>>If Err Then
>>WScript.Echo(Err.Number & " - " & Err.Description)
>>WScript.Quit
>>End If

>>Else
>>WScript.Echo("File: " & sCSVFile & " does not exist.")
>>WScript.Quit
>>end if

>>do until fCSVfile.AtEndOfStream
>>sLine = fCSVfile.ReadLine
>>aCSVargs = split(sLine, ",")
>>aCmd.CommandText = "<LDAP://" & oMyDomain.distinguishedname &
>>">;(&(objectClass=user)(SamAccountName=" & aCSVArgs(0) &
>>"));distinguishedName;subTree"
>>    aCmd.Properties("Page Size") = 500

>>    Err.Clear
>>    Set aRst = aCmd.Execute()

>>    If Err Then
>>        wscript.echo( "Error: Couldn't execute query in AD.")
>>        wscript.echo( "Error: " & Err.Number & " " & Err.Description)
>>        WScript.Quit(2)
>>    End If

>>     Err.Clear
>>     Set oUser = GetObject("LDAP://" & aRst.Fields("distinguishedName"))

>>     If Err Then
>>         wscript.echo( "Error: Couldn't find username in AD.")
>>         wscript.echo( "Error: " & Err.Number & " " & Err.Description)
>>         WScript.Quit(2)
>>     End If

>>     oUser.GetInfo

>>If aCSVargs(1) = "" Then
>>oUser.put "givenName", Chr(32)
>>else
>>     oUser.PutEx 2, "givenName", Array(aCSVArgs(1))
>>     End If

>>     oUser.SetInfo

>>     If aCSVargs(2) = "" Then
>>     oUser.Put "initials", Chr(32)
>>     else
>>     oUser.PutEx 2, "initials", Array(aCSVArgs(2))
>>     end If

>>     oUser.SetInfo

>>     If aCSVargs(3) = "" Then
>>     oUser.Put "sn", Chr(32)
>>     else
>>     oUser.PutEx 2, "sn", Array(aCSVArgs(3))
>>     End If

>>     oUser.SetInfo

>>If aCSVargs(4) = "" Then
>>oUser.Put "displayName", Chr(32)
>>else
>>     'oUser.PutEx 2, "displayName", Array(aCSVArgs(4))
>>   set oContainer = GetObject(oUser.Parent)
>>oContainer.MoveHere oUser.AdsPath, "cn=" & aCSVArgs(4)
>>     End If

>>     oUser.SetInfo

>>If aCSVargs(5) = "" Then
>>oUser.Put "physicalDeliveryOfficeName", Chr(32)
>>else
>>     oUser.PutEx 2, "physicalDeliveryOfficeName", Array(aCSVArgs(5))
>>     End If

>>     oUser.SetInfo

>>If aCSVargs(6) = "" Then
>>oUser.put "telephoneNumber", Chr(32)
>>else
>>     oUser.PutEx 2, "telephoneNumber", Array(aCSVArgs(6))
>>     End If

>>     oUser.SetInfo
>>Loop

>>fCSVfile.Close
>>----------------------------



Tue, 29 Nov 2005 21:46:32 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. Help with script

2. Need help with script to show a hidden text box if a check box is checked

3. Help with script

4. Need Help With Script

5. Help with script - navigation & drop-down menus

6. HELP need script to change screen resolution

7. Need Help on Script Debugger

8. Help with Script

9. Help with script

10. help with scripting

11. help with script

12. Help Writing Script

 

 
Powered by phpBB® Forum Software