3r1c
3r1c

Reputation: 396

How to execute a powershell script using c# and setting execution policy?

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.

Upvotes: 4

Views: 3442

Answers (1)

mklement0
mklement0

Reputation: 440471

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.

Upvotes: 7

Related Questions