Reputation: 103
I am attempting to write a C# core program to run powershell scripts on remote linux systems. Running on .net core is a requirement for this project. I am trying to loosely follow a guide I found on CodeProject.
This is my code:
using System;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
SSHConnectionInfo connectionInfo = new SSHConnectionInfo(userName: "user", computerName: "server", keyFilePath: "id_rsa");
using (Runspace runspace = RunspaceFactory.CreateRunspace(connectionInfo))
{
runspace.Open(); // The program errors out here
runspace.Close();
}
}
}
}
I have the "id_rsa" file located int the same folder as the program. I have verified that openssh for windows, powershell core 6.0.2, and .net core 2 SDK are installed and working. I am using the following nuget packages from the Microsoft Powershell Core repository: Microsoft.PowerShell.SDK (6.0.2) and Sytem.Managment.Automation (6.0.2)
This is the error I am receiving:
Unhandled Exception: System.Management.Automation.Remoting.PSRemotingDataStructureException: An error has occurred which PowerShell cannot handle. A remote session might have ended. ---> System.ArgumentException: The path is not of a legal form.
Parameter name: path
at System.IO.Path.GetDirectoryName(String path)
at System.Management.Automation.Runspaces.SSHConnectionInfo.StartSSHProcess(StreamWriter& stdInWriterVar, StreamReader& stdOutReaderVar, StreamReader& stdErrReaderVar)
at System.Management.Automation.Remoting.Client.SSHClientSessionTransportManager.CreateAsync()
at System.Management.Automation.Remoting.ClientRemoteSessionDSHandlerImpl.SendNegotiationAsync(RemoteSessionState sessionState)
at System.Management.Automation.Remoting.ClientRemoteSessionDSHandlerImpl.HandleStateChanged(Object sender, RemoteSessionStateEventArgs arg)
at System.Management.Automation.ExtensionMethods.SafeInvoke[T](EventHandler`1 eventHandler, Object sender, T eventArgs)
at System.Management.Automation.Remoting.ClientRemoteSessionDSHandlerStateMachine.RaiseStateMachineEvents()
at System.Management.Automation.Remoting.ClientRemoteSessionDSHandlerStateMachine.ProcessEvents()
--- End of inner exception stack trace ---
at System.Management.Automation.Runspaces.AsyncResult.EndInvoke()
at System.Management.Automation.Runspaces.Internal.RunspacePoolInternal.EndOpen(IAsyncResult asyncResult)
at System.Management.Automation.Runspaces.Internal.RemoteRunspacePoolInternal.Open()
at System.Management.Automation.RemoteRunspace.Open()
at ConsoleApp1.Program.Main(String[] args) in C:\ConsoleApp1\ConsoleApp1\Program.cs:line 18
Press any key to continue . . .
At this point I am not sure what I am missing.
Upvotes: 2
Views: 1539
Reputation: 807
The following answer is derived from the Bruc3 work-around answer above and the RemoteRunspace Sample 01 from the Powershell SDK.
namespace Sample.PowerShell.Runspace
{
using System;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
/// <summary>
/// This class contains the Main enrty point for the application.
/// </summary>
internal class SshRemoteRunspace
{
public static void Main(string[] args)
{
SSHConnectionInfo sshConnectionInfo = new
SSHConnectionInfo("Administrator", "remote-hyper-v-server.mydomain.com", @"C:\Users\myself\.ssh\id_ed25519.pub");
// Bruc3 Workaround
if (System.Management.Automation.Runspaces.Runspace.DefaultRunspace is null)
{
var defaultRunspace = RunspaceFactory.CreateRunspace();
defaultRunspace.Open();
System.Management.Automation.Runspaces.Runspace.DefaultRunspace = defaultRunspace;
}
// Create a remote runspace using the connection information.
using (Runspace remoteRunspace = RunspaceFactory.CreateRunspace(sshConnectionInfo))
{
remoteRunspace.Open();
// Powershell command
using (PowerShell powershell = PowerShell.Create().AddCommand("Get-VMReplication"))
{
// makes the Powershell command run in the remote runspace instead of locally
powershell.Runspace = remoteRunspace;
// display the results in the local console
foreach (PSObject result in powershell.Invoke())
{
Console.WriteLine(result.ToString());
}
}
Console.WriteLine("Press 'Enter' to exit > ");
Console.ReadKey();
remoteRunspace.Close();
}
}
}
}
Upvotes: 0
Reputation: 103
I ended up opening an issue on github for this error. To work around this issue currently you will need to add the following code to your program until this issue gets resolved in a future version of powershell core (>6.0.4 or >6.1.0-rc.1). Here is the specific post regarding the issue.
if (System.Management.Automation.Runspaces.Runspace.DefaultRunspace == null)
{
var defaultRunspace = RunspaceFactory.CreateRunspace();
defaultRunspace.Open();
System.Management.Automation.Runspaces.Runspace.DefaultRunspace = defaultRunspace;
}
Upvotes: 1