1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

DSQUERY / DSGET Active Directory

Discussion in 'Software' started by Coley, Mar 10, 2009.

  1. Coley

    Coley New Member

    7
    0
    15
    Hi,
    Is it possible to query AD for users that use a specific Login Script using either DSQuery or DSGet?
     
    Certifications: BEng, A+, MCDST, MCSA 70-294
    WIP: CCNA * ITIL V3 * 70-648
  2. Fergal1982

    Fergal1982 Petabyte Poster

    4,196
    171
    211
    not using dsquery, and dsget isnt going to be a lot of good to you either, as it pull outs the data for a specific user.

    you could pull it out with a vbscript though.
     
    Certifications: ITIL Foundation; MCTS: Visual Studio Team Foundation Server 2010, Administration
    WIP: None at present
  3. hippy

    hippy Kilobyte Poster

    307
    5
    40
    Or do you want to know which user runs which login script?
     
  4. Coley

    Coley New Member

    7
    0
    15
    What I'm actually trying to achieve is to move all of the users who are running "scriptA" onto "scriptB" regardless of what OU they are in etc..
    Obviously an easy way for me to achieve the result i'm after would be just to copy the text of scriptB into scriptA but I thought I'd try and do it with just the one script to keep things simple for future administration
     
    Certifications: BEng, A+, MCDST, MCSA 70-294
    WIP: CCNA * ITIL V3 * 70-648
  5. Triton.Deep

    Triton.Deep Bit Poster

    42
    3
    22
    Is the login script applied via a Group Policy Object or via the Profile Tab under Active Directory Users and Computers?

    I can help, just need a little more info. :)

    J.
     
    Certifications: MCITP EMA, MCTS, MCSE (x3), CCNA, A+,etc
    WIP: MCM for Exchange probably. Not Sure
  6. Fergal1982

    Fergal1982 Petabyte Poster

    4,196
    171
    211
    Sorry, I missed your reply before.

    If its just done using the Profile tab, you can use a VBscript to do so. But as Triton says, we'd need to know which way it was applied.

    That said, I suspect it is this way, as if it was group policy, it would be pretty easy to remedy.
     
    Certifications: ITIL Foundation; MCTS: Visual Studio Team Foundation Server 2010, Administration
    WIP: None at present
  7. Triton.Deep

    Triton.Deep Bit Poster

    42
    3
    22
    Fergal1982 nailed it. If it was a GPO applied login script, then he wouldn't be here asking questions. So..with that in mind, I took one of my old scripts, added a little bit, took away a little bit, added some comments.

    You know, I do a ton of this sort of thing, but never for anyone else. It's tough to code and in the back of your head trying to anticipate all the eventualities and different levels of folks that might try to use it.

    Anyways, here it is; even if the OP doesn't ever see this, maybe some of you other guys might find a use for it. It's easily modified to modify any two string variables on any user object in any Active Directory forest.

    Enjoy.

    J.


    Code:
    '*Script provided as is, am not responsible in any way shape or form for anything that results from using it.  It's on you. :)
    '*
    '*Purpose:  Modifies "Logon Script:" text field on Active Directory user account under the Profile Tab.  Specifically, the script
    '*searches the "Logon Script:" text field for the text assigned to strOldScript and replaces it with the text 
    '*assigned to strNewScript.  
    '*
    '*NOTE:  Use the three variables below to control script operation. Script runs by default in READ-ONLY mode.  For the 
    '*script to actually modify anything, you have to change the WRITABLE variable to yes.  Otherwise, it will just read through 
    '*the list and spit out the displayNames of your users along with the current value of the "Logon Script:" text field.  
    '*If you do run in writable mode, it will output to the screen any changes it makes.
    
    '*LOGGING:  All script actions no matter the mode are logged to the same directory the scriptfile is executed from. The
    '*file name will be "scriptname hour-minute-second.txt" (scriptname 4-5-23.txt).  Look for the file next to the VBS file itself.
    
    
    WRITABLE = "no"   
    strOldScript = "oldScript"  
    strNewScript = "newScript"
    
    
    
    Call isCscript '*Ensures your running it using cscript.exe 
    
    set objShell = createObject("wscript.shell")
    logFileTime = hour(now) - 12
    logFileTime = logFileTime & "-" & Minute(now) & "-" & Second(now)
    
    scrName = lcase(left(wscript.scriptfullname, instrrev(wscript.scriptfullname, ".")- 1)) & " " & logFileTime & ".txt"
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    Set logFile = objFSO.CreateTextFile(scrName, True)
    
    
    Set objRootDSE = GetObject("LDAP://RootDSE")
    strDomain = objRootDSE.Get("DefaultNamingContext")
    Set objConnection = CreateObject("ADODB.Connection")
    objConnection.Open "Provider=ADsDSOObject;"
    
    Set objCommand = CreateObject("ADODB.Command")
    objCommand.ActiveConnection = objConnection
    objCommand.Properties("Page Size") = 1000         'Don't stop till done
    objCommand.Properties("Sort On") = "displayName"  'sort results by displayName in ascending alphabetical order
    
    objCommand.CommandText = _
     "<LDAP://" & strDomain & ">;(&(objectCategory=person)(objectClass=user));" & _
     "distinguishedName,displayName,scriptPath;subtree"
    wscript.echo "Be patient, gathering info..."
    Set objRecordSet = objCommand.Execute
    
    While Not objRecordSet.EOF
    strDistName = objRecordSet.Fields("distinguishedName")
    strDisplayName = objRecordSet.Fields("displayName")
    strScriptPath = objRecordSet.Fields("scriptPath")
    
    If WRITABLE <> "no" AND WRITABLE = "yes" then      'Let your yes be yes and your no be no
      Set objUser = GetObject("LDAP://" & strDistName)
      
      If objUser.ScriptPath = strOldScript then
        objUser.Put "scriptPath", strNewScript
        objUser.SetInfo
        Wscript.echo strDisplayName & " = Logon Script field modified to " & strNewScript & " from " &  strOldScript & "."
        logfile.writeline strDisplayName & " = Logon Script field modified to " & strNewScript & " from " &  strOldScript & "."
      end if
      
       
    else
      wscript.echo strDisplayName & ":     " & strScriptPath
      logfile.writeline strDisplayName & ":     " & strScriptPath
    end if
    
     objRecordSet.MoveNext
    Wend
    
    
    objConnection.Close
    logFile.Close
    
    Sub isCscript()
    
    scrFullName = wscript.fullname
    scrEngine = lcase(mid(scrFullName, instrrev(scrFullName, "\")+1))
    logFile = lcase(mid(scrFullName, instrrev(scrFullName, "\")+1))
    if not scrEngine = "cscript.exe" then
      set objShell = createObject("wscript.shell")
      objShell.run "cmd /k cscript.exe //nologo """ & wscript.scriptfullname & """"
      wscript.quit
    end if
    
    End Sub
    
     
    Certifications: MCITP EMA, MCTS, MCSE (x3), CCNA, A+,etc
    WIP: MCM for Exchange probably. Not Sure
  8. Fergal1982

    Fergal1982 Petabyte Poster

    4,196
    171
    211
    That looks pretty good Triton. A few things I would (personally) change.

    Firstly, amend the script to prompt (InputBox) for both the old and the new script path. This makes it easier to use for those non-programmers to use.
    Secondly, I personally would use while/wend. I cant remember my reasoning for it off the top of my head, but I believe it had something to do with efficiency.

    Thirdly, I would create an output object pointing to a csv file (usually the name of the script tagged with .csv), and modify the output to use this instead. This I think would be the most beneficial change to your script, for two reasons:
    1) Those using it from the command line are going to need to be aware of the pipe command to send the output into a file - and making a change like this with (potentially) hundreds of users - you are definately going to want to keep a record (on that note, when you send it out to csv during the modification, you are going to want to include the original path incase you need to revert it. I know that we are comparing it so can be reasonably sure that the original is what they entered, but they might forget when they come back to look at the file in a month)
    2) those users just double clicking on the script are going to be inundated with popup message boxes.

    Finally, I would add some error handling to the script. You dont want the script to fail halfway through on a single person, when everyone else is fine. What would be better would be to send the error output (with message) to the output file (or a separate output file if you like to keep errors separate) and continue with everyone else. The user can then check the file and investigate failures.

    I've only airchecked the code since I'm not at work, so I cant say for definate there isnt anything else.
     
    Certifications: ITIL Foundation; MCTS: Visual Studio Team Foundation Server 2010, Administration
    WIP: None at present
  9. Triton.Deep

    Triton.Deep Bit Poster

    42
    3
    22
    Fergal,

    Went ahead and added a little bit to it based on some of your comments. -points up to the modified code sample-.

    Naw, it's not hard for people to look at a script, see the variables, read the comments, and make the changes. It's sort of a pet peeve of mine, generally speaking; all administrators worthy of the term should be able to look at that script, understand my comments, and run it (or not :) ) Though, if it was something I was going to use a lot, I'd probably add that. People can look at it as an opportunity to learn how to use the InputBox.

    I'd really be intrested in knowing a little more about that. We all get into habits of using specific constructs, but I think all of us favor more effcient ways of doing things. At this level, I don't think it would be noticiably faster, but regardless would like to know just in case sometime in the future I really want to eek out every last breath of effciency/performance.

    Wise words, I went ahead and added logging so that any action the script takes is automatically logged to a file in the same directory as the vbs script itself. I am used to writing files for myself so in some ways it shines through.

    Again, wise words. I went ahead and added a nifty little procedure to make sure that doesn't happen. :) Check it out, the "isCscript" sub procedure. No danger now of anyone using the wrong interpreter.

    Considering that I don't have a clue who will be using this script, or their exact environment, and all that sort of thing, I opted to take a more draconian approach. The script kills itself if it encounters any error (note the lack of "On Error Resume Next"). So, if something happens, the admin running the script will see the error outputted into the command console AND will have the output file that shows him exactly what modifications were made, and who they were made to, and where the script died as well.

    Thank you for the feedback, and I hope the updated version is a little more to your liking.

    Talk soon,

    J.
     
    Certifications: MCITP EMA, MCTS, MCSE (x3), CCNA, A+,etc
    WIP: MCM for Exchange probably. Not Sure
  10. Fergal1982

    Fergal1982 Petabyte Poster

    4,196
    171
    211
    Looking good. I'll admit I wouldnt have considered a sub to fire the cscript rather than wscript. I would just have totally removed the line by line wscript.echo's and replaced them with .Writelines, leaving only one or two wscript.echos to indicate completion, etc.

    A few comments on your notes:

    I see your point, but remember that not everyone has any desire to develop any knowledge of a programming language. Some of us have a little (or a lot) of developer in them, others dont. Whilst vbscript is a (relatively) easy language to learn, its not always the case that people can (or want to) do so.


    If I find what I read about it, I'll let you know.

    That is an option, however it could cause problems. At my work, certain accounts are prevented from being modified by anyone but a domain admin, yet other groups can make modifications to the rest of the accounts (including changing script path). If you include error handling on the account looping, then only the individual accounts that fail will not be changed, allowing all the other accounts to be modified.

    Without doing that, when I try to run your script it will always fail, and I'll never get past that one account to the rest of the accounts that I can modify.

    Including error handling to fail and alert for the individual account means that I can assess the error message and the account, realise that its a legitimate error, and forget about it (or hand the list to someone capable of making the change).
     
    Certifications: ITIL Foundation; MCTS: Visual Studio Team Foundation Server 2010, Administration
    WIP: None at present
  11. Triton.Deep

    Triton.Deep Bit Poster

    42
    3
    22
    Well to be fair, it didn't even occur to me that anyone except a domain administrator would be running this. But of course, that is also exactly why I didn't add error logging and just opted to give the script engine so to speak. However...the other approach I considered was simply to add the single line "On Error Resume Next" at the top and just let it leap past accounts it couldn't modify. So, folks could add that I suppose. It would work in your example for example.

    In the end, I got a little nervous about how people might use it so just left it to kill itself on the first error. Aww well, It was a fun little exercise. Good to know there are a few more of us automation/scripting folks running around.

    Thank you for the feedback on the script.

    J.
     
    Certifications: MCITP EMA, MCTS, MCSE (x3), CCNA, A+,etc
    WIP: MCM for Exchange probably. Not Sure
  12. Fergal1982

    Fergal1982 Petabyte Poster

    4,196
    171
    211
    No problem. I started my development career on VBScript. I dont use it quite so much any more, but it still holds a little special place in my heart.
     
    Certifications: ITIL Foundation; MCTS: Visual Studio Team Foundation Server 2010, Administration
    WIP: None at present

Share This Page

Loading...