5

I'm trying to call a function in a powershell file as follows:

    string script = System.IO.File.ReadAllText(@"C:\Users\Bob\Desktop\CallPS.ps1");

    using (Runspace runspace = RunspaceFactory.CreateRunspace())
    {
        runspace.Open();
        using (Pipeline pipeline = runspace.CreatePipeline(script))
        {
            Command c = new Command("BatAvg",false); 
            c.Parameters.Add("Name", "John"); 
            c.Parameters.Add("Runs", "6996"); 
            c.Parameters.Add("Outs", "70"); 
            pipeline.Commands.Add(c); 

            Collection<PSObject> results = pipeline.Invoke();
            foreach (PSObject obj in results)
            {
                // do somethingConsole.WriteLine(obj.ToString());
            }
        }
    }

The powershell function is in CallPS.ps1:

Function BatAvg
{
    param ($Name, $Runs, $Outs)
    $Avg = [int]($Runs / $Outs*100)/100 
    Write-Output "$Name's Average = $Avg, $Runs, $Outs "
}

I'm getting the following exception:

The term 'BatAvg' is not recognized as the name of a cmdlet, function, script file, or operable program.

What am I doing wrong, I admit, I know very little about PowerShell.

3 Answers 3

8

This seems to work for me:

using (Runspace runspace = RunspaceFactory.CreateRunspace())
{
    runspace.Open();
    PowerShell ps = PowerShell.Create();
    ps.Runspace = runspace;
    ps.AddScript(script);
    ps.Invoke();
    ps.AddCommand("BatAvg").AddParameters(new Dictionary<string, string>
    {
        {"Name" , "John"},
        {"Runs", "6996"},
        {"Outs","70"}
    });

    foreach (PSObject result in ps.Invoke())
    {
        Console.WriteLine(result);
    }
}
Sign up to request clarification or add additional context in comments.

Comments

1

As it seems the Runspace need to be connected to a Powershell to make that work - see the sample code at MSDN.

1 Comment

Nope, still get the same exception: runspace.Open(); PowerShell ps = PowerShell.Create(); ps.Runspace = runspace; ps.AddScript(script); Command c = new Command("BatAvg",false); ps.AddCommand("BatAvg",false); ps.AddParameter("Name", "John"); ps.AddParameter("Runs", "6996"); ps.AddParameter("Outs", "70"); foreach (PSObject obj in ps.Invoke()) { // do somethingConsole.WriteLine(obj.ToString()); }
1

The solution can be simplified further as in this case a non-default Runspace is not needed.

var ps = PowerShell.Create();
ps.AddScript(script);
ps.Invoke();
ps.AddCommand("BatAvg").AddParameters(new Dictionary<string, string>
{
     {"Name" , "John"}, {"Runs", "6996"}, {"Outs","70"}
});
foreach (var result in ps.Invoke())
{
     Console.WriteLine(result);
}

One other pitfall would be to use AddScript(script, true) in order to use a local scope. The same exception would be encountered (i.e. "The term 'BatAvg' is not recognized as the name of a cmdlet, function, script file, or operable program.").

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.