Jump to content

Active Directory home drive update application fails after first record.


Go to solution Solved by Kovacic,

Recommended Posts

Posted

I am at a loss.. I have this now messy script to simply update home drives for end users from one location to another.  

HOW IT SHOULD WORK:

You put in the old home drive location in the 'Old Home' box

You put the new location in the 'New Home' box

You hit Search AD and it checks all users in AD for any user accounts who have the old location

(optional) hit Verify to make sure they actually have a home drive in the old location

Hit START to replace the old location for the new location in AD, and map it to the H: Drive.

WHATS NOT WORKING

It works on the first record, but all additional records fail afterward.

 

Can someone take a quick peak at my messy code (because I tried so many things) and see if something sticks out? 

The issue seems to be in the ReplaceHome() function.

#include <AD.au3>
#include <GUIConstantsEx.au3>
#include <GuiEdit.au3>
#include <StaticConstants.au3>
Global $a = 0, $b = 0, $i = 1
global $Domain = "MyDomain"
HotKeySet("{PAUSE}", "TogglePause")
HotKeySet("{ESC}", "Terminate")
Global $Paused
Func TogglePause()
    $Paused = Not $Paused
    If $Paused Then
        SplashTextOn("PAUSED", "Process Paused", 400, 75, -1, -1, 0, "", 24)
    Else
        SplashOff()
    EndIf
EndFunc   ;==>TogglePause
Func Terminate()
    ProcessClose("autoit3.exe")
    Exit 0
EndFunc   ;==>Terminate
#region ### START Koda GUI section ### Form=
$Form1_1 = GUICreate("Form1", 828, 586, -1, -1)
$sourcebox = GUICtrlCreateEdit("", 8, 32, 321, 545)
GUICtrlSetLimit(-1, 9900000)
$succbox = GUICtrlCreateEdit("", 560, 272, 249, 201)
GUICtrlSetLimit(-1, 9900000)
$failbox = GUICtrlCreateEdit("", 560, 32, 249, 201)
GUICtrlSetLimit(-1, 9900000)
$B_Verify = GUICtrlCreateButton("Verify", 640, 520, 75, 57)
$B_start = GUICtrlCreateButton("S T A R T", 728, 520, 75, 57)
$Label_lable = GUICtrlCreateLabel("Paste list here", 8, 8, 70, 17)
$Label_Success = GUICtrlCreateLabel("Success", 560, 248, 45, 17)
$Label_Failed = GUICtrlCreateLabel("Failed", 560, 8, 32, 17)
$Group1 = GUICtrlCreateGroup("Options", 344, 32, 185, 537)
$oldhome = GUICtrlCreateInput("", 352, 112, 171, 21)
$L_option5 = GUICtrlCreateLabel("Old Home", 352, 88, 100, 17)
$newhome = GUICtrlCreateInput("", 352, 168, 171, 21)
$L_option7 = GUICtrlCreateLabel("New Home", 352, 144, 100, 17)
$stat1 = GUICtrlCreateLabel("", 352, 280, 166, 56, $SS_CENTER)
GUICtrlSetFont(-1, 24, 400, 0, "Arial Narrow")
$stat2 = GUICtrlCreateLabel("", 352, 335, 166, 56, $SS_CENTER)
GUICtrlSetFont(-1, 24, 400, 0, "Arial Narrow")
$stat4 = GUICtrlCreateLabel($a & "/" & $b, 352, 504, 166, 56, $SS_CENTER)
GUICtrlSetFont(-1, 24, 400, 0, "Arial Narrow")
$stat3 = GUICtrlCreateLabel("READY", 352, 440, 166, 56, $SS_CENTER)
GUICtrlSetFont(-1, 24, 400, 0, "Arial Narrow")
GUICtrlCreateGroup("", -99, -99, 1, 1)
$b_move = GUICtrlCreateButton("Use this list", 640, 480, 75, 17)
$Button1 = GUICtrlCreateButton("Search AD", 552, 520, 75, 57)
GUISetState(@SW_SHOW)
#endregion ### END Koda GUI section ###
Global $MuhVal
While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        
        Case $GUI_EVENT_CLOSE
            Exit
        Case $Button1
            If GUICtrlRead($oldhome) = "" Then
                MsgBox(0, "oops", "You will need to put a path into the 'Old Home' field so I can search AD for it i.e. ehrsan01")
            Else
                GUICtrlSetData($stat1, "Searching")
                $b = 0
                GUICtrlSetData($stat4, $a & "/" & $b)
                getusersfromAD()
                GUICtrlSetData($stat1, "Searched")
                $listnum = StringSplit(GUICtrlRead($sourcebox), @CRLF, 1)
            EndIf
        Case $sourcebox
            Global $b = _GUICtrlEdit_GetLineCount($sourcebox)
            GUICtrlSetData($stat4, $a & "/" & $b)
        Case $B_Verify
            validate()
        Case $b_move
            GUICtrlSetData($sourcebox, "")
            Sleep(1000)
            GUICtrlSetData($sourcebox, GUICtrlRead($succbox))
            GUICtrlSetData($succbox, "")
        Case $B_start
            ReplaceHome()
    EndSwitch
