Sign in to follow this  
Followers 0
NeuroToxic

PsExec + AutoIt on Windows 7 x64

10 posts in this topic

Hi,

I have a problem with AutoIt, when I want to execute an compiled AutoIt script on remote computer with PsExec.

Details :

The AutoIt script "arch.au3" :

If @CPUARCH = "x86" Then
    $CPUARCH = "32-bit"
Else
    $CPUARCH = "64-bit"
EndIf
If @OSARCH = "x86" Then
    $OSARCH = "32-bit"
Else
    $OSARCH = "64-bit"
EndIf
MsgBox(64,"OS and CPU Architechure","The CPU is " & $CPUARCH & " and the OS is " & $OSARCH, 2)

The command line to execute the AutoIt script on a remote computer with PsExec:

PsExec \\IP_Address -u Username -p Password -n 15 -h -i -f -c arch.exe

When I do this on a XP computer, its works, but not on Seven computer and I have an AutoIt error :

Unable to open the script file.

Where is the problem ?

Thank's, sorry for my bad english

Share this post


Link to post
Share on other sites



Are you compiling it as a x86 or x64 bit? If you are compiling it as x86, and trying to run it with PsExec on a remote x64 system, it will not run due to PsExec copying the file to admin$/temp. This directory is actually C:\windows\system32\temp on the remote system, which is for x64 executable only. To get around this, compile as x64 or copy the file to another directory with AutoIt and use PsExec to execute from there without the -c option.

Adam

Share this post


Link to post
Share on other sites

Where in the process does the error appear?

On the host machine or the remote machine?

executable name correct and psexec on remote machine?


Challenge accepted!

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Are you compiling it as a x86 or x64 bit? If you are compiling it as x86, and trying to run it with PsExec on a remote x64 system, it will not run due to PsExec copying the file to admin$/temp. This directory is actually C:\windows\system32\temp on the remote system, which is for x64 executable only. To get around this, compile as x64 or copy the file to another directory with AutoIt and use PsExec to execute from there without the -c option.

Adam

If the script is compiled in x64, its works, but I would like one script for both architecture, its possible ?

Edited by NeuroToxic

Share this post


Link to post
Share on other sites

use the FileInstall to check arch and then use the appropriate script :graduated:

My example when I installed printers

