That console app is just repro'ing what PowerShell Remoting is doing or what MS SysInternals psexec is doing.
Why recreate this?
I get it's a requirement, but it's an over complication that you not have to manage, long term.
This just sounds like PSRemoting is not enabled, hence the reason for this console app.
Anyway, you are going to still instantiate the PowerShell host to run PowerShell stuff. So, you are just hosting PowerShell in your C# app.
Running PowerShell from C# is a common thing and very well documented. A quick search would give you lots of hits and samples to leverage.
How to run PowerShell scripts from C#
Calling C# code in Powershell and vice versa
add the following 'using' statements to import the required types:
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
The following code block shows the RunScript method that does all the
hard work. It takes the script text, executes it, and returns the
result as a string.
private string RunScript(string scriptText)
{
// create Powershell runspace
Runspace runspace = RunspaceFactory.CreateRunspace();
// open it
runspace.Open();
// create a pipeline and feed it the script text
Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.AddScript(scriptText);
// add an extra command to transform the script
// output objects into nicely formatted strings
// remove this line to get the actual objects
// that the script returns. For example, the script
// "Get-Process" returns a collection
// of System.Diagnostics.Process instances.
pipeline.Commands.Add("Out-String");
// execute the script
Collection<psobject /> results = pipeline.Invoke();
// close the runspace
runspace.Close();
// convert the script result into a single string
StringBuilder stringBuilder = new StringBuilder();
foreach (PSObject obj in results)
{
stringBuilder.AppendLine(obj.ToString());
}
return stringBuilder.ToString();
}
How to Let the Script Interact with your Program
Before executing the script using the pipeline.Invoke() call, it's
possible to expose the objects of your program to the script by using
the method runspace.SessionStateProxy.SetVariable("someName",
someObject).
This will create a named variable that the script can access
(getting/setting properties, and even calling methods).
As an example, suppose we would expose the main form of the sample to
the script by adding the SetVariable() call like this:
...
// open it
runspace.Open();
runspace.SessionStateProxy.SetVariable("DemoForm", this);
....
Then, the following script would print the caption of the window:
$DemoForm.Text
The following script would show all the properties and methods of the window:
$DemoForm | Get-Member
Please note, however, that any calls a script makes to your objects
will be from another thread context, as pipeline.Invoke() seems to
start its own worker thread. This means that your exposed objects will
have to be thread-safe.
This could even be seen as a duplicate of this Q&A
Run PowerShell-Script from C# Application
Update for the OP
As for ...
The c# console app is required to act like the center to process
several .ps1 script files,
So, the C# app is the C&C, replacing a PSRemoting / PSExec session.
Yet, you don't say where the script files are or how you plan on getting them to the remote systems.
but first it needs to access the remote machine first.
Which is what PSRemoting ...
$s = New-PSSession -ComputerName (Get-Content Servers.txt) -Credential Domain01\Admin01
Invoke-Command -Session $s -ScriptBlock {
# Run these PowerShell commands or scripts.
Get-Process PowerShell
}
Or as a background job
$s = New-PSSession -ComputerName (Get-Content Servers.txt) -Credential Domain01\Admin01
Invoke-Command -Session $s -ScriptBlock {
# Run these PowerShell commands or scripts.
Get-Process PowerShell
} -AsJob
and PSExec does.
psexec \RemotePCName [-u username[-p password]] command [arguments]
As for ...
Only after all .ps1 files ran successfully, it should be logged out
from the remote machine and return the any output to the console.
Again, exactly what PSRemoting and PSExec does.
That's why I'm thinking to connect remote using c# first, then
followed by calling all the .ps1 files.
Your console app simply has to do the above. This is doable, as thing as noted by these Q&A's, well, there just using command, not calling scripts, but the same rules apply...
Execute powershell script on a remote computer using C#
Invoke remote powershell command from C#
Example:
InitialSessionState initial = InitialSessionState.CreateDefault();
Runspace runspace = RunspaceFactory.CreateRunspace(initial);
runspace.Open();
PowerShell ps = PowerShell.Create();
ps.Runspace = runspace;
ps.AddCommand("invoke-command");
ps.AddParameter("ComputerName", "mycomp.mylab.com");
ScriptBlock filter = ScriptBlock.Create("Get-childitem C:\\windows");
ps.AddParameter("ScriptBlock", filter);
foreach (PSObject obj in ps.Invoke())
{
// Do Something
}
but again, it’s just repro’ing the above. So, Yeppers, it’s a choice. Use PSRemoting, use PSExec, build a different solution.