若要在应用程序中托管 Windows PowerShell,请使用 System.Management.Automation.PowerShell 类。 此类提供创建命令管道的方法,然后在运行空间中执行这些命令。 创建主机应用程序的最简单方法是使用默认运行空间。 默认运行空间包含所有核心 Windows PowerShell 命令。 如果希望应用程序仅公开 Windows PowerShell 命令的子集,则必须创建自定义运行空间。
使用默认运行空间
首先,我们将使用默认运行空间,并使用 System.Management.Automation.PowerShell 类的方法将命令、参数、语句和脚本添加到管道。
AddCommand
使用 System.Management.Automation.PowerShell。AddCommand 方法,用于向管道添加命令。 例如,假设你想要获取计算机上正在运行的进程的列表。 运行此命令的方法如下所示。
创建 System.Management.Automation.PowerShell 对象。
PowerShell ps = PowerShell.Create();
添加要执行的命令。
ps.AddCommand("Get-Process");
调用命令。
ps.Invoke();
如果在调用 System.Management.Automation.PowerShell.Invoke 方法之前多次调用 AddCommand 方法,则第一个命令的结果通过管道传递给第二个命令,依此方式。 如果不想通过管道将上一个命令的结果传递给命令,请通过调用 System.Management.Automation.PowerShell 来添加它。请改为AddStatement。
AddParameter
上一个示例执行一个不带任何参数的命令。 可以使用 System.Management.Automation.PSCommand 将参数添加到命令。AddParameter 方法。 例如,以下代码获取计算机上运行 powershell
命名的所有进程的列表。
PowerShell.Create().AddCommand("Get-Process")
.AddParameter("Name", "powershell")
.Invoke();
可以通过重复调用 AddParameter 方法来添加其他参数。
PowerShell.Create().AddCommand("Get-ChildItem")
.AddParameter("Path", @"C:\Windows")
.AddParameter("Filter", "*.exe")
.Invoke();
还可以通过调用 System.Management.Automation.PowerShell.AddParameters 方法添加参数名称和值的字典。
IDictionary parameters = new Dictionary<String, String>();
parameters.Add("Path", @"C:\Windows");
parameters.Add("Filter", "*.exe");
PowerShell.Create().AddCommand("Get-Process")
.AddParameters(parameters)
.Invoke()
AddStatement
可以使用 System.Management.Automation.PowerShell 模拟批处理。AddStatement 方法,该方法将附加语句添加到管道的末尾。 以下代码获取名称 powershell
正在运行的进程的列表,然后获取正在运行的服务的列表。
PowerShell ps = PowerShell.Create();
ps.AddCommand("Get-Process").AddParameter("Name", "powershell");
ps.AddStatement().AddCommand("Get-Service");
ps.Invoke();
AddScript
可以通过调用 System.Management.Automation.PowerShell 来运行现有脚本。AddScript 方法。 以下示例将脚本添加到管道并运行该脚本。 此示例假定已在名为 D:\PSScripts
的文件夹中有一个名为 MyScript.ps1
的脚本。
PowerShell ps = PowerShell.Create();
ps.AddScript("D:\PSScripts\MyScript.ps1").Invoke();
还有一个版本的 AddScript 方法采用名为 useLocalScope
的布尔参数。 如果此参数设置为 true
,则脚本将在本地范围内运行。 以下代码将在本地范围内运行脚本。
PowerShell ps = PowerShell.Create();
ps.AddScript(@"D:\PSScripts\MyScript.ps1", true).Invoke();
创建自定义运行空间
虽然前面示例中使用的默认运行空间会加载所有核心 Windows PowerShell 命令,但你可以创建自定义运行空间,该运行空间仅加载所有命令的指定子集。 你可能想要执行此作以提高性能(加载更多命令是性能命中),或限制用户执行作的功能。 仅公开有限数量的命令的运行空间称为受约束的运行空间。 若要创建受约束的 Runspace,请使用 System.Management.Automation.Runspaces.Runspace 和 System.Management.Automation.Runspaces.InitialSessionState 类。
创建 InitialSessionState 对象
若要创建自定义 Runspace,必须先创建 System.Management.Automation.Runspaces.InitialSessionState 对象。 在以下示例中,我们使用 System.Management.Automation.Runspaces.RunspaceFactory 在创建默认 InitialSessionState 对象后创建运行空间。
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();
约束运行空间
在前面的示例中,我们创建了一个默认 System.Management.Automation.Runspaces.InitialSessionState 对象,该对象加载了所有内置核心 Windows PowerShell。 我们还可以调用 System.Management.Automation.Runspaces.InitialSessionState.CreateDefault2 方法来创建 InitialSessionState 对象,该对象仅加载 Microsoft.PowerShell.Core 管理单元中的命令。 若要创建受约束的运行空间,必须通过调用 System.Management.Automation.Runspaces.InitialSessionState.Create 方法创建空 InitialSessionState 对象,然后将命令添加到 InitialSessionState。
使用仅加载指定命令的 Runspace 可显著提高性能。
使用 System.Management.Automation.Runspaces.SessionStateCmdletEntry 类的方法定义初始会话状态的 cmdlet。 以下示例创建一个空的初始会话状态,然后定义并将 Get-Command
和 Import-Module
命令添加到初始会话状态。 然后,创建受该初始会话状态约束的运行空间,并在该运行空间中执行命令。
创建初始会话状态。
InitialSessionState iss = InitialSessionState.Create();
定义命令并将其添加到初始会话状态。
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);
创建并打开 Runspace。
Runspace rs = RunspaceFactory.CreateRunspace(iss);
rs.Open();
执行命令并显示结果。
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);
}
关闭运行空间。
rs.Close();
运行时,此代码的输出将如下所示。
Get-Command
Import-Module