I'm attempting to create a function which will take in specified .ps1 file which is embedded within my project, but I'm not quite sure how to change my code around to cater for this.
I've written this in my new .NET 6 C# WPF application based on a VB.net legacy application that does similar stuff:
using System;
using System.Linq;
using System.Management.Automation.Runspaces;
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Windows;
public class PowerShellStuff
{
private readonly string PS_UserName = "";
private readonly string PS_Password = "";
private Runspace? runspace;
private PowerShell? pipeline;
public void ConnectToExchange()
{
System.Security.SecureString securePassword = new System.Security.SecureString();
foreach (char c in PS_Password)
{
securePassword.AppendChar(c);
}
PSCredential? credential = new(PS_UserName, securePassword);
WSManConnectionInfo? connectionInfo = new(new Uri("https://outlook.office365.com/powershell-liveid/"), "http://schemas.microsoft.com/powershell/Microsoft.Exchange", credential)
{
AuthenticationMechanism = AuthenticationMechanism.Basic,
MaximumConnectionRedirectionCount = 2
};
using (runspace = RunspaceFactory.CreateRunspace(connectionInfo))
{
using (pipeline = PowerShell.Create())
{
runspace.Open();
pipeline.Runspace = runspace;
}
}
}
public Collection<PSObject> RunScript(PSCommand command)
{
if (runspace == null)
{
try
{
ConnectToExchange();
pipeline = PowerShell.Create();
pipeline.Runspace = runspace;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "User Information", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
if (runspace.RunspaceStateInfo.State != RunspaceState.Opened)
runspace.Open();
pipeline.Commands.Clear();
Command comand = new Command(command.Commands[0].ToString());
for (int i = 0; i <= command.Commands[0].Parameters.Count - 1; i++)
comand.Parameters.Add(command.Commands[0].Parameters[i]);
pipeline.Commands.AddCommand(comand);
Collection<PSObject> results;
try
{
results = pipeline.Invoke();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "User Information", MessageBoxButton.OK, MessageBoxImage.Error);
}
return results;
}
}
This is how its used in VB.net:
Dim command As New PSCommand
command.AddCommand("").AddParameter("", "")...
RunScript(command)
The issue I am having is that I can't even get the above working in C# as it fails with Non-invocable member 'PSCommand.Commands' cannot be used like a method.
My goal is to have a function which I can use to populate a DataTable with results from the .ps1 script, e.g. DataTable dt = new DataTable(RunScript(Resources.MyScript.ps1))
and a function which will not return any data and just execute a SET command with few parameters, which I imagine would follow the same criteria as the VB.net code with command.AddCommand("").AddParameter("", "")...
Its my first time starting PowerShell in C# from scratch as in the past I only carried out simple changes in existing VB.net code, which I used as base to write this...
EDIT 1:
Clearly C# newbie... thanks to first two commenters the issue of executing the above code is resolved, but still unsure how to execute a .ps1 file using my existing runspace & pipeline and populate a DataTable.