If @OSArch = "X86" Then
_RunDOS("if not exist C:\temp\ mkdir C:\temp\")
FileInstall("C:\Installationwizard\Printer.exe", "C:\temp\Printer.exe")
_RunDOS("start C:\temp\Printer.exe")
ElseIf @OSArch = "X64" Then
_RunDOS("if not exist C:\temp\ mkdir C:\temp\")
FileInstall("C:\Installationwizard\Printer64.exe", "C:\temp\Printer64.exe")
_RunDOS("start C:\temp\Printer64.exe")
Else
MsgBox(0, "Error", 'Setup cannot determine your OS architechture,' & @CRLF & ' please contact edb@kjemi.uio.no')
EndIf
Exit

Challenge accepted!

Share this post


Link to post
Share on other sites

use the FileInstall to check arch and then use the appropriate script :graduated:

My example when I installed printers

If @OSArch = "X86" Then
_RunDOS("if not exist C:\temp\ mkdir C:\temp\")
FileInstall("C:\Installationwizard\Printer.exe", "C:\temp\Printer.exe")
_RunDOS("start C:\temp\Printer.exe")
ElseIf @OSArch = "X64" Then
_RunDOS("if not exist C:\temp\ mkdir C:\temp\")
FileInstall("C:\Installationwizard\Printer64.exe", "C:\temp\Printer64.exe")
_RunDOS("start C:\temp\Printer64.exe")
Else
MsgBox(0, "Error", 'Setup cannot determine your OS architechture,' & @CRLF & ' please contact edb@kjemi.uio.no')
EndIf
Exit

The problem still exist if PsExec send this script

Share this post


Link to post
Share on other sites

If you compile your script as x86, and want to run it on a remote x64 computer, try this.

$sIP_Address = ""
$sLocalFile = "arch.exe"
$sRemoteFolder = "PsExecRunX86"
$sRemotePath = "\\" & $sIP_Address & "\c$\" & $sRemoteFolder & "\"
$sRemoteLocalPath = "C:\" & $sRemoteFolder & "\"
 
If Not FileCopy($sLocalFile, $sRemotePath, 9) Then Exit MsgBox(16, "ERROR!", "Unable to copy " & $sLocalFile & ".")
 
Run('PsExec \\' & $sIP_Address & ' -n 15 -h -i "' & $sRemoteLocalPath & $sLocalFile & '"', '', @SW_HIDE)

The user running the script on the local computer needs to have permissions to write to the remote computer to copy the file.

You could also put it on a remote server share, and execute from there. e.g.

$sIP_Address = ""
$sShareFilePath = "\\server\share\arch.exe"
Run('PsExec \\' & $sIP_Address & ' -n 15 -h -i "' & $sShareFilePath & '"', '', @SW_HIDE)

The user running the script on the local computer needs to have permissions to the server share.

Adam

Share this post


Link to post
Share on other sites

Thanks

Its works fine, I coded a function to automate this :

#include <Date.au3>
#include <File.au3>
 
 
_LaunchProgramOnRemoteComputer("192.168.50.0", "TEST-PC", "usertest", "passtest", "D:\programToExecute.exe", "", True, "15")
 
 
; #FUNCTION# ====================================================================================================================
; Name...........: _LaunchProgramOnRemoteComputer
; Description ...: Copy and execute a program on remote computer.
;
; Syntax.........: _LaunchProgramOnRemoteComputer($ipaddress, $domain, $username, $password, $program[, $parameters = ""[, $show = True[, $timeout = "15"]]])
;
; Parameters ....: $ipadress    - IP Address of the remote computer.
;                 $domain     - Active Directory domain name or Remote computer name.
;                 $username - Username of the user who execute the program on the remote computer.
;                 $password - Password of the user who execute the program on the remote computer.
;                 $program      - Local path of the program to execute.
;                 $parameters  - Parameters of the program.
;                 $show     - Display the interaction with the remote Desktop (True or False).
;                 $timeout   - Timeout in seconds (like "20").
;
; Return values .: Success    - Returns the return code of the program executed.
;                 Failure     - 0  and sets @ERROR
;                                            1 : Timeout.
;                                            2 : PsExec service failed to start on the remote computer.
;                                            3 : The program could not be executed.
;
; Author ........: Jeremy Guillot
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func _LaunchProgramOnRemoteComputer($ipaddress, $domain, $username, $password, $program, $parameters = "", $show = True, $timeout = "15")
 
    ; We decompose the path of the program.
    Local $sProgramDrive, $sProgramDir, $sProgramFName, $sProgramExt
    _PathSplit($program, $sProgramDrive, $sProgramDir, $sProgramFName, $sProgramExt)
 
    ; Delete the file on the remote machine.
    RunAsWait($username, $domain, $password, 2, @ComSpec & ' /c del /F \\"' & $ipaddress & "\c$\" & $sProgramFName & $sProgramExt, "", @SW_HIDE)
 
    ; Copy the program on sharing 'c$' on the remote machine.
    RunAsWait($username, $domain, $password, 2, @ComSpec & ' /c copy /Y "' & $program & '" \\"' & $ipaddress & "\c$\" & $sProgramFName & $sProgramExt, "", @SW_HIDE)
 
    ; Parameters of the program.
    If $parameters <> "" Then $parameters = " " & $parameters
 
    ; Display the interaction with the remote Desktop.
    If $show Then
        $show = " -i"
    Else
        $show = ""
    EndIf
 
    ; Program execution.
    Local $iStdoutg = Run(@comspec & " /c PsExec \\" & $ipaddress & " -u " & $domain & "\" & $username & " -p " & $password & $show & " -h -n " & $timeout & " C:\" & $sProgramFName & $sProgramExt & $parameters, @ScriptDir & "\Tools\PsTools\", @SW_HIDE, 6)
    Local $sTimeoutBegin = _NowCalc()
    Local $sCommandResult = ""
    Local $sCurrentLine = ""
    While True
        If _DateDiff("s", $sTimeoutBegin, _NowCalc()) > $timeout Then
            ProcessClose("PsExec.exe")
            ProcessClose("PSEXESVC.exe")
            Return SetError(1, 0, 0)
        EndIf
        $sCurrentLine = StderrRead($iStdoutg)
        If @error Then ExitLoop
        If $sCurrentLine <> "" Then
            $sCommandResult = $sCommandResult & @CRLF & $sCurrentLine
        EndIf
    WEnd
    ;If $sCommandResult <> "" Then ConsoleWrite($sCommandResult & @CRLF)
 
    ; Closing the PsExec process in case they would not shut.
    ProcessClose("PsExec.exe")
    ProcessClose("PSEXESVC.exe")
 
    ; Remove the program on the remote machine.
    RunAsWait($username, $domain, $password, 2, @ComSpec & ' /c del /F \\"' & $ipaddress & "\c$\" & $sProgramFName & $sProgramExt, "", @SW_HIDE)
 
    ; Error handling.
    Local $bServiceStarted = False
    Local $bCommandExecuted = False
    Local $bCommandFinished = False
    If StringInStr($sCommandResult, "Connecting with PsExec service on") And Not $bServiceStarted Then $bServiceStarted = True
    If StringInStr($sCommandResult, "Starting " & $program & " on") And Not $bCommandExecuted Then $bCommandExecuted = True
    If StringInStr($sCommandResult, " exited on " & $ipaddress & " with error code") And Not $bCommandFinished Then $bCommandFinished = True
 
    If $bCommandFinished Then
        ; We get the return code of the program.
        $sCommandResult = StringStripCR(StringStripWS(StringStripWS($sCommandResult, 1), 2))
        Local $sCommandResultCodePosition = StringInStr($sCommandResult, "with error code ")
        $sCommandResult = StringTrimLeft($sCommandResult, $sCommandResultCodePosition)
        $sCommandResult = StringTrimLeft($sCommandResult, 15)
        $sCommandResult = StringTrimRight($sCommandResult, 1)
    Else
         If Not $bServiceStarted Then Return SetError(2, 0, 0)
         If Not $bCommandExecuted Then Return SetError(3, 0, 0)
    EndIf
 
     Return SetError(0, 0, $sCommandResult)
 
EndFunc

Share this post


Link to post
Share on other sites

Glad I could help. That is a very useful function.

Adam

Share this post


Link to post
Share on other sites

Hey NeuroToxic and Adam,

Thanks for putting this together. I have been messing around with run(psexec...) with quotes spaces, x86 or x64, admin, interactive, etc blah blah blah for an eternity, and learning alot, but overcoming all these hurtles is like extremely time consuming.

also capturing any stdin stderr as well is frustrating.

Thanks guys for this wonderful package, I'm extremely thankful to you for your efforts here!!!!!

-Jeff

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