locked
Update Logon Workstations details RRS feed

  • Question

  • Hi,

    We are working to Configure User to hostname binding by adding Hostnames to Logonto option of the user properties. We are using a script to update the data. We keep the details in a text file as "UserID;Hostname. The script reads these details and update the same in AD. We are facing a challenge in the same if only one Hostname needs to be binded with User ID then this script is working fine but in many cases we have multiple hostnames which need to be added. In this case I need help in modifying the script so that I specify all the details in the txt file and script should read the details from text file and update in AD.

    Even if you can help me with Powershell script it should be fine.

    =============================================================================

    on error resume next
    Const ADS_SCOPE_SUBTREE = 2

    Set objConnection = CreateObject("ADODB.Connection")
    Set objCommand =   CreateObject("ADODB.Command")

    objConnection.Provider = "ADsDSOObject"
    objConnection.Open "Active Directory Provider"

    Set objCommand.ActiveConnection = objConnection

    objCommand.Properties("Page Size") = 1000
    objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE

    Set objShell = CreateObject("Wscript.Shell")

    Set oFso = CreateObject("Scripting.FileSystemObject")

    sDesktop = objShell.SpecialFolders("Desktop")
    spath = sDesktop & "\User1.txt"

    Set oT = oFso.OpenTextFile(spath,1)

    Do Until oT.AtEndofStream
      temp= oT.ReadLine()
      arry = Split(temp,";")
     
      objCommand.CommandText ="SELECT Adspath FROM 'LDAP://dc=Domain,dc=Com' WHERE objectCategory='user' and SamaccountName = '" & trim(arry(0)) & "'" 
    Set objRecordSet = objCommand.Execute

    objRecordSet.MoveFirst
    Do Until objRecordSet.EOF
            p = objRecordSet.Fields("Adspath").Value
            Set objUser = GetObject(p)
            
             
    objUser.Put "userWorkstations", trim(arry(1))
    objUser.SetInfo

    objRecordSet.MoveNext
    Loop
    LOOP

     ============================================================================

    Monday, November 25, 2013 1:11 PM

Answers

  • Here is a cleaner version of your code.

    Set objConnection = CreateObject("ADODB.Connection")
    Set objCommand =   CreateObject("ADODB.Command")
    
    objConnection.Provider = "ADsDSOObject"
    objConnection.Open "Active Directory Provider"
    
    Set objCommand.ActiveConnection = objConnection
    objCommand.Properties("Searchscope") = 2 'ADS_SCOPE_SUBTREE 
    Set objShell = CreateObject("Wscript.Shell")
    Set oFso = CreateObject("Scripting.FileSystemObject")
    sDesktop = objShell.SpecialFolders("Desktop")
    spath = sDesktop & "\User1.txt"
    
    Set oT = oFso.OpenTextFile(spath)
    
    Do Until oT.AtEndofStream
       temp= oT.ReadLine()
       arry = Split(temp,";")
      
       objCommand.CommandText ="SELECT Adspath FROM 'LDAP://dc=Domain,dc=Com' WHERE SamaccountName = '" & trim(arry(0)) & "'"  
       Set objRecordSet = objCommand.Execute
    
        Do Until objRecordSet.EOF
            p = objRecordSet.Fields("Adspath").Value
            Set objUser = GetObject(p)
            ret = objUser.Put( "userWorkstations", trim(arry(1)))
            objUser.SetInfo
            objRecordSet.MoveNext
        Loop
        
    Loop
    When you use samaccountname no other filters are required.  It is a unique value.


    ¯\_(ツ)_/¯



    • Edited by jrv Monday, November 25, 2013 3:34 PM
    • Marked as answer by Sukhwin08 Tuesday, November 26, 2013 6:57 AM
    Monday, November 25, 2013 3:33 PM

