Windows PowerShell Host Quickstart

To host Windows PowerShell in your application, you use the System.Management.Automation.PowerShell class. This class provides methods that create a pipeline of commands and then execute those commands in a runspace. The simplest way to create a host application is to use the default runspace. The default runspace contains all of the core Windows PowerShell commands. If you want your application to expose only a subset of the Windows PowerShell commands, you must create a custom runspace.

Using the default runspace

To start, we'll use the default runspace, and use the methods of the System.Management.Automation.PowerShell class to add commands, parameters, statements, and scripts to a pipeline.

AddCommand

You use the System.Management.Automation.PowerShell.AddCommand method to add commands to the pipeline. For example, suppose you want to get the list of running processes on the machine. The way to run this command is as follows.

  1. Create a System.Management.Automation.PowerShell object.

    PowerShell ps = PowerShell.Create();
    
  2. Add the command that you want to execute.

    ps.AddCommand("Get-Process");
    
  3. Invoke the command.

    ps.Invoke();
    

If you call the AddCommand method more than once before you call the System.Management.Automation.PowerShell.Invoke method, the result of the first command is piped to the second, and so on. If you do not want to pipe the result of a previous command to a command, add it by calling the System.Management.Automation.PowerShell.AddStatement instead.

AddParameter

The previous example executes a single command without any parameters. You can add parameters to the command by using the System.Management.Automation.PSCommand.AddParameter method. For example, the following code gets a list of all of the processes that are named PowerShell running on the machine.

PowerShell.Create().AddCommand("Get-Process")
                   .AddParameter("Name", "PowerShell")
                   .Invoke();

You can add additional parameters by calling the AddParameter method repeatedly.

PowerShell.Create().AddCommand("Get-ChildItem")
                   .AddParameter("Path", @"c:\Windows")
                   .AddParameter("Filter", "*.exe")
                   .Invoke();

You can also add a dictionary of parameter names and values by calling the System.Management.Automation.PowerShell.AddParameters method.

IDictionary parameters = new Dictionary<String, String>();
parameters.Add("Path", @"c:\Windows");
parameters.Add("Filter", "*.exe");

PowerShell.Create().AddCommand("Get-Process")
   .AddParameters(parameters)
      .Invoke()

AddStatement

You can simulate batching by using the System.Management.Automation.PowerShell.AddStatement method, which adds an additional statement to the end of the pipeline. The following code gets a list of running processes with the name PowerShell, and then gets the list of running services.

PowerShell ps = PowerShell.Create();
ps.AddCommand("Get-Process").AddParameter("Name", "PowerShell");
ps.AddStatement().AddCommand("Get-Service");
ps.Invoke();

AddScript

You can run an existing script by calling the System.Management.Automation.PowerShell.AddScript method. The following example adds a script to the pipeline and runs it. This example assumes there is already a script named MyScript.ps1 in a folder named D:\PSScripts.

PowerShell ps = PowerShell.Create();
ps.AddScript("D:\PSScripts\MyScript.ps1").Invoke();

There is also a version of the AddScript method that takes a boolean parameter named useLocalScope. If this parameter is set to true, then the script is run in the local scope. The following code will run the script in the local scope.

PowerShell ps = PowerShell.Create();
ps.AddScript(@"D:\PSScripts\MyScript.ps1", true).Invoke();

Creating a custom runspace

While the default runspace used in the previous examples loads all of the core Windows PowerShell commands, you can create a custom runspace that loads only a specified subset of all commands. You might want to do this to improve performance (loading a larger number of commands is a performance hit), or to restrict the capability of the user to perform operations. A runspace that exposes only a limited number of commands is called a constrained runspace. To create a constrained runspace, you use the System.Management.Automation.Runspaces.Runspace and System.Management.Automation.Runspaces.InitialSessionState classes.

Creating an InitialSessionState object

To create a custom runspace, you must first create a System.Management.Automation.Runspaces.InitialSessionState object. In the following example, we use the System.Management.Automation.Runspaces.RunspaceFactory to create a runspace after creating a default InitialSessionState object.

InitialSessionState iss = InitialSessionState.CreateDefault();
Runspace rs = RunspaceFactory.CreateRunspace(iss);
rs.Open();
PowerShell ps = PowerShell.Create();
ps.Runspace = rs;
ps.AddCommand("Get-Command");
ps.Invoke();
rs.Close();

Constraining the runspace

In the previous example, we created a default System.Management.Automation.Runspaces.InitialSessionState object that loads all of the built-in core Windows PowerShell. We could also have called the System.Management.Automation.Runspaces.InitialSessionState.CreateDefault2 method to create an InitialSessionState object that would load only the commands in the Microsoft.PowerShell.Core snapin. To create a more constrained runspace, you must create an empty InitialSessionState object by calling the System.Management.Automation.Runspaces.InitialSessionState.Create method, and then add commands to the InitialSessionState.

Using a runspace that loads only the commands that you specify provides significantly improved performance.

You use the methods of the System.Management.Automation.Runspaces.SessionStateCmdletEntry class to define cmdlets for the initial session state. The following example creates an empty initial session state, then defines and adds the Get-Command and Import-Module commands to the initial session state. We then create a runspace constrained by that initial session state, and execute the commands in that runspace.

Create the initial session state.

InitialSessionState iss = InitialSessionState.Create();

Define and add commands to the initial session state.

SessionStateCmdletEntry getCommand = new SessionStateCmdletEntry(
    "Get-Command", typeof(Microsoft.PowerShell.Commands.GetCommandCommand), "");
SessionStateCmdletEntry importModule = new SessionStateCmdletEntry(
    "Import-Module", typeof(Microsoft.PowerShell.Commands.ImportModuleCommand), "");
iss.Commands.Add(getCommand);
iss.Commands.Add(importModule);

Create and open the runspace.

Runspace rs = RunspaceFactory.CreateRunspace(iss);
rs.Open();

Execute a command and show the result.

PowerShell ps = PowerShell.Create();
ps.Runspace = rs;
ps.AddCommand("Get-Command");
Collection<CommandInfo> result = ps.Invoke<CommandInfo>();
foreach (var entry in result)
{
    Console.WriteLine(entry.Name);
}

Close the runspace.

rs.Close();

When run, the output of this code will look as follows.

Get-Command
Import-Module