James123
James123

Reputation: 11652

How to run multiple commands in single script block in PowerShell using C#?

I am trying to execute multiple PS commands in single script but it is throwing an exception. I tried different options but did not work.

 using (powershell = PowerShell.Create())
 {
    command = new PSCommand();
    command.AddCommand("Invoke-Command");
    command.AddParameter("ScriptBlock",
          System.Management.Automation.ScriptBlock.Create(
           "New-MailContact -Name '" + txtEmail.Text + "' -ExternalEmailAddress '" + txtEmail.Text + "';" ));
     command.AddParameter("ScriptBlock",
           System.Management.Automation.ScriptBlock.Create(
           "Set-MailContact -Identity '" + txtEmail.Text + "'-HiddenFromAddressListsEnabled $true"));


    command.AddParameter("Session", session);
    powershell.Commands = command;
    powershell.Runspace = runspace;
    result = powershell.Invoke();
    if (powershell.Streams.Error.Count > 0 || result.Count != 1)
    {
         if (powershell.Streams.Error[0].ToString().ToLowerInvariant().Contains("already exists"))
         {
               return;
          }
          else
          {
               throw new Exception("Fail to establish the connection");
           }
       }
      }

Cannot bind parameter because parameter 'ScriptBlock' is specified more than once. To provide multiple values to parameters that can accept multiple values, use the array syntax. For example, "-parameter value1,value2,value3".

I also tried

command.AddParameter("ScriptBlock",
   System.Management.Automation.ScriptBlock.Create(
   "New-MailContact -Name '" + txtEmail.Text + "' -ExternalEmailAddress '" + txtEmail.Text + "';" +  " Set-MailContact -Identity '" + txtEmail.Text + "'-HiddenFromAddressListsEnabled $true"));

and

command.AddParameter("ScriptBlock",
   System.Management.Automation.ScriptBlock.Create(
   "(New-MailContact -Name '" + txtEmail.Text + "' -ExternalEmailAddress '" + txtEmail.Text + "')" +  " Set-MailContact -Identity '" + txtEmail.Text + "'-HiddenFromAddressListsEnabled $true"));

Upvotes: 1

Views: 1885

Answers (1)

mclayton
mclayton

Reputation: 9975

I think you can simplify your code quite a bit - you don't need the Invoke-Command and ScriptBlock elements just to call a single command each - you can call the cmdlets directly instead.

You can also address the script injection concern raised by @madreflection at the same time if you build up your commands with parameters.

Here's a version in PowerShell (it was easier for me to test than spinning up a sample C# project :-)) that you could convert to C#:

$p = [System.Management.Automation.PowerShell]::Create()

$c = new-object System.Management.Automation.Runspaces.Command("New-MailContact");
$c.Parameters.Add("Name", $name)
$c.Parameters.Add("ExternalEmailAddress", $address)
$null = $p.Commands.AddCommand($c)

$c = new-object System.Management.Automation.Runspaces.Command("Set-MailContact");
$c.Parameters.Add("Identity", $identity)
$c.Parameters.Add("HiddenFromAddressListsEnabled", $hidden)
$null = $p.Commands.AddCommand($c)

$p.Invoke()

Update - ah, just noticed you're using the Session parameter on Invoke-Command - if you're executing it with remoting then you probably do need Invoke-Command after all. Maybe this answer will help...

Set Paramerters in ScriptBlock when Executing Powershell Commands with C#

Upvotes: 1

Related Questions