Windows PowerShell 主机快速入门

若要在应用程序中托管 Windows PowerShell,请使用 System.Management.Automation.PowerShell 类。 此类提供创建命令管道的方法,然后在运行空间中执行这些命令。 创建主机应用程序的最简单方法是使用默认运行空间。 默认运行空间包含所有核心 Windows PowerShell 命令。 如果希望应用程序仅公开 Windows PowerShell 命令的子集,则必须创建自定义运行空间。

使用默认运行空间

首先,我们将使用默认运行空间,并使用 System.Management.Automation.PowerShell 类的方法将命令、参数、语句和脚本添加到管道。

AddCommand

使用 System.Management.Automation.PowerShell。AddCommand 方法,用于向管道添加命令。 例如,假设你想要获取计算机上正在运行的进程的列表。 运行此命令的方法如下所示。

  1. 创建 System.Management.Automation.PowerShell 对象。

    PowerShell ps = PowerShell.Create();
    
  2. 添加要执行的命令。

    ps.AddCommand("Get-Process");
    
  3. 调用命令。

    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.RunspaceSystem.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-CommandImport-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