托管PowerShell无法在同一个程序集中看到Cmdlet

时间:2011-09-26 20:09:27

标签: c# powershell cmdlet

我正在尝试从我的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或Runspace中注册我的Cmdlet有什么需要做的吗?

3 个答案:

答案 0 :(得分: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。

答案 1 :(得分: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类不必公开。

答案 2 :(得分:1)

您需要先注册cmdlet,然后才能在Powershell会话中使用它。你通常会通过Powershell Snap-In来做到这一点。以下是该过程的高级概述:

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

MSDN上有一些有用的文章可以非常彻底地解释这个过程:

还有一个关于ByteBlocks的两部分系列文章讨论编写自定义cmdlet。那个系列可能是你最好的选择,因为你似乎已经完成了第1部分的相同工作。您可以使用第2部分作为快速参考,并且可以继续使用。