托管的PowerShell不能在同一个程序集中看到cmdlet

本文关键字:集中 程序集 cmdlet 程序 同一个 PowerShell 不能 | 更新日期: 2023-09-27 18:09:37

我正试图从我的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。我写错cmlet了吗?我需要做些什么来注册我的Cmdlet在PowerShell或在Runspace或什么?

托管的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();
        // 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。

另一种简单的方法是在运行空间配置中注册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类不必是公共的。

在Powershell会话中使用cmdlet之前,您确实需要注册它。您通常会通过Powershell管理单元来实现这一点。以下是该流程的高级概述:

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

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

  • 使用Windows PowerShell开发
  • 如何创建Windows PowerShell管理单元

还有一个关于ByteBlocks的两部分系列,讨论编写自定义cmdlet。这个系列可能是您最好的选择,因为您似乎已经完成了与第1部分相同的内容。你可以把第二部分作为一个快速参考,然后就可以了。

  • 如何编写自定义cmd -第1部分
  • 如何编写自定义cmd - Part 2