How can I execute a batch/exe/ps1 files on client from the server?

Anand Anilkumar Nair 21 Reputation points

I have a web appllication made using I have a function to start the process from my web app.

System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.FileName = Server.MapPath("~/ScriptFiles/" + app.Location);

It works fine as expected when I debug using Visual Studio, but when I deployed it using IIS from the server, it doesn't execute the process in the client PC.
I have searched in many forums and it says it is as expected as it's a security issue if you are able to execute an exe on a client side.
But for my case I'm doing a web application in a corporate network, so the webapp requirement is to remotely install softwares at client pc from the batch files in the server.

Is there any way I can execute the script files in the client PC

A set of technologies in the .NET Framework for building web applications and XML web services.
4,235 questions
Windows Server
Windows Server
A family of Microsoft server operating systems that support enterprise-level management, data storage, applications, and communications.
12,271 questions
Windows Server PowerShell
Windows Server PowerShell
Windows Server: A family of Microsoft server operating systems that support enterprise-level management, data storage, applications, and communications.PowerShell: A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
5,404 questions
0 comments No comments
{count} votes

Accepted answer
  1. MotoX80 32,246 Reputation points

    Is it possible to see the powershell or cmd window when we start the process?

    Not from the browser window. Remember, you have 3 machines involved here. PC-1 running Edge/Chrome browsing a site on PC-2 running IIS, w3wp.exe, which launches a Powershell.exe subprocess which does a WinRM (Invoke-Command) call to PC-3 where svchost.exe processes the call and launches the ultimate setup.exe (or whatever) for the app you want to install.

    The basic issue here is that you are trying to live in 2 different worlds. There is the classic desktop world where a process runs in the context of a user and GUI programs and message boxes and prompts to get input, all work.

    Then there is the non-interactive world of services and background applications like IIS. GUI's and prompts don't work here. Using IIS to front end processes is a great idea. I build a number of web sites to do various functions at the place I used to work at. But you have to understand that the web site is the user interface in that environment.

    Let's say that you have a PS script to install MS Office. And it prompts the user to select the components to install; Word, Excel, etc. It works fine in the desktop world, but you need to modify it for the non-interactive world. There is no one there to "click ok to continue". On the ASPX page for "Office Install", you need to add controls and text boxes to gather the install details. Then when you launch Powershell.exe you would pass that information as script parameters to execute on PC-3. That needs to be a silent install that uses stdout and stderr to return success or failure messages to PC-2 and ultimately back to the user on PC-1.

    Let's try this; check your IIS config. Do you know how to find the application pool for your site? Check to see if it's set to run as the system account. See if you can set it to your account so that whoami.exe returns your account instead of system. If you get that to work, then try running Powershell to do an invoke-command on remote system and return something trivial like $env:COMPUTERNAME.

    If that works, then you have admin access to PC-3 and you can run anything that you want. If you don't want to change your existing scripts, you could run "schtasks.exe /create /TN OfficeInstall /RU interactive /tr \server\share\OurStuff\whatever.exe" and run the script in the context of whoever is logged on to the desktop. (But they would also need admin authority to do an app install...)

    Long term you would not want to use your own account for the app pool. You should get a dedicated account for that. Or get impersonation working and overcome the IIS double hop problem which is what I'm trying to have you avoid at the moment.

    And you would still need to implement some kind of user authentication test so that only members of your team can access the web site.


2 additional answers

Sort by: Most helpful
  1. Carlos de Souza Jr 76 Reputation points

    You can use remote PowerShell. It could work in small companies environments, but for big companies I would like recommend you Endpoint Management like Microsoft SCCM or Intune if you have Windows 10 with Office 365 licenses.

  2. MotoX80 32,246 Reputation points

    it doesn't execute the process in the client PC.

    Your process.Start(); statement is only going to launch the process on the local system (web server).

    As Carlos noted, you can use Powershell, but you will need to build a script that executes a "Invoke-Command -ComputerName ClientPcName ...etc". The client PCwill nede to have WinRM set up to allow remote connections.

    Another way is to use the Sysinternals tool PSExec.

    PsExec executes a program on a remote system, where remotely executed console
    applications execute interactively.
    Usage: psexec [\computer[,computer2[,...] | @Gaydamak ]][-u user [-p psswd][-n s][-r servicename][-h][-l][-s|-e][-x][-i [session]][-c [-f|-v]][-w directory][-d][-<priority>][-a n,n,...] cmd [arguments]
    -a Separate processors on which the application can run with
    commas where 1 is the lowest numbered CPU. For example,
    to run the application on CPU 2 and CPU 4, enter:
    "-a 2,4"
    -c Copy the specified program to the remote system for
    execution. If you omit this option the application
    must be in the system path on the remote system.
    -d Don't wait for process to terminate (non-interactive).
    -e Does not load the specified account's profile.
    -f Copy the specified program even if the file already
    exists on the remote system.
    -i Run the program so that it interacts with the desktop of the
    specified session on the remote system. If no session is
    specified the process runs in the console session.
    -h If the target system is Vista or higher, has the process
    run with the account's elevated token, if available.
    -l Run process as limited user (strips the Administrators group
    and allows only privileges assigned to the Users group).
    On Windows Vista the process runs with Low Integrity.
    -n Specifies timeout in seconds connecting to remote computers.
    -p Specifies optional password for user name. If you omit this
    you will be prompted to enter a hidden password.
    -r Specifies the name of the remote service to create or interact.
    -s Run the remote process in the System account.
    -u Specifies optional user name for login to remote
    -v Copy the specified file only if it has a higher version number
    or is newer on than the one on the remote system.
    -w Set the working directory of the process (relative to
    remote computer).
    -x Display the UI on the Winlogon secure desktop (local system
    -arm Specifies the remote computer is of ARM architecture.
    -priority Specifies -low, -belownormal, -abovenormal, -high or
    -realtime to run the process at a different priority. Use
    -background to run at low memory and I/O priority on Vista.
    computer Direct PsExec to run the application on the remote
    computer or computers specified. If you omit the computer
    name PsExec runs the application on the local system,
    and if you specify a wildcard (\
    ), PsExec runs the
    command on all computers in the current domain.
    @Gaydamak PsExec will execute the command on each of the computers listed
    in the file.
    cmd Name of application to execute.
    arguments Arguments to pass (note that file paths must be
    absolute paths on the target system).
    -accepteula This flag suppresses the display of the license dialog.
    -nobanner Do not display the startup banner and copyright message.*

    The next big issue that you face is authenticating to the client PC with Administrator level credentials. The easiest way it pass a userid and password to psexec using -u and -p switches.

    Your process.start() would launch something like:

    C:\Utilities\psexec.exe \\clientpcname -accepteula -u admin -p adminpswd  C:\Folder-on-client\app.exe"   

    Read about the -c switch if you need to copy the executable from the web server to the client.

    Also note that the code should all be command line stuff because this is all unattended execution. There is no user to click on ok. Your ASPX code should capture stdout and stderr and display the results back to the browser. Psexec can launch processes in the context of the desktop user using the -i switch, but you should not rely on a user being there to interact with the process.

    Be sure to specify -accepteula otherwise psexec will hang expecting you to acknowledge the license agreement, but you will have no way to do that.

    Put the admin id+pswd in your web.config and have your site pull it from there. You have to use an account that has administrator access to the client pc.

    If you want to use the credentials of the browser user instead of using -u and -p, then you'll need to configure IIS to impersonate the user on the site. And that user will still need to have admin access to the client PC.