4

I tried to combine two answers from stackoverflow (first & second)

InitialSessionState iss = InitialSessionState.CreateDefault();
// Override ExecutionPolicy

PropertyInfo execPolProp = iss.GetType().GetProperty(@"ExecutionPolicy");
if (execPolProp != null && execPolProp.CanWrite)
{
    execPolProp.SetValue(iss, ExecutionPolicy.Bypass, null);
}
Runspace runspace = RunspaceFactory.CreateRunspace(iss);
runspace.Open();

Pipeline pipeline = runspace.CreatePipeline();

//Here's how you add a new script with arguments
Command myCommand = new Command(scriptfile);
CommandParameter testParam = new CommandParameter("key","value");
myCommand.Parameters.Add(testParam);

pipeline.Commands.Add(myCommand);

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

In my powershell script I have the following parameter:

Param(
[String]$key
)

However, when I execute this, then I get the following exception:

System.Management.Automation.CmdletInvocationException: Cannot validate argument on parameter 'Session'. 
The argument is null or empty. 
Provide an argument that is not null or empty, and then try the command again.

1 Answer 1

7

Without knowing what your specific problem was, note that your C# code can be greatly streamlined, which may also resolve your problem:

  • There is no need to resort to reflection in order to set a session's execution policy.

  • Using an instance of the PowerShell class greatly simplifies command invocation.

// Create an initial default session state.
var iss = InitialSessionState.CreateDefault2();
// Set its script-file execution policy (for the current session only).
iss.ExecutionPolicy = Microsoft.PowerShell.ExecutionPolicy.Bypass;

// Create a PowerShell instance with a runspace based on the 
// initial session state.
PowerShell ps = PowerShell.Create(iss);

// Add the command (script-file call) and its parameters, then invoke.
var results =
  ps
   .AddCommand(scriptfile)
   .AddParameter("key", "value")
   .Invoke();

Note:

  • Using a per-process execution-policy override, as shown above, does not work if the current machine's / current user's execution policy is controlled by GPOs (Group Policy Objects).

    • See this answer for a comprehensive overview of PowerShell's script execution policies.
  • The .Invoke() method only throws an exception if a terminating error occurred during execution of the PowerShell script. The more typical non-terminating errors are instead reported via .Streams.Error.

Sign up to request clarification or add additional context in comments.

3 Comments

This is interesting. So, in C# you don't have to mark a line continuation like you would in PowerShell (i.e. : the backtick ( ` ) )?
@AbrahamZinala: There is no line-continuation char. in C#, because the logic is reversed: a statement, irrespective of how many lines it spans, is only terminated by ; In PowerShell, which doesn't require explicit statement termination, you can situationally get away without a line-ending backtick, namely when the statement is unambiguously incomplete, notably after a line-ending | and, similarly, but not identically, to the ps example above: a line-ending . - that is, the . must be at the end of the line for PowerShell to know that the statement continues.
@AbrahamZinala: As an explicit exception, PowerShell (Core) 7+ now allows you to place a | on the next line in order to continue a pipeline. That is, while Windows PowerShell only supports, e.g. Get-Date |<newline> Format-List, PowerShell (Core) 7+ now also supports Get-Date<newline>| Format-List, albeit only in scripts, because interactively Get-Date would execute by itself before you get a chance to continue the statement (except inside { ... }).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.