WEnd
Func getusersfromAD()
    _ad_open()
    Local $objCommand = ObjCreate("ADODB.Command")
    Local $objConnection = ObjCreate("ADODB.Connection")
    $objConnection.Provider = "ADsDSOObject"
    $objConnection.Open("Active Directory Provider")
    $objCommand.ActiveConnection = $objConnection
    Local $strBase = "<GC://dc=" & $Domain & ",dc=COM>"
    Local $strFilter = "(&(objectCategory=person)(objectClass=user)(sAMAccountName=*))"
    Local $strAttributes = "cn,sAMAccountName,displayName,sn,distinguishedName"
    Local $strQuery = $strBase & ";" & $strFilter & ";" & $strAttributes & ";subtree"
    $objCommand.CommandText = $strQuery
    $objCommand.Properties("Page Size") = 100
    $objCommand.Properties("Timeout") = 30
    $objCommand.Properties("Cache Results") = False
    $ADS_SCOPE_SUBTREE = 2
    $objCommand.Properties("searchscope") = $ADS_SCOPE_SUBTREE
    Local $objRecordSet = $objCommand.Execute
    Local $Muhvar
    While Not $objRecordSet.EOF
        GUICtrlSetData($stat3, "Found")
        $i += 1
        $user = $objRecordSet.Fields("sAMAccountName").Value
        $homedir = _AD_GetObjectAttribute($user, "homeDirectory")
        If StringInStr($homedir, GUICtrlRead($oldhome)) Then
            $Muhvar = $Muhvar & $user & " - " & $homedir & @CRLF
            $b += 1
            GUICtrlSetData($stat4, $a & "/" & $b)
        EndIf
        GUICtrlSetData($stat2, $i)
        $objRecordSet.MoveNext
    WEnd
    GUICtrlSetData($stat3, "READY")
    $MuhVal2 = StringSplit($Muhvar, @CRLF)
    GUICtrlSetData($sourcebox, $Muhvar)
    $objConnection.Close
    $objConnection = ""
    $objCommand = ""
    $objRecordSet = ""
    _ad_close()
EndFunc   ;==>getusersfromAD
Func validate()
    _ad_open()
    GUICtrlSetData($stat3, "Verifying")
    Sleep(100)
    Global $321 = GUICtrlRead($sourcebox)
    $useracc = StringSplit($321, @CR, 0)
    For $i = 1 To UBound($useracc) - 2
        Global $a = $i
        GUICtrlSetData($stat4, $a & "/" & $b)
        $43 = $useracc[$i]
        $123 = StringSplit($43, " - ", 3)
        If FileExists($123[1]) Then
            GUICtrlSetData($succbox, $123[0] & " - " & $123[1] & @CRLF, 1)
        Else
            GUICtrlSetData($failbox, $123[0] & " - " & $123[1] & @CRLF, 1)
        EndIf
        Sleep(20)
    Next
    _ad_close()
    GUICtrlSetData($stat3, "READY")
EndFunc   ;==>validate
Func ReplaceHome()
    GUICtrlSetData($succbox, "")
    GUICtrlSetData($failbox, "")
    _ad_open()
    Global $321 = GUICtrlRead($sourcebox)
    $useracc = StringSplit($321, @CR, 0)
    For $i = 1 To UBound($useracc) - 2
        Global $a = $i
        GUICtrlSetData($stat4, $a & "/" & $b)
        $43 = $useracc[$i]
        $123 = StringSplit($43, " - ", 3)
        $user = $123[0]
        $009 = GUICtrlRead($oldhome)
        $010 = GUICtrlRead($newhome)
        $newhomespot = StringReplace($123[1], $009, $010, 0, 2)
        $fred = _AD_ModifyAttribute($user, "homeDrive", "H:", 2)
        $pete =  _AD_ModifyAttribute($user, "homeDirectory", $newhomespot, 2)
        $Dave = $fred + $Pete
        If $Dave = 2 Then
            GUICtrlSetData($succbox, $user & " - " & "FROM:" & $123[1] & " TO:" & $newhomespot, 3)
        Else
            If @error Then GUICtrlSetData($failbox, $user & " - " & "FROM:" & $123[1] & " TO:" & $newhomespot & " ERROR:" & @error & " Account could not be modified." & @CRLF, 3)
        EndIf
        Sleep(1000)
    Next
    _ad_close()
    GUICtrlSetData($stat3, "READY")
