Jump to content
SanCon

RunAs, ProcessEx UDF and returned errorlevels - (Moved)

Recommended Posts

SanCon

Greetings,

I've found and used @TheDcoder's ProcessEX UDF, and have found it and invaluable tool in my scripting arsenal. Recently, I found myself needing to create a script which then attempts to run another program as a different user. I was able to heavily borrow from the _Process_RunCommand function to create _Process_RunAsCommand:

; #FUNCTION# ====================================================================================================================
; Name ..........: _Process_RunAsCommand
; Description ...: Runs a command or an executable under a different user security privilege.
; Syntax ........: _Process_RunAsCommand($iMode, $sUserName, $sUserPass, $sUserDomain, $sExecutable [, $sWorkingDir = @TempDir [, $iRunOptFlag = $STDERR_MERGED]])
; Parameters ....: $iMode               - Mode in which this function should operate, See Remarks.
;                  $sUserName           - User name under which you would like to run the command/executable.
;                  $sUserPass           - Password for $sUserName.
;                  $sUserDomain         - Domain name to which the $sUserName belongs.
;                  $sExecutable         - The command to run/execute (along with any arguments).
;                  $sWorkingDir         - [optional] The working directroy for the command. Default is @TempDir. $sUserName must have
;                                         privileges to create/modify files on this directory.
;                  $iRunOptFlag         - [optional] The Opt flag for the Run function. Default is $STDERR_MERGED.
; Return values .: Success: Mode $PROCESS_RUN     : Will return the process handle & @extended will contain the PID of the command
;                           Mode $PROCESS_RUNWAIT : Will return the output & @extended will contain the exit code for the function
;                  Failure: Will return False & @error will contain:
;                           1 - If the $iMode flag is invalid
;                           2 - If the command is invalid
; Author ........: J. Sanchez, heavily borrowing from code by TheDcoder
; Modified ......: N/A
; Remarks .......: 1. The ONLY valid modes are: $PROCESS_RUN & $PROCESS_RUNWAIT
;                     $PROCESS_RUN     : Will act similarly to Run function, See Return values
;                     $PROCESS_RUNWAIT : Will act similarly to RunWait function, See Return values
;                     If you use $PROCESS_RUN then use _Process_GetExitCode to get the exit code & use StdoutRead to get the output of the command
;                  2. Use $PROCESS_COMMAND to run commands like this: $PROCESS_COMMAND & "ping 127.0.0.1"
;                  3. Add $PROCESS_DEBUG to $iMode to automagically debug the command, $PROCESS_RUN is equivalent to $PROCESS_RUNWAIT in this case
; Related .......: RunAs, RunWait
; Link ..........: http://bit.ly/ProcessUdfForAutoIt
; Example .......: Yes, see example.au3
; ===============================================================================================================================; Functions
Func _Process_RunAsCommand($iMode, $sUserName, $sUserPass, $sUserDomain, $sExecutable, $sWorkingDir = @TempDir, $iRunOptFlag = $STDERR_MERGED)
    Local $iExitCode = 0 ; Declare the exit code variable before hand
    Local $sOutput = "" ; Declare the output variable before hand
    Local $bDebug = False ; Declare the debug variable before hand
    If BitAND($iMode, $PROCESS_DEBUG) Then $bDebug = True
    If BitAND($iMode, $PROCESS_RUN) Then
        $iMode = $PROCESS_RUN
    ElseIf BitAND($iMode, $PROCESS_RUNWAIT) Then
        $iMode = $PROCESS_RUNWAIT
    Else
        Return SetError(1, 0, False)
    EndIf
    ; If Not $iMode = $PROCESS_RUN Or Not $iMode = $PROCESS_RUNWAIT Then Return SetError(1, 0, False) ; If the mode is invalid...
    ;Local $iPID = Run($sExecutable, $sWorkingDir, @SW_HIDE, $iRunOptFlag) ; Run!!! :P
    Local $iPID = RunAs($sUserName,$sUserDomain,$sUserPass,BitAND(0,4),$PROCESS_COMMAND & " " & $sExecutable,$sWorkingDir,@SW_HIDE,$iRunOptFlag)
    If @error Then Return SetError(2, @error, False) ; If the command is invalid...
    Local $hProcessHandle = _Process_GetHandle($iPID) ; Get the handle of the process
    If $iMode = $PROCESS_RUN Then
        If Not $bDebug Then Return SetExtended($iPID, $hProcessHandle) ; If the function is in Run mode then return the PID & Process Handle
        $sOutput = _Process_DebugRunCommand($hProcessHandle, $iPID) ; Debug the process
        $iExitCode = _Process_GetExitCode($hProcessHandle) ; Note the exit code
        Return SetExtended($iExitCode, $sOutput) ; Return the output & exit code
    EndIf
    If Not $bDebug Then
        While ProcessExists($iPID)
            $sOutput &= StdoutRead($iPID) ; Capture the output
            Sleep(250) ; Don't kill the CPU
        WEnd
        $sOutput &= StdoutRead($iPID) ; Capture any remaining output
        $iExitCode = _Process_GetExitCode($hProcessHandle) ; Note the exit code
        Return SetExtended($iExitCode, $sOutput) ; Return the exit code & the output :D
    EndIf
    $sOutput = _Process_DebugRunCommand($hProcessHandle, $iPID) ; Debug the process
    $iExitCode = _Process_GetExitCode($hProcessHandle) ; Note the exit code
    Return SetExtended($iExitCode, $sOutput) ; Return the output & exit code
EndFunc

The issue that I currently have is that, regardless of what the errorlevel returned by the program being executed, the errorlevel returned by the _Process_RunAsCommand is 259, which, according to this page it means that there's no more data (I'm guessing from the STDIO and STDERR?)

Any guidance would be greatly appreciated.

Share this post


Link to post
Share on other sites
Melba23

Moved to the appropriate forum, as the Developer General Discussion forum very clearly states:

Quote

General development and scripting discussions. If it's super geeky and you don't know where to put it - it's probably here.


Do not create AutoIt-related topics here, use the AutoIt General Help and Support or AutoIt Technical Discussion forums.

Moderation Team


Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______Open Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites
SanCon

Thanks, @Melba23 Sorry for posting it on the wrong forum.

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

  • Similar Content

    • damon
      By damon
      Hello,
      You guys helped me years ago to address logging in with a different account than the user.  I have sense modified it over the years due to laptops syncing with AD which is why you will see 3 different passwords.  So, this script snippet has worked for me in many things i have written but I am all the sudden having an issue getting it to work.  I have verified that the password i am using for the local user account is $pass.  Verified by doing a run as different user on Chrome and cut and pasted the password out of the script just to make sure i was not fat fingering something.  
      I get a fail back from RunAs every time.   
      Any chance you guys see something i am doing wrong?
       
      #include <MsgBoxConstants.au3> #include <WinAPIFiles.au3> ;#RequireAdmin If $CmdLine[0] > 0 Then If $CmdLine[1] = "/Install" Then RunUpdate() Exit EndIf ;;Will check users account to determine if admin, if not will Run with admin rights -------------------------------------------------------------- ;;Varables Start Local $user = ".\user" Local $pass = "password1" Local $pass2 = "password2" Local $pass3 = "password3" Local $filetorun = @ScriptFullPath & " /Install" ;;Varables End If IsAdmin () = 0 Then If RunAs ( $user, @CompterName, $pass, $RUN_LOGON_NOPROFILE,$filetorun) = 0 Then ;If RunAs ( $user, @ComputerName, $pass2, 0,$filetorun) = 0 Then ;If RunAs ( $user, @ComputerName, $pass3, 0,$filetorun) = 0 Then ;MsgBox (0,"Installation Error", "This installation was interrupted due to an incorrect Admin Password") ;Exit ;EndIf ;EndIf EndIf Exit Else Run ($filetorun) EndIf Func RunUpdate() MsgBox(0,"worked","worked") EndFunc
    • HariKara
      By HariKara
      Hi AutoIters!
       
      Im trying to launch a .exe file that is nested within the program files (x86) folder structure. i have already used the standard RunAs Syntax and found that it fails to launch the application. I have switched to Run and that seems to work. My issue is I have to use RunAs as the applicaton would need to run under a completely different account. The Current logged in user is a Local User on the machine, however, the application must be run as a domain user. The Machine is domain connected.
       
       have tried the following:
      RunAs("username","logonpassword", $RUN_LOGON_PROFILE, "D:\Program Files (x86)\Vendor\Application Name\Exe Location\Executable.exe") The above fails to launch, there are no errors or syntax issues, it just does nothing when the variables are replaced for the correct values.
      I did the same using the Run command
      Run("D:\Program Files (x86)\Vendor\Application Name\Exe Location\Executable.exe") That seems to work fine, but runs in local user context. Any thoughts? Could it be a local Machine rights issue? Or have i missed something glaring in my script
    • PINTO1927
      By PINTO1927
      HI GUYS,
      I'm trying to run this script with an advanced domain user, but when compiling the cmd it returns access denied, as if it did not recognize the user of AD.
       
      RunAsWait("administrator", "CONTOSO", "Services.1", 2, "C:\Users\albert.frizz\Desktop\test.bat")
       
      can you help me please?
    • Traskiz
      By Traskiz
      Hello,
       
      I have a problem, I cant run script as administrator in Windows 10:
      main.exe:
      RegWrite('HKLM\SOFTWARE\Policies\Microsoft\Windows\BITS', 'EnableBITSMaxBandwidth','REG_DWORD',Number('1'))
      RegWrite('HKLM\SOFTWARE\Policies\Microsoft\Windows\BITS', 'MaxTransferRateOnSchedule','REG_DWORD',Number('100'))
      RegWrite('HKLM\SOFTWARE\Policies\Microsoft\Windows\BITS', 'MaxBandwidthValidFrom','REG_DWORD',Number('7'))
      RegWrite('HKLM\SOFTWARE\Policies\Microsoft\Windows\BITS', 'MaxBandwidthValidTo','REG_DWORD',Number('22'))
      RegWrite('HKLM\SOFTWARE\Policies\Microsoft\Windows\BITS', 'UseSystemMaximum','REG_DWORD',Number('1'))
      RegWrite('HKLM\SOFTWARE\Policies\Microsoft\Windows\BITS', 'MaxTransferRateOffSchedule','REG_DWORD',Number('400'))
      run.exe:
      Global $sUserName = "administrator"
      Global $sPassword = "pass"
      Global $sDomain = "domain"
      RunAsWait($sUserName, $sDomain, $sPassword, 2, "main.exe", "", @TempDir)
      If I run "run.exe" it dont work...
      If  I change main.exe to this:
      msgbox(1,"",@username)        
      and it runs and shows administrator in message box... but it cant elevate main.exe with RegWrite() command...
       
      I tried using #RequireAdmin in first line of main.exe, but it not worked... UAC is set to "do not notify"
       
       
      This method of elevation worked on Windows 7 and Windows XP...
      Please help!
    • Surf243
      By Surf243
      Hello,
      I've been using this UDF to set ACL permissions to some network folders, everything works great (no issues). However, I want to apply these permissions using elevated domain credentials supplied by the user and not the user that's currently running the script. As a temporary solution, I've implemented a RunAs function, but that's not the solution I'm looking for. I'm not fluent with using Dlls, but I have been trying out different methods.
      My RunAs Function:
      Func _RunAs($sUser, $sPass) If @Compiled Then RunAs($sUser, @LogonDomain, $sPass, 4, FileGetShortName(@ScriptFullPath), "", @SW_MAXIMIZE) Else RunAs($sUser, @LogonDomain, $sPass, 4, FileGetShortName(@AutoItExe) & " " & FileGetShortName(@ScriptFullPath), "", @SW_MAXIMIZE) EndIf EndFunc ;==>_RunAs I tried LogonUser and I know that I can take that token to ImpersonateLoggedOnUser, but I'm not sure how to implement that or if that's even the right method. I also need to RevertToSelf once completed.
      Func _LogonUser($sUsername, $sPassword, $sServer = @LogonDomain) ; Returns True if user exists Local $stToken $stToken = DllStructCreate("int") Local $aRet = DllCall("advapi32.dll", "int", "LogonUser", _ "str", $sUsername, "str", $sServer, "str", $sPassword, "dword", 3, "dword", 0, "ptr", DllStructGetPtr($stToken)) ;$hToken = DllStructGetData($stToken, 1) If Not @error And $aRet[0] <> 0 Then Return True EndIf Return False EndFunc ;==>_LogonUser Any assistance, suggestions or idea's would be helpful.
      Thanks!
×