9

我正在尝试从我的 C# 代码运行 PowerShell 脚本,这将使用运行它们的程序集中的自定义 Cmdlet。这是代码:

using System;
using System.Management.Automation;

[Cmdlet(VerbsCommon.Get,"Hello")]
public class GetHelloCommand:Cmdlet
{
    protected override void EndProcessing()
    {
        WriteObject("Hello",true);
    }
}

class MainClass
{
    public static void Main(string[] args)
    {
        PowerShell powerShell=PowerShell.Create();
        powerShell.AddCommand("Get-Hello");
        foreach(string str in powerShell.AddCommand("Out-String").Invoke<string>())
            Console.WriteLine(str);
    }
}

当我尝试运行它时,我得到了一个 CommandNotFoundException。我写错了我的 Cmdlet 吗?我需要做些什么来在 PowerShell 或运行空间中注册我的 Cmdlet 吗?

4

3 回答 3

9

使用您当前的代码片段执行此操作的最简单方法是这样的:

using System; 
using System.Management.Automation; 

[Cmdlet(VerbsCommon.Get,"Hello")] 
public class GetHelloCommand:Cmdlet 
{ 
    protected override void EndProcessing() 
    { 
        WriteObject("Hello",true); 
    } 
} 

class MainClass 
{ 
    public static void Main(string[] args) 
    { 
        PowerShell powerShell=PowerShell.Create();

        // import commands from the current executing assembly
        powershell.AddCommand("Import-Module")
            .AddParameter("Assembly",
                  System.Reflection.Assembly.GetExecutingAssembly())
        powershell.Invoke()
        powershell.Commands.Clear()

        powershell.AddCommand("Get-Hello"); 
        foreach(string str in powerShell.AddCommand("Out-String").Invoke<string>()) 
            Console.WriteLine(str); 
    } 
} 

这假定 PowerShell v2.0(您可以使用 $psversiontable 或版权日期(应该是 2009)检查您的控制台。)如果您使用的是 win7,那么您使用的是 v2。

于 2011-09-26T21:37:44.850 回答
5

另一种简单的方法是在运行空间配置中注册 cmdlet,使用此配置创建运行空间,然后使用该运行空间。

using System;
using System.Management.Automation;
using System.Management.Automation.Runspaces;

[Cmdlet(VerbsCommon.Get, "Hello")]
public class GetHelloCommand : Cmdlet
{
    protected override void EndProcessing()
    {
        WriteObject("Hello", true);
    }
}

class MainClass
{
    public static void Main(string[] args)
    {
        PowerShell powerShell = PowerShell.Create();
        var configuration = RunspaceConfiguration.Create();
        configuration.Cmdlets.Append(new CmdletConfigurationEntry[] { new CmdletConfigurationEntry("Get-Hello", typeof(GetHelloCommand), "") });
        powerShell.Runspace = RunspaceFactory.CreateRunspace(configuration);
        powerShell.Runspace.Open();

        powerShell.AddCommand("Get-Hello");
        foreach (string str in powerShell.AddCommand("Out-String").Invoke<string>())
            Console.WriteLine(str);
    }
}

以防万一,使用这种方法 cmdlet 类不必是公共的。

于 2011-09-26T22:22:29.100 回答
1

您确实需要先注册您的 cmdlet,然后才能在 Powershell 会话中使用它。您通常会通过 Powershell 管理单元来执行此操作。以下是该过程的高级概述:

  • 创建自定义 cmdlet(您已经完成了这部分)
  • 创建一个包含并描述您的 cmdlet 的 Powershell 管理单元
  • 使用在您的系统上安装新的管理单元Installutil
  • 使用将管理单元添加到特定的 Powershell 会话Add-PSSnapin

MSDN 上有几篇有用的文章非常彻底地解释了该过程:

还有一个关于 ByteBlocks 的 2 部分系列讨论编写自定义 cmdlet。该系列可能是您最好的选择,因为您似乎已经完成了与第 1 部分相当的工作。您也许可以将第 2 部分用作快速参考,并且一切顺利。

于 2011-09-26T20:39:36.753 回答