2007-11-14

How to execute program on remote computer?

 
Several days ago I faced with a simple task - I had to execute program (automated QTP test in my case) on several remote computers.
My goal was simple - if I can execute scripts on my computer, then why don't we execute them on remote computers?


I think, this task is very interesting and practical, isn't it? :)

There was one condition. I tried to use "native" Windows solutions, which do not require additional installed software or libraries. I didn't want to use external soft, files, etc.

As a result, I found two solutions. Both of them use WMI:
  1. Win32_Process Class
  2. Win32_ScheduledJob Class
I will describe both of them.
Running ahead, I will say that I decided in favour of second solution (Win32_ScheduledJob class).


Let's explore these solutions, and compare them.
For clarity, I will show how to execute simple application (notepad.exe) on remote computer.

  1. Execute program on remote computer with Win32_Process сlass
    To create and start new process, I used Create method of the Win32_Process class.
    VBScript code is simple enough:

    1. strComputer = "."
    2. strCommand = "notepad.exe"

    3. Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
    4. Set objProcess = objWMIService.Get("Win32_Process")

    5. errReturn = objProcess.Create(strCommand, null, null, intProcessID)

    6. If errReturn = 0 Then
    7. Wscript.Echo "notepad.exe was started with a process ID: " & intProcessID
    8. Else
    9. Wscript.Echo "notepad.exe could not be started due to error: " & errReturn
    10. End If


    String strComputer = "." means "local computer".
    So, the result of notepad starting on my local computer was:
    And notepad started on my computer! Great!

    Then I tried execute my script on remote computer (I set strComputer = "servername"). The result was:
    Script said, that the process was created.
    Indeed, process was created. It was shown in Task Manager on remote computer:
    But I didn't see it on a desktop of remote computer!
    Further investigations shown, that:
    For security reasons the Win32_Process.Create method cannot be used to start an interactive process remotely.

    Win32_Process class is very useful to create and execute batch tasks on remote computer. But it can be applicable for interactive processes.

    That's why I preferred the second way. I mean Win32_ScheduledJob сlass.


  2. Execute program on remote computer with Win32_ScheduledJob сlass
    By analogy, to create and start new process, I used Create method of the Win32_ScheduledJob class.
    VBScript code is :

    1. strComputer = "."
    2. strCommand = "notepad.exe"

    3. Const INTERVAL = "n"
    4. Const MINUTES = 1

    5. Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
    6. Set objScheduledJob = objWMIService.Get("Win32_ScheduledJob")
    7. Set objSWbemDateTime = CreateObject("WbemScripting.SWbemDateTime")

    8. objSWbemDateTime.SetVarDate(DateAdd(INTERVAL, MINUTES, Now()))
    9. errReturn = objScheduledJob.Create(strCommand, objSWbemDateTime.Value, False, 0, 0, True, intJobID)

    10. If errReturn = 0 Then
    11. Wscript.Echo "notepad.exe was started with a process ID: " & intJobID
    12. Else
    13. Wscript.Echo "notepad.exe could not be started due to error: " & errReturn
    14. End If


    Create method of Win32_ScheduledJob сlass creates new scheduled job on computer. (Hm... Have I said a tautology? :) ) In script I specified the time when scheduled job should be executed - in one minute from now. For that i used standard VBScript function - DateAdd.

    Hint: Some time ago I wrote an article abount time/date functions in VBScript. Read it.

    The result of execution was excellent! It created
    scheduled jobs both on local and remote computer.
    This is result for remote computer is:

    In one minute, the notepad was started and shown on desktop of remote computer!
    I was happy :))


I hope, these two methods of remote application execution will be very helpful for you. Computer should calculate, human should think :)

So, I shown how to force your computers to work.
Do you have any ideas on how to force a human to think? :)

Summary:
If you have to run batch tasks, I think first method (Win32_Process Class) is simpler.
If you have to run interactive programs, use Win32_ScheduledJob Class.


