1

Is there way to convert invoked powershell command from C# to string?.

Let's say for example i have something like this:

PowerShell ps = PowerShell.Create();
                    ps.AddCommand("Add-VpnConnection");
                    ps.AddParameter("Name", "VPN_" + ClientName);
                    ps.AddParameter("ServerAddress", VPN_SERVER_IP);
                    ps.AddParameter("AllUserConnection");
                    ps.AddParameter("SplitTunneling", true);
                    ps.AddParameter("TunnelType", "L2tp");

And i would like to save invoked command to log file.

Can i somehow return whole command as string?

mklement0
  • 382,024
  • 64
  • 607
  • 775
Johny Wave
  • 111
  • 2
  • 11
  • Given that PowerShell practically is C#, why write a c# app to call a ps script to connect a a DB? – Caius Jard Jul 13 '20 at 22:45
  • @CaiusJard Im not connecting to DB - im just creating VPN connection profile with powershell command, thats all and its part of bigger app and because of GUI ;-) – Johny Wave Jul 13 '20 at 22:53
  • You can use `AddScript` instead and add the command all at once. See my answer. I believe that it is what you are looking for. – Sage Pourpre Jul 13 '20 at 23:07

2 Answers2

1

I believe what you want essentially is this.

PowerShell ps = PowerShell.Create();
ps.AddScript($"Add-VpnConnection -Name \"VPN_{ClientName}\" -ServerAddress {VPNServerIP} -AllUserConnection -SplitTunneling -TunnelType L2tp");
ps.Invoke();

The invoke return will contain a collection of PSObject so you can read it and save the information like you want in a log in c#.

Sage Pourpre
  • 9,932
  • 3
  • 27
  • 39
  • Somehow i can return invoked WHOLE command from PSObject? Btw i use this cause its one string so i can save it into string variable and then pass it to this addscript method and into log i use string variable. Kind of workaround so thanks. – Johny Wave Jul 16 '20 at 19:13
0

Note: This answer does not solve the OP's problem. Instead, it shows how to capture a PowerShell command's output as a string in C#, formatted in the same way that the command's output would print to the display (console), if it were run in an interactive PowerShell session.


Out-String is the cmdlet that produces formatted, for-display representations of output objects as strings, as they would print to the screen in a PowerShell console.

Therefore, you simply need to use another .AddCommand() in order to pipe the output from your Add-VpnConnection call to Out-String:

string formattedOutput;
using (PowerShell ps = PowerShell.Create())
{

  ps.AddCommand("Add-VpnConnection")
    .AddParameter("Name", "VPN_" + ClientName)
    .AddParameter("ServerAddress")
    .AddParameter("AllUserConnection", VPN_SERVER_IP)
    .AddParameter("SplitTunneling", true)
    .AddParameter("TunnelType", "L2tp");

  // Add an Out-String call to which the previous command's output is piped to.
  // Use a -Width argument (column count) large enough to show all data.
  ps.AddCommand("Out-String").AddParameter("Width", 512);

  // Due to use of Out-String, a *single string* is effectively returned,
  // as the only element of the output collection.
  formattedOutput = ps.Invoke<string>()[0];

}

Console.Write(formattedOutput);
mklement0
  • 382,024
  • 64
  • 607
  • 775
  • @JohnyWave: I see - I've added a disclaimer to the top of the language; I think the answer may still be useful to future readers, who may come here based on the question's title. You don't need the PowerShell SDK to translate SDK calls into PowerShell command lines - all you need is an understanding of PowerShell's syntax. As Sage's answer shows, the SDK also allows you to call PowerShell command lines _directly_ - assuming that your [execution policy](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Execution_Policies) allows script execution. – mklement0 Jul 16 '20 at 22:14