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.