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.
Create a System.Management.Automation.PowerShell object.
PowerShell ps = PowerShell.Create();
Add the command that you want to execute.
ps.AddCommand("Get-Process");
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