17

I have a PS1 file with multiple Powershell functions in it. I need to create a static DLL that reads all the functions and their definitions in memory. It then invokes one of these functions when a user calls the DLL and passes in the function name as well as the parameters for the function.

My question is, is it possible to do this. ie call a function that has been read and stored in memory?

Thanks

Sean
  • 171
  • 1
  • 1
  • 3
  • If you'd like to execute powershell in .NET Core, look at [https://stackoverflow.com/questions/39141914/running-powershell-from-net-core](https://stackoverflow.com/questions/39141914/running-powershell-from-net-core) – Sielu Jan 22 '18 at 10:29

2 Answers2

19

Here's the equivalent C# code for the code mentioned above

string script = "function Test-Me($param1, $param2) { \"Hello from Test-Me with $param1, $param2\" }";

using (var powershell = PowerShell.Create())
{
    powershell.AddScript(script, false);

    powershell.Invoke();

    powershell.Commands.Clear();

    powershell.AddCommand("Test-Me").AddParameter("param1", 42).AddParameter("param2", "foo");

    var results = powershell.Invoke();
}
George
  • 303
  • 2
  • 7
Amr Reda
  • 632
  • 7
  • 18
  • I tried implementing this, but am having trouble. I am using WinUI 3. I posted a separate question here about it with details: https://stackoverflow.com/questions/70843636/how-to-call-powershell-functions-from-c-sharp-in-winui-3 – Michael Kintscher they-them Jan 25 '22 at 05:02
5

It is possible and in more than one ways. Here is probably the simplest one.

Given our functions are in the MyFunctions.ps1 script (just one for this demo):

# MyFunctions.ps1 contains one or more functions

function Test-Me($param1, $param2)
{
    "Hello from Test-Me with $param1, $param2"
}

Then use the code below. It is in PowerShell but it is literally translatable to C# (you should do that):

# create the engine
$ps = [System.Management.Automation.PowerShell]::Create()

# "dot-source my functions"
$null = $ps.AddScript(". .\MyFunctions.ps1", $false)
$ps.Invoke()

# clear the commands
$ps.Commands.Clear()

# call one of that functions
$null = $ps.AddCommand('Test-Me').AddParameter('param1', 42).AddParameter('param2', 'foo')
$results = $ps.Invoke()

# just in case, check for errors
$ps.Streams.Error

# process $results (just output in this demo)
$results

Output:

Hello from Test-Me with 42, foo

For more details of the PowerShell class see:

http://msdn.microsoft.com/en-us/library/system.management.automation.powershell

Roman Kuzmin
  • 40,627
  • 11
  • 95
  • 117
  • 9
    The question is how to do it in c# and you answer how to do it in powershell and tell him to translate it himself into c#? I get that it's not teribly difficult, but really? – Eric Brown - Cal May 30 '12 at 17:59
  • @Eric Brown - Cal - this is your understanding of the question. My understanding is different - what PowerShell API methods should be called from C#, VB.NET, F#, any .NET language. – Roman Kuzmin May 30 '12 at 18:39
  • 6
    Am I confused? is the title not "Calling Powershell functions from C#". Did I miss something? – Eric Brown - Cal May 30 '12 at 18:46
  • 1
    Is this a question in the title? The question is: "My question is, is it possible to do this. ie call a function that has been read and stored in memory?". – Roman Kuzmin May 30 '12 at 18:50