--
Dmitry Motevich

32 comments:

  1. Hello Dmitry Motevich,

    I am Naveen Kamisetty. I am working as a Test Engineer for DB.I found your script in the net while i am searching for how to execute the script on the remote machine. The methods you specified is fine.They are working in the local machine but while i am speficying my remote address or machine name they are not working. I tried so many time.It stating that The remote server machine does not exist or is unavailable : 'GetObject'.This is the error i am getting while executing it. So could you please tell me the solution to resolve it. You can contact me on this mail-id: naveen.kamisetty@db.com.

    Thanks & Regards,
    Naveen

    ReplyDelete
  2. I have tried the code for exectuing scripts on remote machine with Win32_ScheduledJob class,but i am not able to see the notepad application on remote desktop whereas the notepad.exe can be seen from task manager of remote machine.Please suggest me the solution

    ReplyDelete
  3. 2Naveen:
    It seems, you do not have administrative rights on remote computer.
    Actually, it's difficult to answer, because you didn't provide the exact error message.

    ReplyDelete
  4. 2gauri:
    I guess, that you do not connect to the console session on your Terminal Server.
    Try open Remote Desktop Connection with "/console" parameter. Something like:
    C:\Windows\System32\mstsc.exe /console

    ReplyDelete
  5. Hello Dmitry Motevich,

    In your article you mention that to run an interactive process, one should use Win32_ScheduledJob Class.
    For me interactive process means that you can communicate with the process back and forth. In other words, you can invoke a command that might have an output response and that response can be sent back to the computer invoking the remote process. For example: on a CMD window you can invoke a TIME command that will return the time and prompt for new time entry. Can Win32_ScheduledJob Class return the current time on the remote machine to the local machine invoking the process?
    Basically what I need is to invoke remote process and get it's output. Is there a WMI class can help do that or do I have to look for alternatives?
    Thanks

    ReplyDelete
  6. 2ralnaser:
    "Interactive process" means a process which interacts with a end-user using UI.
    For example, Web server (Apache or IIS) isn't an interactive process, 'cause it just return HTML-page and does not provide any user interface for use.
    Opposite, browser is an interactive process, 'cause it deals with a user. User can see browser, click it, moove, etc.

    If you execute TIME command on remote computer using "Win32_ScheduledJob", it will be executed there. That means, that command line will be shown on remote computer.

    So, I you want to get time on remote computer, I recommend to read this article:
    How Can I Determine the System Time on a Computer?

    ReplyDelete
  7. This is suppose to be code sample for a REMOTE computer!!! Your sample code is for LOCAL!! Why didnt you include source code that references a remote computer?? thats what it is all about!!! Gee Wiz!

    ReplyDelete
  8. 2Gee Wiz,
    Variable 'strComputer' contains the name of remote server.
    So, use the following:
    strComputer = "srvname"
    and your command will be executed on "srvname" computer.

    Please, read carefully! I wrote the following in the article:
    String strComputer = "." means "local computer".
    ...
    Then I tried execute my script on remote computer (I set strComputer = "servername").

    ReplyDelete
  9. Is there a way to pass the script an account that has admin permissions on the remote server? The GetObject line returns me a "permission denied" error.

    ReplyDelete
  10. To Anonymous,
    This page explains how to connect to WMI on a remote computer and all related security settings.

    ReplyDelete
  11. Tried using Win32_ScheduledJob code snippet, but couldn't invoke Notepad on remote machine. Did all suggested security configurations but still couldn't make it work.

    Please suggest

    ReplyDelete
  12. 2Praveen,
    I would have helped you if you had provided detailed info...
    Did you get any error messages?
    Did you try to run 'notepad' with Win32_ScheduledJob on local computer?
    Do you have administrator rights on remote computer?
    Etc...

    Since you provided NOTHING, I cannot help you.

    ReplyDelete
  13. Hello Dmitry,

    Very nice article - thank you. I'm writing scripts to remote install programs which seem to require UI even though they are silent/unattended. Running under windows XP the interactive process spawns under the creator context as expected. When launching under Windows 2003 it spawns under the localsystem account unfortunately. There doesn't seem to be any way to set security for the win32_scheduledJob class :(. I'm thinking I might need to launch schtasks.exe processes unless you have a suggestion?

    ReplyDelete
  14. 2David,
    I answered this question several days ago. Please, read my above comment:
    here.

    ReplyDelete
  15. Hi,
    How will i specify the user account under which the exe should run?

    Thanks.

    ReplyDelete
  16. hi,can u please explain how to run an QTP application in an remote machine..

    ReplyDelete
  17. @jerry,
    Reread the above article.
    Replace notepad with QTP and you'll get an answer :)

    ReplyDelete
  18. This script is very nice. I was wondering if there was a way to set it up so it could have a command like

    thefile.vbs computername

    and have it run on computername.

    Otherwise great job!

    ReplyDelete
  19. Hey Dmitry, thanks for the post, it is very helpful. 2 questions:

    (1) The scheduled job approach succeeds in creating an interactive process, but then that scheduled job remains as a daily task on the remote machine. In your example, Notepad would open up every day! Do you have a suggestion for remotely and automatically removing the task that was created, after it executes the first time?

    (2) Your scheduled job approach uses the source system's date/time to start the task one minute after the call is made. However, if the target computer's date/time is out of sync and later than the source system, the scheduled job would wait nearly 24 hours before executing. Do you have a suggestion for determining the target system's date/time and then adding a minute onto that timestamp?

    Thanks,
    JasonRene

    ReplyDelete
  20. Actually upon closer review, I see that the scheduled job only runs once and then terminates, so please forgive my mistake on question #1. However, question #2 remains - if you have any suggestions on how to determine the timestamp of the target machine, I would appreciate it.
    - JasonRene

    ReplyDelete
  21. @Anonymous (November 7),
    You have to pass arguments to your script.
    Solutions are explained here and here.

    ReplyDelete
  22. @JasonRene (November 7),
    You can get time from a remote computer.
    The solution is explained here

    ReplyDelete
  23. Hi,

    This Post helped me a lot to run a batchfile in a remote system. i am trying to record a script in a remote system with QTP being in my local system. Is it Possible ?

    Please help !

    Thanks,
    Praveen

    ReplyDelete
  24. Win32_ScheduledJob spawns an interactive process on windows 2000 and stock XP only. On XP SP1 or higher, the process is not interactive.
    more info: http://msdn.microsoft.com/en-us/library/aa394399(VS.85).aspx

    ReplyDelete
  25. how can I use this script to run several apps in diferent servers?
    like a loop you know.

    ReplyDelete
  26. Hello Dmitry,

    I have attempted to run the Win32 Process job and am getting an error "2" on remote systems. The particular application I am running is a batch job froma file server.

    ReplyDelete
  27. The script works for me but is very inconsistent. Sometimes it will start the application other times it won't. I never get any errors when running the script itself.

    I thought it might be a time issue but I made sure that both systems were time synced to the same domain controller and even put up to a 3min delay.

    ReplyDelete
  28. Hi, I am using $objProcess->Create with credentials for an admin user. It starts the process ok but I need a way to receive the output of the command back to the computer starting it. Can that be done? Redirecting the output using "myCmd > \\uncshare\data\output.txt" does not work for me.

    ReplyDelete
  29. Hello Dmitry,
    I am trying to execute an exe residing in a server, on the client machine using vbs. Your code shows how to start a process in a remote machine.
    Could you help me on how to run an exe on the client machine?
    Thanks in advance.

    ReplyDelete
  30. Dear Readers!
    Thank you very much for you comments!

    Since this article was published more than one year ago, I've just disabled an adding of new comments for the article.

    ReplyDelete