As part of a book I am writing, I wanted to show how simple it could be to create your own cmdlet in C#. This was to be a part of an advanced look at the things you can do with PowerShell 7 and DotNet Core.
Most IT professionals know about the .NET objects produced by cmdlets, how to discover details about those objects, and how to reach into the .NET BCLs to do things that cmdlets can't. You can also extend PowerShell using a .NET Language such as C# to create a class. You use Add-Type to import the class into your PowerShell session and use it just like any other .NET class. Creating a cmdlet turned out to be more complex.
The first question any sane person might ask is; WHY? Why would anyone want to write a cmdlet or create a class using C#? The obvious reason, per Jimmy The Swede, is because you can. As an IT professional, knowing how is just another tool on your tool belt. But aside from that, there really are some good reasons. Using C# is easier when you need to perform asynchronous operations or multi-threading, or if you wish to use Language-Integrated Query (LINQ). IN those cases, C# is a lot easier than trying to use PowerShell in those scenarios. Another use case is taking some ASP.NET code, such as a page which creates a list of out of stock items and re-purposing it for administrative use. Admittedly, there are not a lot of use cases in the wild - but as a PowerShell person, you should know!
If you are a hardcore Windows developer, you probably have Visual Studio and know how to use it. But in this article, I'm going to use a different approach which is to use the .NET SDK and the dotnet.exe command. You can do most of this from the command line, although there seems no simple way to install the SDK. So here goes
1. Install the .Net Core SDK.
This is almost the hardest part of the job. You need to install the Software Development Kit in order to get the tools you need to create the cmdlet. This involves using the GUI.
Navigate to the Dotnet download page: https://dotnet.microsoft.com/download/
# 2. Create the cmdlet folderNew-Item -Path C:\Foo\Cmdlet -ItemType Directory -ForceSet-Location C:\Foo\Cmdlet# 3. Creating a class library projectdotnet new classlib --name SendGreetings# 4. Viewing contents of new folderSet-Location -Path .\SendGreetingsGet-ChildItem# 5. Creating global.jsondotnet new globaljson# 6. Adding PowerShell packagedotnet add package PowerShellStandard.Library# 7. Create the cmdlet source file$Cmdlet = @"using System.Management.Automation; // Windows PowerShell assembly.namespace Reskit{// Declare the class as a cmdlet// Specify verb and noun = Send-Greeting[Cmdlet(VerbsCommunications.Send, "Greeting")]public class SendGreetingCommand : PSCmdlet{// Declare the parameters for the cmdlet.[Parameter(Mandatory=true)]public string Name{get { return name; }set { name = value; }}private string name;// Override the ProcessRecord method to process the// supplied name and write a geeting to the user by// calling the WriteObject method.protected override void ProcessRecord(){WriteObject("Hello " + name + " - have a nice day!");}}}"@$Cmdlet | Out-File .\SendGreetingCommand.cs# 8. remove class fileRemove-Item -Path .\Class1.cs# 9. Build the cmdletdotnet build# 10. Importing the DLL holding the cmdlet$DLLPath = '.\bin\Debug\net5.0\SendGreetings.dll'Import-Module -Name $DLLPath