EndFunc   ;==>ReplaceHome

C0d3 is P0etry( ͡° ͜ʖ ͡°)

  • Moderators
Posted

Kovacic, I would suggest waiting more than an hour and a half before you throw your hands up in despair. The norm is to give folks on the forum 24 hours to respond; we are a multi-national forum and the person with the best answer may not be online at the moment.

Also, how about providing better detail than "doesn't work"? You say after the first record the rest fail - what kind of error are you receiving? Help us help you ;)

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Posted

Why do you mix the AD UDF and direct AD access?

I didn't see anything you couldn't do with the AD UDF. The UDF provides better error handling etc.

My UDFs and Tutorials:

Spoiler

UDFs:
Active Directory (NEW 2024-07-28 - Version 1.6.3.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2017-07-21 - Version 0.4.0.1) - Download - General Help & Support - Example Scripts
OutlookEX (2021-11-16 - Version 1.7.0.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX_GUI (2021-04-13 - Version 1.4.0.0) - Download
Outlook Tools (2019-07-22 - Version 0.6.0.0) - Download - General Help & Support - Wiki
PowerPoint (2021-08-31 - Version 1.5.0.0) - Download - General Help & Support - Example Scripts - Wiki
Task Scheduler (2022-07-28 - Version 1.6.0.1) - Download - General Help & Support - Wiki

Standard UDFs:
Excel - Example Scripts - Wiki
Word - Wiki

Tutorials:
ADO - Wiki
WebDriver - Wiki

 

Posted (edited)

Here is an example of using the AD UDF to update your function using "getusersfromAD."  I haven't looked at your other functions, as this function looked like it had the most issues.  The querying AD portion of the function works correctly, but the code to work with your GUI has not been tested.  Hopefully this will give you an idea of how to use the AD UDF.  

#include <AD.au3>
#include <Array.au3>

Global $aTest = _GetUsersFromAD()
_ArrayDisplay($aTest)

Func _GetUsersFromAD($sBaseOU = "", $sDataToRetrieve = "", $sFilter = "")
    Local $sLDAPFilter = "(&(objectCategory=Person)" & $sFilter & ")"
    If $sDataToRetrieve = "" Then $sDataToRetrieve = "sAMAccountName,displayName,distinguishedName,homeDrive,homeDirectory"

    _AD_Open()
    Local $aUsers = _AD_GetObjectsInOU($sBaseOU, $sLDAPFilter, 2, $sDataToRetrieve)
    If @error Then
        Return SetError(@error, _AD_Close(), 0)
    EndIf
    _AD_Close()

    Local $Muhvar
    Local $user
    Local $homedir

    For $i = 1 To $aUsers[0][0]
        GUICtrlSetData($stat3, "Found")
        $user = $aUsers[$i][0]
        $homedir = $aUsers[$i][4]
        If StringInStr($homedir, GUICtrlRead($oldhome)) Then
            $Muhvar = $Muhvar & $user & " - " & $homedir & @CRLF
            $b += 1
            GUICtrlSetData($stat4, $a & "/" & $b)
        EndIf

        GUICtrlSetData($stat2, $i)
    Next

    GUICtrlSetData($stat3, "READY")
    $MuhVal2 = StringSplit($Muhvar, @CRLF)
    GUICtrlSetData($sourcebox, $Muhvar)

    Return $aUsers
EndFunc   ;==>_GetUsersFromAD
Also, your "validate" function calls _AD_Open and _AD_Close, but does not use any AD functions.  I would simplify your script using the AD UDF functions, and then it will be easier to pinpoint your problems.  

 

 

Adam

Edited by AdamUL
  • Solution
Posted

I found out what was wrong, my $user variable was fine for the first record, but after that, it had a line break before it, in the variable. Example of the raw value wrapped in pipes..

$i = 1

$user is now:

|demo1|

$i = 2

$user is now:

|

demo2|

I added some string replace and I was able to srtip it out.. The script worked like a charm after that. 

 

Why do you mix the AD UDF and direct AD access?

I didn't see anything you couldn't do with the AD UDF. The UDF provides better error handling etc.

 

I agree but I was up against a deadline and looking for a quick simple way to do it. I couldn't think of an easy way to run a query to EOF on the script at the time I was making it.

 

Im going to take a page from Adams book next time I run into this.

 

Thanks everyone!

C0d3 is P0etry( ͡° ͜ʖ ͡°)

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...