1

Update: The answer below was able to get me where I needed to be. Here is the full solution, if interested in seeing Angular / WebAPI interface with PowerShell on the backend.

enter image description here

I have a .ps1 file saved as an embedded resource in a Scripts folder in a C# class library. What I would like to do is pass this script into a new System.Management.Automation.Runspaces.Command class as follows:

InitialSessionState iss = InitialSessionState.CreateDefault();
iss.ExecutionPolicy = Microsoft.PowerShell.ExecutionPolicy.Unrestricted;

using (Runspace rs = RunspaceFactory.CreateRunspace(iss))
{
    rs.Open();                        
    Command queryWmi = new Command("PowerShellAPIFramework.Core.Scripts.QueryWmi.ps1");
    queryWmi.Parameters.Add("query", model.query);
    queryWmi.Parameters.Add("properties", model.properties);
    queryWmi.Parameters.Add("computername", model.computername);
    queryWmi.Parameters.Add("wmiNamespace", model.wmiNamespace);

    using (PowerShell ps = PowerShell.Create())
    {
        ps.Runspace = rs;
        ps.Commands.AddCommand(queryWmi);
        var results = ps.Invoke();

        if (ps.HadErrors)
        {
            if (ps.Streams.Error.Count > 0)
            {
                foreach (var error in ps.Streams.Error)
                {
                    Console.WriteLine(error.Exception.GetExceptionMessageChain());
                }
            }
        }
        else
        {
            foreach (var result in results)
            {
                Console.WriteLine(result.ToString());
            }
        }
    }
}

The following exception is thrown whenever I hit ps.Invoke()

"The term 'PowerShellAPIFramework.Core.Scripts.QueryWmi.ps1' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again."

I've run the same code, but specifying a URL for a file on my hard drive, for instance, D:\Desktop\QueryWmi.ps1, and it works just fine.

Jaime Still
  • 1,949
  • 20
  • 31

1 Answers1

2

After reading PetSerAl's comment, I've updated the code. Using the Command(string command, bool isScript) constructor.

        using (Stream st = new MemoryStream(Properties.Resources.yourResource))
        {
            using (StreamReader sr = new StreamReader(st))
            {
                string script = sr.ReadToEnd();

                using (PowerShell ps = PowerShell.Create())
                {
                    Command cmd = new Command(script, true);
                    //Add Parameters

                    ps.Commands.AddCommand(cmd);
                    ps.Invoke();
                }
            }
        }
Jaime Macias
  • 857
  • 6
  • 11
  • I'd prefer to use the Command class so that I can configure the associated parameters. If it can't be done as an embedded resource, I'll most likely just store the scripts on a file server and resolve the path that way. Thanks for the feedback though! – Jaime Still Sep 07 '16 at 11:26
  • 2
    @JaimeStill you can use `Command` class with script: `new Command(script, true)`. – user4003407 Sep 07 '16 at 15:54
  • Thank you both, this is great! – Jaime Still Sep 07 '16 at 19:08
  • Updated the solution in the question with a fully working version, if ya'll are interested in seeing Angular / WebAPI interfacing with PowerShell on the back end. Included thanks to both of you above the extension method based on the answer, and linked to this SO question. – Jaime Still Sep 08 '16 at 20:34