views:

6343

answers:

4

I need to execute a PowerShell script from within C#. The script needs commandline arguments.

This is what I have done so far:

RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();

Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
runspace.Open();

RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);

Pipeline pipeline = runspace.CreatePipeline();
pipeline.Commands.Add(scriptFile);

// Execute PowerShell script
results = pipeline.Invoke();

scriptFile contains something like "C:\Program Files\MyProgram\Whatever.ps1".

The script uses a commandline argument such as "-key Value" whereas Value can be something like a path that also might contain spaces.

I don't get this to work. Does anyone know how to pass commandline arguments to a PowerShell script from within C# and make sure that spaces are no problem?

+6  A: 

Try creating scriptfile as a separate command:

Command myCommand = new Command(scriptfile);

then you can add parameters with

CommandParameter testParam = new CommandParameter("key","value");
myCommand.Parameters.Add(testParam);

and finally

pipeline.Commands.Add(myCommand);
Kosi2801
I still seem to have the problem that if value is something like c:\program files\myprogram, the key is set to c:\program. :(
Mephisztoe
Never mind. Sometimes it helps when you know how to correctly split strings. ;-) Thanks again, your solution helped me in resolving my problem!
Mephisztoe
@Tronex - you should be defining the key as being a parameter for your script. PowerShell has some great builtin tools for working with paths. Maybe ask another question about that. @Kosi2801 has the correct answer for adding parameters.
Steven Murawski
Typing my reply overlapped yours.. I'm glad you got it resolved!
Steven Murawski
A: 

You can also just use the pipeline with the AddScript Method:

string cmdArg = ".\script.ps1 -foo bar"            
Collection<PSObject> psresults;
using (Pipeline pipeline = _runspace.CreatePipeline())
            {
                pipeline.Commands.AddScript(cmdArg);
                pipeline.Commands[0].MergeMyResults(PipelineResultTypes.Error, PipelineResultTypes.Output);
                psresults = pipeline.Invoke();
            }
return psresults;

It will take a string, and whatever parameters you pass it.

James Pogran
A: 

Any chance I could get more clarity on the passing params to the Commands.AddScript method?

C:\Foo1.PS1 Hello World Hunger C:\Foo2.PS1 Hello World

scriptFile = "C:\Foo1.PS1"

parameters = "parm1 parm2 parm3" ... variable length of params

Resolved this ... passing null as the name and the param as value into a collection of CommandParameters

here is my function:

private static void RunPowershellScript(string scriptFile, string scriptParameters)
{
    RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
    Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
    runspace.Open();
    RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
    Pipeline pipeline = runspace.CreatePipeline();
    Command scriptCommand = new Command(scriptFile);
    Collection<CommandParameter> commandParameters = new Collection<CommandParameter>();
    foreach (string scriptParameter in scriptParameters.Split(' '))
    {
        CommandParameter commandParm = new CommandParameter(null, scriptParameter);
        commandParameters.Add(commandParm);
        scriptCommand.Parameters.Add(commandParm);
    }
    pipeline.Commands.Add(scriptCommand);
    Collection<PSObject> psObjects;
    psObjects = pipeline.Invoke();
}
twalker
A: 

Hi,

I trying to execute the powershell script in C#. But I am getting the exception like "Assignment statements are not allowed in restricted language mode or a Data section."

Here is my C# code :

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

PowerShell exec_script = PowerShell.Create(); exec_script.RunspacePool = rs; exec_script.AddScript(script);

IAsyncResult exec_AsyncResult = exec_script.BeginInvoke(); PSDataCollection exec_Result = exec_script.EndInvoke(exec_AsyncResult);

foreach (PSObject cmdlet in exec_Result) {
PSMemberInfoCollection collec = cmdlet.Members;
foreach (PSMemberInfo temp in collec) { Console.WriteLine(temp.Name + "\t\t\t\t:\t" + temp.Value); }
}

Here is my PowerShell script :

[Collections.ArrayList]$serverList = New-Object Collections.ArrayList [string]$server

if ($server -eq "") { $objects = Get-MailboxServer foreach ($object in $objects) { $out = $serverList.Add($object.Name) } }

else { $serverList.Add($server) }

wondering what is the problem.

Thanks is advance,

Viswanath B

viswanath