I am using Microsoft.PowerShell.5.1.ReferenceAssemblies to run some powershell scripts.
    private void RunScript(string command)
    {
        var runspace = RunspaceFactory.CreateRunspace();
        runspace.Open();
        var builder = new StringBuilder();
        var task = new Task(() => {
            var pipeline = runspace.CreatePipeline();
            pipeline.Commands.AddScript(command);
            try
            {
                var result = pipeline.Invoke();
                foreach (var r in result)
                {
                    builder.Append(r.ToString());
                }
            }
            catch (Exception e)
            {
                builder.Append(e);
            }
            runspace.Close();
            var consoleOutput = builder.ToString();
            runspace.Dispose();
        });
        psScriptsRunning.Add(runspace);
        task.Start();
    }
I keep track of the runspaces in psScriptsRunning. So when my app is closed, I go through and close the runspaces.
    public void deinit()
    {
        foreach(var runspace in psScriptsRunning)
        {
            runspace.Dispose();   
        }
    }
This has the effect of closing the powershell scripts and any processes it has spawned. However seems like it takes a while to actually close the processes, if you have a better way to improve this, please let me know.
However, if someone kills my app from Task Manager, this code will not run. How can I kill any processes launched by the powershell scripts?
Previously before supporting powershell scripts directly via runspaces, I used to create a process and launch via powershell.exe.
I was able to make sure any processes spawned were killed by using job objects see Kill child process when parent process is killed.
Now that I am using runspaces, how can I achieve the same ?
The reason I went with runspaces instead of using powershell.exe was due to better launching times of the powershell scripts.