All replies


  • What is in your file?  The format is not clear.


    ¯\_(ツ)_/¯

    Monday, November 25, 2013 1:20 PM
  • user.Put "userWorkstations","pc01,pc02,pc03"

    It is a comma separated string of PC NetBIOS names.

    YOu should check the results of Put

    results = uer.Put("userWorkstations","pc01,pc02,pc03")

    if results are non zero then there is an error.


    ¯\_(ツ)_/¯

    Monday, November 25, 2013 1:26 PM
  • Hi,

    The text file contains details as below mentioned

    User1;hostname1

    user2;hostname2

    user3;hostname3

    ...and so on

    this is working fine as long as one to one mapping is there but I need to map user ID's with Multiple Hostnames like below

    User1;Hostname1,hostname2

    User2;hostname2,hostname3

    and so on

    As the number of users is very high I cannot specify as "user.Put "userWorkstations","pc01,pc02,pc03" in the script.

    Monday, November 25, 2013 3:17 PM
  • I believe you'll need to use PutEx instead of Put.

    See: http://support.microsoft.com/kb/260251/en-us 

    excerpt:

    You can use the Put method for simple attribute assignment, but not to remove an attribute. Attempts to use the Put method to set the attribute value to null or an empty string (for instance) cause an error. You can use the Put method to set the value of an attribute that can have multiple values, but it replaces any existing values. The syntax for the Put method is as follows:
      <Object>.Put <attribute name>, <value> 

    -or-

      <Object>.<property> = <value>
    The PutEx method is more comprehensive, and can be used to assign attribute values, to add or remove values from attributes that can have multiple values, and to clear the value of an attribute. As described above, clearing the attribute has the effect of removing the attribute from the directory structure. The syntax for the PutEx method is as follows:
      <Object>.PutEx <controlcode>, <attribute name>, <value(s)>


    G. Samuel Hays, MCT, MCSE 2012, MCITP: Enterprise Admin

    Blog:gsamuelhays.blogspot.com

    twitter:twitter.com/gsamuelhays

    Monday, November 25, 2013 3:20 PM
  • I still don't understand your problem.  You have a comma delimited string.  What is not working?  What error are you getting?


    ¯\_(ツ)_/¯

    Monday, November 25, 2013 3:23 PM
  • Putex is not needed and won't work.  The value is a single string.  PutEx is used with things like arrays.  The ADSI docs clearly define this as as ingle comma delimited string.


    ¯\_(ツ)_/¯

    Monday, November 25, 2013 3:27 PM
  • First remove this line and fix the errors in your script.

    on error resume next


    ¯\_(ツ)_/¯

    Monday, November 25, 2013 3:28 PM
  • Here is a cleaner version of your code.

    Set objConnection = CreateObject("ADODB.Connection")
    Set objCommand =   CreateObject("ADODB.Command")
    
    objConnection.Provider = "ADsDSOObject"
    objConnection.Open "Active Directory Provider"
    
    Set objCommand.ActiveConnection = objConnection
    objCommand.Properties("Searchscope") = 2 'ADS_SCOPE_SUBTREE 
    Set objShell = CreateObject("Wscript.Shell")
    Set oFso = CreateObject("Scripting.FileSystemObject")
    sDesktop = objShell.SpecialFolders("Desktop")
    spath = sDesktop & "\User1.txt"
    
    Set oT = oFso.OpenTextFile(spath)
    
    Do Until oT.AtEndofStream
       temp= oT.ReadLine()
       arry = Split(temp,";")
      
       objCommand.CommandText ="SELECT Adspath FROM 'LDAP://dc=Domain,dc=Com' WHERE SamaccountName = '" & trim(arry(0)) & "'"  
       Set objRecordSet = objCommand.Execute
    
        Do Until objRecordSet.EOF
            p = objRecordSet.Fields("Adspath").Value
            Set objUser = GetObject(p)
            ret = objUser.Put( "userWorkstations", trim(arry(1)))
            objUser.SetInfo
            objRecordSet.MoveNext
        Loop
        
    Loop
    When you use samaccountname no other filters are required.  It is a unique value.


    ¯\_(ツ)_/¯



    • Edited by jrv Monday, November 25, 2013 3:34 PM
    • Marked as answer by Sukhwin08 Tuesday, November 26, 2013 6:57 AM
    Monday, November 25, 2013 3:33 PM
  • I believe jrv's solution will work. Just to clarify, the input file is semicolon delimited. The first field is the sAMAccountName (pre-Windows 2000 logon name) of the user, which uniquely identifies the object in the domain. The second field is a comma delimited string of computer names, exactly what is required for the userWorkstations attribute. It is not an array, but a string.


    Richard Mueller - MVP Directory Services

    Monday, November 25, 2013 4:03 PM
  • The code, without the "on error" statement works correctly.  I just ran it pretty much as-is.

    Suspect issues with the file.

    To prove it works hard code in the name and workstations to prove to yourself that the code mechanism is correct.

    Here is a tester.

    Set objConnection = CreateObject("ADODB.Connection")
    Set objCommand =   CreateObject("ADODB.Command")
    
    objConnection.Provider = "ADsDSOObject"
    objConnection.Open "Active Directory Provider"
    
    Set objCommand.ActiveConnection = objConnection
    objCommand.Properties("Searchscope") = 2 'ADS_SCOPE_SUBTREE 
    
       temp="testme3;ws701,ws702,ws703"
       arry = Split(temp,";")
        
       objCommand.CommandText ="SELECT aDSPath FROM 'LDAP://dc=testnet,dc=local' WHERE SamaccountName = '" & trim(arry(0)) & "'"  
       Set objRecordSet = objCommand.Execute()
    
    
        Do Until objRecordSet.EOF
            p = objRecordSet.Fields("Adspath").Value
            Set objUser = GetObject(p)
            ret = objUser.Put( "userWorkstations",Trim(arry(1)))
            If ret <> 0 Then MsgBox ret
            objUser.SetInfo
            objRecordSet.MoveNext
        Loop
        
    

    This will run and set the workstations.  Just pick a test user and some real workstations.  Set the domain.


    ¯\_(ツ)_/¯

    Monday, November 25, 2013 4:08 PM