Sign in to follow this  
Followers 0
Kovacic

Active Directory home drive update application fails after first record.

6 posts in this topic

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( ͡° ͜ʖ ͡°)

Share this post


Link to post
Share on other sites



Back to the drawing board I guess :/


C0d3 is P0etry( ͡° ͜ʖ ͡°)

Share this post


Link to post
Share on other sites

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 ;)


√-1 2^3 ∑ π, and it was delicious!

Share this post


Link to post
Share on other sites

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 2017-04-18 - Version 1.4.8.0) - Download - General Help & Support - Example Scripts - Wiki
OutlookEX (NEW 2017-02-27 - Version 1.3.1.0) - Download - General Help & Support - Example Scripts - Wiki
ExcelChart (2015-04-01 - Version 0.4.0.0) - Download - General Help & Support - Example Scripts
Excel - Example Scripts - Wiki
Word - Wiki
PowerPoint (2015-06-06 - Version 0.0.5.0) - Download - General Help & Support

Tutorials:
ADO - Wiki

 

Share this post


Link to post
Share on other sites

#5 ·  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

Share this post


Link to post
Share on other sites

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( ͡° ͜ʖ ͡°)

Share this post


Link to post
Share on other sites

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
Sign in to follow this  
Followers 0

  • Similar Content

    • Quantumation
      By Quantumation
      #include <AD.au3> #include <Array.au3> ;~ GUI INCLUDES #include <GuiEdit.au3> #include <ButtonConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #Region ### START Koda GUI section ### Form= Global $Form1_1 = GUICreate("Get Managers", 592, 516, -1, -1) Global $Edit1 = GUICtrlCreateEdit("", 16, 112, 177, 361) GUICtrlSetData(-1, "") Global $Edit2 = GUICtrlCreateEdit("", 200, 112, 385, 177) GUICtrlSetData(-1, "") Global $Label1 = GUICtrlCreateLabel("GROUP NAMES", 16, 88, 135, 24) GUICtrlSetFont(-1, 12, 800, 4, "MS Sans Serif") Global $Label2 = GUICtrlCreateLabel("Group Name - Manager Names", 200, 88, 251, 24) GUICtrlSetFont(-1, 12, 800, 4, "MS Sans Serif") Global $Button1 = GUICtrlCreateButton("Get Managed By", 32, 52, 163, 31) GUICtrlSetFont(-1, 12, 800, 0, "MS Sans Serif") Global $Button2 = GUICtrlCreateButton("Copy Automated", 456, 296, 99, 25) Global $Button3 = GUICtrlCreateButton("CLEAR ALL", 440, 24, 83, 25) GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif") Global $Label3 = GUICtrlCreateLabel("Created by - Clint Smith", 185, 480, 212, 24) GUICtrlSetFont(-1, 12, 800, 0, "Century") Global $Label4 = GUICtrlCreateLabel("Enter group names with no leading spaces", 16, 8, 244, 17) GUICtrlSetFont(-1, 8, 800, 4, "MS Sans Serif") Global $Label5 = GUICtrlCreateLabel("Each Group name should be on its own line", 16, 32, 250, 17) GUICtrlSetFont(-1, 8, 800, 4, "MS Sans Serif") Global $Edit4 = GUICtrlCreateEdit("", 200, 328, 385, 145) GUICtrlSetData(-1, "") Global $Label8 = GUICtrlCreateLabel("Automated Groups", 200, 304, 156, 24) GUICtrlSetFont(-1, 12, 800, 4, "MS Sans Serif") Global $Button4 = GUICtrlCreateButton("Copy All Output", 464, 80, 99, 25) Global $Label9 = GUICtrlCreateLabel("This will Clear all boxes", 328, 32, 112, 17) Global $Label6 = GUICtrlCreateLabel("Input", 160, 88, 28, 17) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $Button1 GetManBy() Case $Button3 EndSwitch WEnd Func GetManBy() Local $dispname[0] Local $groupnames = StringSplit(GUICtrlRead($Edit1), @CR) _ArrayDisplay($groupnames) _AD_Open() If @error Then Exit MsgBox(16, "Active Directory", "Function _AD_Open encountered a problem. @error = " & @error & ", @extended = " & @extended) For $i = 1 To $groupnames[0] $GRPname = _AD_GetObjectProperties($groupnames[$i], "displayname") If $GRPname = @error Then Return MsgBox(16, "Group Not Found", $groupnames[$i] & " was not found") $info = _AD_GetObjectProperties($groupnames[$i], "info") Global $Managedby = _AD_GetObjectProperties($groupnames[$i], "managedBy,msExchCoManagedByLink") If $Managedby = @error Then MsgBox(1, "No Manager for group", $groupnames[$i] & " - Has no managers") EndIf _ArrayDisplay($Managedby) For $f = 1 To $Managedby[0][0] _ArrayDisplay($Managedby) ;~ Here is the problem below. $add = _AD_FQDNToDisplayname($Managedby[$f][1]) _ArrayAdd($dispname, $add, 0) Next $Managers = _ArrayToString($dispname, ",") $str = StringInStr($info[1][1], "automated") If $str = 0 Then GUICtrlSetData($Edit2, $GRPname & " - " & $Managers & @CRLF) ElseIf $str > 0 Then GUICtrlSetData($Edit4, $GRPname & " - Automated Group" & @CRLF) EndIf Next _AD_Close() EndFunc ;==>GetManBy I have two groups that i created with all the correct properties to make sure this script has data in all fields.
      Basically i'm trying to run a for look inside a for loop and the loops aren't playing well together for some reason. Can anyone help?
      Below is the error I get when i try to run this script.
      "C:\Users\casmith\Documents\Autoit Scripts\GetManAndCoMan.au3" (72) : ==> Subscript used on non-accessible variable.:
      For $f = 1 To $Managedby[0][0]
      For $f = 1 To $Managedby^ ERROR
      ->04:00:21 AutoIt3.exe ended.rc:1
      +>04:00:21 AutoIt3Wrapper Finished.
      >Exit code: 1    Time: 10.42
    • Kovacic
      By Kovacic
      Greetings, here is what I am running into.. About my setup:

      Computer 1: is on the domain, user account logged in is in local admin group and is a member of the domain, and has elevated AD abilities

      Computer 2 (testing computer) logged in to by local admin account (not domain user), is on the domain.


      when I execute this on computer 1, it returns the proper OU, on computer 2, it throws an Error 4 during the _AD_Open portion:


      #include dim $sAD_UserIdParam, $sAD_PasswordParam _AD_Open( $sAD_UserIdParam = "ServiceProfile", $sAD_PasswordParam = "MyPassword") If @error Then Exit MsgBox(16, "Active Directory Example Skript", "Function _AD_Open encountered a problem. @error = " & @error & ", @extended = " & @extended) $fullou = (_AD_SamAccountNameToFQDN("DomainUserAccount")) Msgbox(0, "Message", "This is Mikes OU:" & @CRLF & $fullou) _AD_Close()

      Keep in mind, I changed usernames and profiles to protect the innocent

      When I run this on computer 2, I get Error 4 which is:

      4 - Creation of the RootDSE object failed. @extended returns the error code received by the COM error handler. Generated when connection to the domain isn't successful. @extended returns -2147023541 (0x8007054B)

      Any thoughts?