Wednesday, January 29, 2020

PowerShell Scripts and Cmdlets - Part 3

In my last post, I walked through creating a Cmdlet using .NET and working in Visual Studio 2010.  To review, a PowerShell cmdlet is implemented as a class within a class library.  The cmdlet class inherits from one of two classes, Cmdlet or PSCmdlet.  At this point (I'm writing this post 8 and a half years later than part 2) I should just move onto the implementation without sweating the details too much.  I did find a blog post here - https://weblogs.asp.net/shahar/cmdlet-vs-pscmslet-windows-powershell -  that talks about the difference.  Long story short I'm going to derive from Cmdlet for reasons stated in that article.

Side Note: I had to chuckle a little (and I'm still smiling as I write this) that I actually am reading and finding useful a blog post that I wrote that long ago.  And I still need to google and research quite a bit whenever I do anything with PowerShell since I do it so infrequently.  So back to the nitty-gritty as Natcho Libre would say...

I should mention that for this particular implementation I have now moved on from Visual Studio 2010 and am now using Visual Studio 2017 (It is the year 2020 now, after all).  The class library I'm creating is going to be using a REST client library that I've created to call the Salesforce REST API.

I did follow my advice from the last post and found a verb that has Microsoft's official stamp of approval (by virtue of showing up in their latest documentation here).  I decided to use the Publish verb, and for the noun I used SalesforceContentVersion to indicate both the platform and the REST endpoint (ContentVersion).  Given that information my class looks like this:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Management.Automation;

namespace SFRest.PowerShell
{
    [Cmdlet("Publish", "SalesforceContentVersion")]
    public class PublishSalesforceContentVersionCmdlet : Cmdlet
    {
    }
}


Notice three important things in the above code snippet:

1. I've included a using System.Management.Automation to include the PowerShell namespace and make it easier to reference the PowerShell types.
2. I've indicated my Cmdlet verb and noun in the Cmdlet attribute on the class
3. I've inherited my class from Cmdlet

At this point I can compile my class without error and am ready to move on to the implementation.  Note that as I go off to implement this thing, I'm going to rely on Microsoft's Writing a Windows PowerShell Cmdlet to actually get it working.

The first thing I'm starting with is the parameters that I need to pass in.  In my case I need to pass in a bunch of string parameters that will be used for authentication with Salesforce and then parameters related to the metadata and data for the file that will be uploaded.

I'm not going to get into the details but basically most of my parameters are defined in my class like this:

[Parameter(Mandatory = true)]
public String FilePath { get; set; }


Most of my parameters are mandatory, but there is one that is a switch parameter which is an optional parameter that acts like a boolean.  By default the value is false, but when you specify this parameter on the command line it becomes true.  Here is my switch parameter:

[Parameter(HelpMessage = "Specify for loading a file to a production org.")]
public SwitchParameter IsProduction { get; set; }


The next step after specifying parameters was to actually write the code that would upload the file.

For my cmdlet, I put all of the code in the ProcessRecord method, which is overridden from the Cmdlet.ProcessRecord method.  To do this, you just override the method in your cmdlet class and implement away:

protected override void ProcessRecord()
{
    // Implementation goes here
}

Once you get the implementation out of the way, you can proceed to test your cmdlet.  I'll cover that in Part 4, hopefully before another 8 years has passed.

No comments: