Sign in to follow this  
Followers 0
ohstoopid1

RunAs with functions instead of executables

16 posts in this topic

It has come up a few times for me within applications where it would be nice to perform a custom function within a RunAs function (more specifically the functions from UDF _ServiceControl.au3)

Does anyone know if this is possible, or is there a better way to do this? From testing it appears to just disregard the embedded function in RunAs as I expected. For example:

RunAs("username", "domain", "password", 2, _StartService($pc,"ServiceName"))

I'm aware of the #RequireAdmin header but in some instances (from my understanding) this would not work, say if the script is a scheduled task or triggered by a rule.

Thoughts?

Share this post


Link to post
Share on other sites



Well I resolved the immediate issue by creating a simple script that calls the other script with RunAs. Seems to be a bit of a hack this way, though I can understand why the method I would like to do it may never work (running a segment of a binary with separate credentials). Anyhow, I'd be interested to hear input on this one..

Share this post


Link to post
Share on other sites

You can re start your script with RunAs()

#include <UDF _ServiceControl.au3>

$sUsername = @UserName
$sPassword = 'Password'
$sDomain = @ComputerName

If $CMDLine[0] = 0 Then
    RunAs($sUsername, $sDomain, $sPassword, 0, @AutoItExe & ' /RunAs', @SystemDir, @SW_HIDE)
    Exit
EndIf

_StartService($pc, "ServiceName")


AutoIt Scripts:NetPrinter - Network Printer UtilityRobocopyGUI - GUI interface for M$ robocopy command line

Share this post


Link to post
Share on other sites

Very nice, I may have never thought of that. Thanks!

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

You can re start your script with RunAs()

#include <UDF _ServiceControl.au3>

$sUsername = @UserName
$sPassword = 'Password'
$sDomain = @ComputerName

If $CMDLine[0] = 0 Then
    RunAs($sUsername, $sDomain, $sPassword, 0, @AutoItExe & ' /RunAs', @SystemDir, @SW_HIDE)
    Exit
EndIf

_StartService($pc, "ServiceName")
So, if I wanted to create a script to install an application where the user that logs in doesn't have Admin rights on the PC and there is no MS Domain (we're a Novell shop), will your example work??? I've been trying to get this working and have hit a wall. What I want to do is:

1. Non-Admin user logs into Novell network.

2. Push AutoIT script during Novell loging that launches application installation using Local PCs admin account and password.

3. Install application and reboot PC as needed.

Can this be done??? This is my original Code.

Local $sUserName = "administrator"
    Local $sPassword = "password"
    Dim $Filename = IniRead ( @ScriptDir & "\SciTE.ini", "LogoData", "Destination1", "default" )
    $Domain = @ComputerName
    
    If Not IsAdmin() Then
      ; Run a command prompt as the other user.
        local $pid = RunAs($sUserName, $Domain, $sPassword, 0, Run(@ComSpec & " /c " & $Filename), @ScriptDir)
      ; Wait for the process to close.
        ProcessWaitClose($pid)
    Else
        Run($Filename, @ScriptDir, @SW_HIDE)
    EndIf
Edited by cpremo

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Remove the second Run function and it should work ok, also why not use RunAsWait?

Local $sUserName = "administrator"
    Local $sPassword = "password"
    Dim $Filename = IniRead ( @ScriptDir & "\SciTE.ini", "LogoData", "Destination1", "default" )
    $Domain = @ComputerName
    
    If Not IsAdmin() Then
      ; Run a command prompt as the other user.
        RunAsWait($sUserName, $Domain, $sPassword, 0, @ComSpec & " /c " & $Filename, @ScriptDir)
    Else
        Run($Filename, @ScriptDir, @SW_HIDE)
    EndIf
Edited by ohstoopid1

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

You can re start your script with RunAs()
#include <UDF _ServiceControl.au3>

$sUsername = @UserName
$sPassword = 'Password'
$sDomain = @ComputerName

If $CMDLine[0] = 0 Then
    RunAs($sUsername, $sDomain, $sPassword, 0, @AutoItExe & ' /RunAs', @SystemDir, @SW_HIDE)
    Exit
EndIf

_StartService($pc, "ServiceName")oÝ÷ Ûú®¢×¢êÚ¦èiÈly鬽êòºÇºVî´mëmërÝ{-jwÂ+azW¯j×®(!¶Ëh®éÀ+a¢è!¶Æ®¶­sbb33c·5W6W&æÖRÒgV÷C´FöÖä66÷VçEvF&vG2gV÷C°¢b33c·577v÷&BÒgV÷Cµ77v÷&BgV÷C°¢b33c·4FöÖâÒgV÷C´×FöÖâgV÷C° ¤bb33c´4ÔDÆæU³ÒÒFVà¢b33cµ'Vå&W7VÇBÒ'Vä2b33c·5W6W&æÖRÂb33c·4FöÖâÂb33c·577v÷&BÂÂWFôDWRfײb33²õ'Vä2b33²Â77FVÔF"Â5uôDR¢×6t&÷CbÂgV÷C³ÒfÂgV÷C²ÂgV÷Cµ&W7VÇBÒgV÷C²fײb33cµ'&W7VÇB¢W@¤VæD`£²Fò7GVfbW&RvFVÆWfFVB&vG0
Edited by Tim H.

Share this post


Link to post
Share on other sites

The only time I can't get the second instance with elevated rights to run is when I change the password and forgot to update the script with the new password. So, be sure you have the right information (Username, Password, and Domain/Computername). The script below is what I use to run any software with administrator rights.

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

$sUsername = 'UserName'
$sPassword = 'Password'
$sDomain = @ComputerName

If $CMDLine[0] = 0 Then
    RunAs($sUsername, $sDomain, $sPassword, 0, @AutoItExe & ' /RunAs', @SystemDir, @SW_SHOW)
    Exit
EndIf

$MainGUI = GUICreate("RunAs", 342, 121, -1, -1, -1, $WS_EX_ACCEPTFILES)
GUICtrlCreateLabel("Browse or Drag and Drop a Program.", 40, 20, 260, 17)
GUICtrlCreateLabel("Open:", 0, 40, 33, 17)
$FullPath = GUICtrlCreateInput("", 40, 38, 289, 21)
GUICtrlSetState($FullPath, $GUI_DROPACCEPTED)
$Ok = GUICtrlCreateButton("Ok", 96, 88, 75, 25, 0)
$Cancel = GUICtrlCreateButton("Cancel", 176, 88, 75, 25, 0)
$Browser = GUICtrlCreateButton("Browser...", 256, 88, 75, 25, 0)
GUISetState(@SW_SHOW)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE, $Cancel
            Exit
        Case $Browser
            $message = 'Choose A Program.'
            $FilePath = FileOpenDialog($message, "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", "All (*.*)", 3, '', $MainGUI)
            If @error Then $FilePath = ''            
            GUICtrlSetData($FullPath, $FilePath)
        Case $Ok
            $sProgram = GUICtrlRead($FullPath)
            If $sProgram = '' Then
                MsgBox(48,"RunAs","You need to browse or drag and drop a program.")
                ContinueLoop
            EndIf
            ShellExecute($sProgram, '', @WorkingDir)
            Exit
    EndSwitch
WEnd


AutoIt Scripts:NetPrinter - Network Printer UtilityRobocopyGUI - GUI interface for M$ robocopy command line

Share this post


Link to post
Share on other sites

Thanks for the quick response. "Bad Credentials" were my first thought too. I tried three different sets, all of which I verified were correct and operational. I'll keep playing with it.

Share this post


Link to post
Share on other sites

Something else is going on in my environment. When I run the script locally with the local administrator account's credentials, it runs perfectly. When I run it locally with the domain credentials of an account in my local administrator's group, it runs perfectly again. When I try to run it from my network using UNCs (ignoring any drive mapping issues) , it fails. Perhaps I have a latency issue or a NAS attribute problem that's precluding the second instance from launching.

At least I have a working scenario.

Thanks again for your help.

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

Um. Drive mapping isseus? Drive mapping issues are caused because UserB can't see the UNC path UserA can so UserB can't see the drive, either. If you are running from a UNC path then both UserA and UserB must be able to see that the UNC path.

Always, always, ALWAYS copy the script somewhere when attempting to re-run it with RunAs(). It should be copied to a location that all users have read/write access to to avoid any access denied errors. The follow pseudo-code sequence is the best way to do it:

If @Compiled Then
    Local Const $sPath = "The\Path\Everyone\Can\See"
    FileCopy(@AutoItExe, $sPath)
    RunAsWait(...)
    FileDelete($sPath)
Else
    MsgBox(0, "Error", "The script must be compiled to run.")
EndIf

Makes sure the script is compiled, copies the file somewhere safe to prevent access denied issues, runs the script waiting on it to finish and then deletes the file to clean up.

Edited by Valik

Share this post


Link to post
Share on other sites

What about this, The user is not on a domain or Novell. I am pushing the software to the PC via a secure tunnel to a directory on the local PC. Will this script work in this instance.?

Um. Drive mapping isseus? Drive mapping issues are caused because UserB can't see the UNC path UserA can so UserB can't see the drive, either. If you are running from a UNC path then both UserA and UserB must be able to see that the UNC path.

Always, always, ALWAYS copy the script somewhere when attempting to re-run it with RunAs(). It should be copied to a location that all users have read/write access to to avoid any access denied errors. The follow pseudo-code sequence is the best way to do it:

If @Compiled Then
    Local Const $sPath = "The\Path\Everyone\Can\See"
    FileCopy(@AutoItExe, $sPath)
    RunAsWait(...)
    FileDelete($sPath)
Else
    MsgBox(0, "Error", "The script must be compiled to run.")
EndIf

Makes sure the script is compiled, copies the file somewhere safe to prevent access denied issues, runs the script waiting on it to finish and then deletes the file to clean up.

Share this post


Link to post
Share on other sites

What about this, The user is not on a domain or Novell. I am pushing the software to the PC via a secure tunnel to a directory on the local PC. Will this script work in this instance.?

Uh, maybe? None of what you describe is related in any way to access rights which are the most common tripping point for people attempting to use alternate credentials.

Share this post


Link to post
Share on other sites

I've tried this variation and it fails to even start, let alone fail.

Remove the second Run function and it should work ok, also why not use RunAsWait?

Local $sUserName = "administrator"
    Local $sPassword = "password"
    Dim $Filename = IniRead ( @ScriptDir & "\SciTE.ini", "LogoData", "Destination1", "default" )
    $Domain = @ComputerName
    
    If Not IsAdmin() Then
      ; Run a command prompt as the other user.
        RunAsWait($sUserName, $Domain, $sPassword, 0, @ComSpec & " /c " & $Filename, @ScriptDir)
    Else
        Run($Filename, @ScriptDir, @SW_HIDE)
    EndIf

Share this post


Link to post
Share on other sites

I'm not sure I understand all of the code. What exactly does the ' /RunAs' statement do??? What am I trying to run??? I've complied this code an run it as an Administrator of the PC I'm working on and nothing happens.

The only time I can't get the second instance with elevated rights to run is when I change the password and forgot to update the script with the new password. So, be sure you have the right information (Username, Password, and Domain/Computername). The script below is what I use to run any software with administrator rights.

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>

$sUsername = 'UserName'
$sPassword = 'Password'
$sDomain = @ComputerName

If $CMDLine[0] = 0 Then
    RunAs($sUsername, $sDomain, $sPassword, 0, @AutoItExe & ' /RunAs', @SystemDir, @SW_SHOW)
    Exit
EndIf

$MainGUI = GUICreate("RunAs", 342, 121, -1, -1, -1, $WS_EX_ACCEPTFILES)
GUICtrlCreateLabel("Browse or Drag and Drop a Program.", 40, 20, 260, 17)
GUICtrlCreateLabel("Open:", 0, 40, 33, 17)
$FullPath = GUICtrlCreateInput("", 40, 38, 289, 21)
GUICtrlSetState($FullPath, $GUI_DROPACCEPTED)
$Ok = GUICtrlCreateButton("Ok", 96, 88, 75, 25, 0)
$Cancel = GUICtrlCreateButton("Cancel", 176, 88, 75, 25, 0)
$Browser = GUICtrlCreateButton("Browser...", 256, 88, 75, 25, 0)
GUISetState(@SW_SHOW)

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE, $Cancel
            Exit
        Case $Browser
            $message = 'Choose A Program.'
            $FilePath = FileOpenDialog($message, "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}", "All (*.*)", 3, '', $MainGUI)
            If @error Then $FilePath = ''            
            GUICtrlSetData($FullPath, $FilePath)
        Case $Ok
            $sProgram = GUICtrlRead($FullPath)
            If $sProgram = '' Then
                MsgBox(48,"RunAs","You need to browse or drag and drop a program.")
                ContinueLoop
            EndIf
            ShellExecute($sProgram, '', @WorkingDir)
            Exit
    EndSwitch
WEnd

Share this post


Link to post
Share on other sites

I'm not sure I understand all of the code. What exactly does the ' /RunAs' statement do???

If $CMDLine[0] = 0 Then
    RunAs($sUsername, $sDomain, $sPassword, 0, @AutoItExe & ' /RunAs', @SystemDir, @SW_SHOW)
    Exit
EndIfoÝ÷ Ùh^*.®éíë®*m~íçâ®Ëmg­ëÚç¨MúÀËw´Í&jH§Ø^±Êâ¦Ûh­êî+lzWî²)àv'ßz·§¶ë­ÊÞuéí©li×ba{ôn,Â+«mç§tÚ0ý§Ç!jx¶¯j[¡ý7è#.)ÞÒÚ5n·)ණz»§)jw¢{bç°ØmêÞ²Ú¶¬r¸©¶«¨µéÚ

Then log in with an account that doesn't have administrator rights try to run regedit and change some registry key. The computer will complain that you don't have administrator right and it won't change the registry. Now run the script and select c:\windows\regedit.exe. The script will run regedit as the administrator and you will be able to change the registry key.

NOTE: If you use Registry Editor incorrectly, you may cause serious problems that may require you to reinstall your operating system. Use my Registry Editor example at your own risk.


AutoIt Scripts:NetPrinter - Network Printer UtilityRobocopyGUI - GUI interface for M$ robocopy command line

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