How to execute program on remote computer?

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:

Naveen said...

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

gauri said...

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

Dmitry Motevich said...

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.

Dmitry Motevich said...

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

ralnaser said...

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

Dmitry Motevich said...

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?

Anonymous said...

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!

Dmitry Motevich said...

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").

Anonymous said...

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.

Dmitry Motevich said...

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

Praveen said...

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

Dmitry Motevich said...

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.

David said...

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?

Dmitry Motevich said...

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

Jegu said...

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

Thanks.

Dmitry Motevich said...

@Jegu,
Answered in above comments

jerry said...

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

Dmitry Motevich said...

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

Anonymous said...

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!

JasonRene said...

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

JasonRene said...

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

Dmitry Motevich said...

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

Dmitry Motevich said...

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

Praveen said...

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

Dmitry Motevich said...

@Praveen,
Not possible.

RrD said...

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

Anonymous said...

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

Anonymous said...

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.

Anonymous said...

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.

Anonymous said...

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.

Anonymous said...

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.

Dmitry Motevich said...

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.