3 Comments

 

You van execute a process on an other machine from C#, by using the code below:

 

Example for calling the function

var rc = new RemotingComponent(null);
rc.RunRemoteProcess
(
    @"MyMachine1", 
    "MyMachine1\Administrator", 
    "MyPassword1", 
    @"C:\Windows\System32\notepad.exe",
    string.Empty
 );

C# class

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Security;
using System.Text;

namespace Research
{
    public interface IRemotingComponent
    {
        void RunRemoteProcess(string machineName, string userName, string password, string processPath, string processArguments);
    }

    public class RemotingComponent : IRemotingComponent
    {
        public void RunRemoteProcess(string machineName, string userName, string password, string processPath, string processArguments)
        {
            var connectTo = new Uri(String.Format("http://{0}:5985/wsman", machineName));

            _logger.Info("Building powershell command.");
            var command = new StringBuilder();
            command.AppendLine("$pinfo = New-Object System.Diagnostics.ProcessStartInfo");
            command.AppendLine(string.Format(@"$pinfo.FileName = ""{0}""", processPath));
            command.AppendLine("$pinfo.UseShellExecute = $false");
            command.AppendLine("$pinfo.RedirectStandardError = $true");
            command.AppendLine("$pinfo.RedirectStandardOutput = $true");
            command.AppendLine("$pinfo.CreateNoWindow = $true");
            command.AppendLine(string.Format(@"$pinfo.WorkingDirectory = ""{0}""", new FileInfo(processPath).Directory.FullName));
            command.AppendLine(string.Format(@"$pinfo.Arguments = ""{0}""", processArguments));
            command.AppendLine("$p = New-Object System.Diagnostics.Process");
            command.AppendLine("$p.StartInfo = $pinfo");
            command.AppendLine("$p.Start() | Out-Null");
            command.AppendLine("$output = $p.StandardOutput.ReadToEnd()");
            command.AppendLine("$p.WaitForExit()");
            command.AppendLine("$output");
            
            string shell = @"http://schemas.microsoft.com/powershell/Microsoft.PowerShell";
            using (var passing = new SecureString())
            {
                foreach (char c in password.ToCharArray())
                {
                    passing.AppendChar(c);
                }
                passing.MakeReadOnly();
                var credentials = new PSCredential(userName, passing);

                var connection = new WSManConnectionInfo(connectTo, shell, credentials);
                using (var runspace = RunspaceFactory.CreateRunspace(connection))
                {
                    runspace.Open();

                    using (var powershell = PowerShell.Create())
                    {
                        powershell.Runspace = runspace;
                        powershell.AddScript(command.ToString());

                        var results = powershell.Invoke();
                        runspace.Close();

                        foreach (var obj in results.Where(o => o != null))
                        {
                            Console.Writeline(string.Format("Output: [{0}].", obj));
                        }
                    }
                }
            }
        }
    }
}

3 Replies to “How to start a process / application on an other computer from C#, by using PowerShell remoting

  1. This seems to start a process, but not a visible application. Same way as the WMI solutions do. How to start a visible process?

  2. I am using a ”Connect-MSolService” method with it’s credentials, but I have missed a runspace.Close(); line of code for a couple of minutes.
    For a period of time it worked properly.
    But now this command (I guess!), is trying to open a dialog on Server side.

    Is this ”runspace.Close();” causing the problem?

  3. Use TaskScheduler. Or, do what PSExec does:
    Create a new service on the remote machine, allow the service to interact with the desktop, have the service get the user’s session token and Winsta, then either impersonate the logged on user (or use System) to run your remote program.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Related Posts