Hosted PowerShell cannot see Cmdlets in the same Assembly Hosted PowerShell cannot see Cmdlets in the same Assembly powershell powershell

Hosted PowerShell cannot see Cmdlets in the same Assembly


The easiest way to do this with your current code snippet is like this:

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);     } } 

This assumes PowerShell v2.0 (you can check in your console with $psversiontable or by the copyright date which should be 2009.) If you're on win7, you are on v2.


Yet another simple way is to register cmdlets in a runspace configuration, create a runspace with this configuration, and use that runspace.

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);    }}

Just in case, with this approach cmdlet classes do not have to be public.


You do need to register your cmdlet before you can use it in a Powershell session. You'll generally do that by way of a Powershell Snap-In. Here's a high-level overview of the process:

  • Create custom cmdlets (you've already done this part)
  • Create a Powershell Snap-in which contains and describes your cmdlets
  • Install the new Snap-in on your system using Installutil
  • Add the Snap-in to a specific Powershell session using Add-PSSnapin

There are a couple useful articles on MSDN that explain the process pretty thoroughly:

There's also a 2-part series on ByteBlocks that discusses writing custom cmdlets. That series may be your best bet, since you seem to have done the equivalent of part 1 already. You may be able to just use part 2 as a quick reference and be good to go.