views:

253

answers:

1

Hi,

I'm trying to pass a parameter to powershell from c# web app, but keep getting an error

Reason = {"The term 'Param($ds)\r\n\r\n$ds\r\n\r\n\r\n' 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."}

my powershell script is as follows:

Param($ds)

write-host $ds

my c# is:

    protected void drpCluster_SelectedIndexChanged(object sender, EventArgs e)
    {
        // Looping through all the rows in the GridView
        foreach (GridViewRow row in GridVMApprove.Rows)
        {
            if (row.RowState == DataControlRowState.Edit)
            {
                //create dynamic dropDowns for datastores
                DropDownList drpDatastore = (DropDownList)row.FindControl("drpDatastore");
                DropDownList drpCluster = (DropDownList)row.FindControl("drpCluster");
                var Datacenter = "'" + drpCluster.SelectedValue + "'";
                strContent = this.ReadPowerShellScript("~/scripts/Get-DatastoresOnChange.ps1");
                this.executePowershellCommand(strContent, Datacenter);
                populateDropDownList(drpDatastore);
            }
        }
    }

    public string ReadPowerShellScript(string Script)
    {
        //Read script
        StreamReader objReader = new StreamReader(Server.MapPath(Script));
        string strContent = objReader.ReadToEnd();
        objReader.Close();

        return strContent;
    }

    private string executePowershellCommand(string scriptText, string scriptParameters)
    {
        RunspaceConfiguration rsConfig = RunspaceConfiguration.Create();
        PSSnapInException snapInException = null;
        PSSnapInInfo info = rsConfig.AddPSSnapIn("vmware.vimautomation.core", out snapInException);
        Runspace RunSpace = RunspaceFactory.CreateRunspace(rsConfig);
        RunSpace.Open();
        Pipeline pipeLine = RunSpace.CreatePipeline();
        Command scriptCommand = new Command(scriptText); 
        pipeLine.Commands.AddScript(scriptText);
        if (!(scriptParameters == null))
        {
            CommandParameter Param = new CommandParameter(scriptParameters);
            scriptCommand.Parameters.Add(Param);
            pipeLine.Commands.Add(scriptCommand);              
        }

        // execute the script
        Collection<PSObject> commandResults = pipeLine.Invoke();


        // close the runspace
        RunSpace.Close();

        // convert the script result into a single string
        System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder();
        foreach (PSObject obj in commandResults)
        {
            stringBuilder.AppendLine(obj.ToString());
        }

        OutPut = stringBuilder.ToString();
        return OutPut;
    }

i've followed some other threads but can't script to execute. My Powershell scripts executes if i run it from powershell console just calling the script and a parameter. if i remove Param($ds) from the powershell script it doesn't error.

can anyone help?

thanks.

+2  A: 

Only scriptblocks, ps1/psm1 files and functions/filters can have a param block. The script you should be adding with AddScript should be of the form:

& { param($ds); $ds }

& is the call operator. In your example, you are trying to execute param as a command.

update

You must pass the arguments to the scriptblock like so:

& { param($ds); $ds } 42

This results in 42 being passesd to the scriptblock. Sticking script in with AddScript doesn't implicitly create a ps1 file. It's akin to you typing:

ps c:\> param($ds); $ds

...directly at the prompt; this is meaningless. Make sense?

-Oisin

x0n
Thanks for the reply but that doesn't seem to ring true. if i have a script called test.ps1 with the following Param($msg) write-host $msg and then call it with ./test.ps1 Hello I do get hello written to the console. I've also tried using $args[0] int he script with the same outcome. if i put $ds | out-file c:\scripts\testparam.txt }into the script i'm calling i still get the same error.
Paul Houghton
You must pass the arguments to the scriptblock like so: $ds } 42This results in 42 being passesd to the scriptblock. Sticking script in with AddScript doesn't implicitly create a ps1 file. It's akin to you typing:ps c:\> param($ds); $ds directly at the prompt. This is meaningless. Make sense?
x0n
cool yes it does now. thank you.
Paul Houghton
sorry looking over this again it still doesn't quite make sense, ait's what i thought was actaully doing. The script i'm reading in from "~/scripts/get-datastores.ps1" contains a script block exactly as you described. I though i was then adding params with "scriptCommand.Parameters.Add(Param);" But i take what you've said about sticking a script in with AddScript doesn't create a .ps1 file, so do i actually have to create the powershell script in the c# code rather than read in an external script? Do you have or could you point me to any sample code so i can visualise it? thanks.
Paul Houghton
Heh, you're not quite getting it yet. If you're reading content in from a ps1 file, you're *removing* the param block from the context where it makes sense. If you want to execute that script, DON'T READ THE CONTENTS OF THE PS1, instead EXECUTE THE PS1. Get rid of your ReadPowerShellScript method, and instead do: Command scriptCommand = new Command("~/script/Get-DatastoresOnChange.ps1") - capiche? :D
x0n