0

I am trying to call Powershell script file with parameters in C# using the System.Management.Automation like this:

using (var ps = PowerShell.Create())
{
    try
    {
        var script = System.IO.File.ReadAllText("MyPsFile.ps1");
        ps.Commands.AddScript(script);
         ps.AddScript(script);
        ps.AddParameter("MyKey1", value1);
        ps.AddParameter("MyKey2", value2);
        var results = ps.Invoke();
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex.Message);
    }
}

The Powershell file looks like this:

function MyFunction {
    Param (
        [Parameter(Mandatory=$true)][string] $MyKey1,
        [Parameter(Mandatory=$true)][string] $MyKey1,
    )
    Process {        
      ..do some stuff
    }
}
MyFunction $args[0] $args[1]

If I run the script file inside Powershell like this:

powershell -file MyPsFile.ps1 "Value1" "Value2"

It works fine. But calling the file from within C# is not working. Any idea why?

So I have updated the code like this

var runspace = RunspaceFactory.CreateRunspace();
                    runspace.Open();

                    var runSpaceInvoker = new RunspaceInvoke(runspace);
                    runSpaceInvoker.Invoke("Set-ExecutionPolicy Unrestricted");

                    // create a pipeline and feed it the script text
                    var pipeline = runspace.CreatePipeline();
                    var command = new Command(@". .\MyScript.ps1");
                    command.Parameters.Add("MyParam1", value1);
                    command.Parameters.Add("MyParam2", value2);
                    pipeline.Commands.Add(command);

                    pipeline.Invoke();
                    runspace.Close();

But I am getting the error Powershell ps1 file “is not recognized as a cmdlet, function, operable program, or script file.”

I found this Powershell ps1 file "is not recognized as a cmdlet, function, operable program, or script file."

But it did not solve the problem. Any idea what else could cause this error?

doorman
  • 15,707
  • 22
  • 80
  • 145
  • 2
    empty catch statements make me cry – Ctznkane525 Jan 10 '18 at 14:12
  • What's the error? Looks like an error that can be solved by reading the error message. – Fabian S. Jan 10 '18 at 14:12
  • Hi @FabianH there is no error it runs fine. I left it empty cause I am just debugging. I have the real try catch in the parent. – doorman Jan 10 '18 at 14:14
  • So it runs fine but I am not getting the expected results from the PowerShell script. – doorman Jan 10 '18 at 14:17
  • @doorman so what is not working? – Fabian S. Jan 10 '18 at 14:17
  • If I run the script directly in the powershell window it runs successfully and a success message is printed out. If I run this in c# it runs without exception but it´s a bit like the script doesn´t run because it doesn´t change what it is supposed to change. Nothing is changed . – doorman Jan 10 '18 at 14:18
  • @FabianH Is it correct to call the function at the end of the ps file? MyFunction $args[0] $args[1] will the parameters be linked correctly using the automation dll? – doorman Jan 10 '18 at 14:21
  • 1
    Take a look at https://stackoverflow.com/a/10260767/4136669 – Fabian S. Jan 10 '18 at 14:22
  • Thanks @FabianH. I modified the code accordingly but I am getting another error. See my updated question. – doorman Jan 10 '18 at 15:36

1 Answers1

0

Finally I found a solution. Two things: This code solved the "is not recognized as a cmdlet, function, operable program, or script file bug. Thanks to Problem with calling a powershell function from c#

using (var runspace = RunspaceFactory.CreateRunspace())
{
    try
    {
        var script = File.ReadAllText("MyScript.ps1");
        runspace.Open();
        var ps = PowerShell.Create();
        ps.Runspace = runspace;
        ps.AddScript(script);
        ps.Invoke();
        ps.AddCommand("MyFunction").AddParameters(new Dictionary<string, string>
        {
            { "Param1" , value1},
            { "Param2", value2},
            { "Param3", value3},            
        });

        foreach (var result in ps.Invoke())
        {
        }
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex.Message);
    }
}

Important, I also had to remove the process wrapper attribute from the script file

****MyScripts.ps1

    function MyFunction 
    {
        Param (
            [Parameter(Mandatory=$true)][string] myParam1,        
            [Parameter(Mandatory=$true)][string] myParam2,        
            [Parameter(Mandatory=$true)][string] myParam3,  
        )
        //  Removing the Process wrapper solved the problem, the code didn't run with it 
        Process {     
            //DOSTUFF
        }
    }
doorman
  • 15,707
  • 22
  • 80
  • 145