cherdeg Posted May 19, 2010 Share Posted May 19, 2010 (edited) Dear Ladies and Gentlemen, I currently try to run one of our check-tools on several remote machines in parallel. The final goal is to have a "stack", a pre-defined number of psexec-processes (dependent of the machine's performance), running in parallel. Manadar once helped me greatly to parallelize the ping command, and I try to do the same with psexec, but I'm stuck: The tool hangs after executing the first stack of commands. PSEXECSVC is started on the remote machines, but then nothing happens. If the service is killed manually there, the next stack of machines is processed seemingly correctly. Here's my current code - does somebody of you have any idea? expandcollapse popup#include <Constants.au3> Global $s_CRLF = @CRLF Global $a_Hosts[3] = ["HOST1", "HOST2", "HOST3"] ; replace with existing hosts Global $s_RemoteCMD = "net user" ; just an example _CheckOnlineStatus($a_Hosts, 2) ; Function Name _CheckOnlineStatus() ; ================================================================================================== ; ; Function Name: _CheckOnlineStatus() ; Description: Use psexec to execute checker on several systems ; Parameter(s): $a_Hostnames, $i_MaxProcess ; Requirement(s): AutoIt 3.3 ; Return Value(s): Currently none - proof of concept ; Author(s): Manadar, cs-it-solutions ; ; ================================================================================================== Func _CheckOnlineStatus($a_Hosts, $i_MaxProcess) ; Prepare the asynchronous execution Local Const $MAX_PROCESS = $i_MaxProcess ; We spawn a maximum of "$i_MaxProcess" processes at once Local $a_process[$MAX_PROCESS] ; An array to keep a reference to spawned processes; the following loop we fill it with 0 For $i = 0 To UBound($a_process) - 1 $a_process[$i] = 0 Next Local $i = 0 ; A pointer to run through the $a_Hosts array Local $i_finished = 0 While True ; Check on the current processes, and look if there is one finished for use with our next host in line (from $a_Hosts) For $n = 0 To UBound($a_process) - 1 If ($i <> UBound($a_Hosts) And $a_process[$n] == 0) Then ; Check if we need a spot, and there is an existing spot ; There is an empty spot $a_process[$n] = _MSpsexec($a_Hosts[$i]) $i += 1 Else ; Something is running here, let's check on the output If ($a_process[$n] <> 0 And _MSpsexecIsReady($a_process[$n])) Then ; We have an output here, let's get it! $s_hostname = _MSpsexecGetHostname($a_process[$n]) $i_success = _MSpsexecGetResult($a_process[$n]) If ($i_success == "Yes") Then ; Do some command line output ConsoleWrite("PSexec: Worked on " & $s_hostname & "." & $s_CRLF) Else ; Do some command line output ConsoleWrite("PSexec: Didn't work on " & $s_hostname & "." & $s_CRLF) EndIf ; Free up an empty space for the next machine $a_process[$n] = 0 $i_finished += 1 If ($i_finished == UBound($a_Hosts)) Then ExitLoop 2 ; Return EndIf EndIf EndIf Next Sleep(50) ; Give existing commands some time to process the request WEnd EndFunc ;==>_CheckOnlineStatus ; Function Name _MSpsexec() ; ================================================================================================== ; ; Function Name: _MSpsexec() ; Description: ; Parameter(s): ; Requirement(s): ; Return Value(s): ; Author(s): Manadar, cs-it-solutions ; ; ================================================================================================== Func _MSpsexec($hostname, $timeout = 50) Local $return_struc[4] ; [0] = Successful Execution: Yes/No ; [1] = The hostname originally used ; [2] = Process handle (for internal use only) ; [3] = Buffer (for internal use only) $s_PsexecCMD = "psexec /accepteula \\" & $hostname & " -u " & $hostname & "\Administrator -p PASSWORD " & $s_RemoteCMD ConsoleWrite($s_PsexecCMD & $s_CRLF) $return_struc[1] = $hostname $return_struc[2] = Run($s_PsexecCMD, "", @SW_HIDE, $STDOUT_CHILD) Return $return_struc EndFunc ;==>_MSpsexec ; Function Name _MSpsexecIsReady() ; ================================================================================================== ; ; Function Name: _MSpsexecIsReady() ; Description: ; Parameter(s): ; Requirement(s): ; Return Value(s): ; Author(s): Manadar ; ; ================================================================================================== Func _MSpsexecIsReady(ByRef $return_struc) Return ___MSpsexecReadOutput($return_struc) EndFunc ;==>_MSpsexecIsReady ; Function Name _MSpsexecGetResult() ; ================================================================================================== ; ; Function Name: _MSpsexecGetResult() ; Description: ; Parameter(s): ; Requirement(s): ; Return Value(s): ; Author(s): Manadar ; ; ================================================================================================== Func _MSpsexecGetResult($return_struc) Return $return_struc[0] EndFunc ;==>_MSpsexecGetResult ; Function Name _MSpsexecGetHostname() ; ================================================================================================== ; ; Function Name: _MSpsexecGetHostname() ; Description: ; Parameter(s): ; Requirement(s): ; Return Value(s): ; Author(s): Manadar ; ; ================================================================================================== Func _MSpsexecGetHostname($return_struc) Return $return_struc[1] EndFunc ;==>_MSpsexecGetHostname ; Function Name ___MSpsexecReadOutput() ; ================================================================================================== ; ; Function Name: ___MSpsexecReadOutput() ; Description: ; Parameter(s): ; Requirement(s): ; Return Value(s): ; Author(s): Manadar, cs-it-solutions ; ; ================================================================================================== ; Internal use only Func ___MSpsexecReadOutput(ByRef $return_struc) $data = StdoutRead($return_struc[2]) If (@error) Then ___MSpsexecParseResult($return_struc) Return 1 Else $return_struc[3] &= $data Return 0 EndIf EndFunc ;==>___MSpsexecReadOutput ; Function Name ___MSpsexecParseResult() ; ================================================================================================== ; ; Function Name: ___MSpsexecParseResult() ; Description: ; Parameter(s): ; Requirement(s): ; Return Value(s): ; Author(s): Manadar, cs-it-solutions ; ; ================================================================================================== ; Internal use only Func ___MSpsexecParseResult(ByRef $return_struc) $result = StringRegExp($return_struc[3], "error code ([0-1]*)", 3) If @error Then $return_struc[0] = "No" Else $return_struc[0] = "Yes" EndIf EndFunc ;==>___MSpsexecParseResult Best Regards, Chris Edited May 19, 2010 by cherdeg Link to comment Share on other sites More sharing options...
Danny35d Posted May 19, 2010 Share Posted May 19, 2010 The function Func _MSpsexec($hostname, $timeout = 50) add to the psexec the following switches:-d meaning don't wait for process to terminate.-i meaning run the program so that it interacts with the desktop.I notice some time depending which command I'm try to run with psexec if I don't add -i the process freeze at the remote computer. AutoIt Scripts:NetPrinter - Network Printer UtilityRobocopyGUI - GUI interface for M$ robocopy command line Link to comment Share on other sites More sharing options...
cherdeg Posted May 20, 2010 Author Share Posted May 20, 2010 The function Func _MSpsexec($hostname, $timeout = 50) add to the psexec the following switches:-d meaning don't wait for process to terminate.-i meaning run the program so that it interacts with the desktop.I notice some time depending which command I'm try to run with psexec if I don't add -i the process freeze at the remote computer.-i helps - thank you! -d can't be used because in my case: in a later iteration of this proof of concept I'm gonna copy certain result files from the remote machines; which can only be done after psexec has terminated after the "remote executed tool" is finished. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now