Sunday, May 4, 2014

How to call custom cmdlet’s from PowerShell Script/How to create a custom cmdlet project in PowerShell

·         Open visual Studio

·         Create a Class library project

·         Add a new class file
The file will have be inheriting “System.Management.Automation.Cmdlet” .The file will also decorate the class file with the following verb [Cmdlet(VerbsCommon.Add, "NameOfYourFunctionality")]
Some sample code showing a sample powershell file


    [Cmdlet(VerbsCommon.Add, " NameOfYourFunctionality ")]
    public class MyClass : System.Management.Automation.Cmdlet
    {
        [Parameter(Position = 0, Mandatory = true)]
  public string para1;
   // define more parameters here
protected override void ProcessRecord()
        {

              //write your functionality here
 }

Add more class files if you need to build your functionality

·         Add a new installer file
Add the following code to the installer class
    [RunInstaller(true)]
    public class Installer : PSSnapIn
{
       public override string Name
        {
            get
            {
                return "NameWithWhichYouWantToRegisterWhenYouImportusing Add-PSSnapin";
            }
        }
}
}

·         Strong sign your assembly
·         In order to call this custom cmdlet from a script file you may have to first register this assembly in the GAC using the GACUTIL , once that is done you can use this custom cmdlet using the following commands in the script file

Add-PSSnapin NameWhichYoudefinedInTheNamePropertyOfinstallerFile -ErrorAction "Stop"

How to invoke/call custom cmdlet from another custom cmdlet in powershell

For example you have a requirement where you are writing custom cmdlet cmdLET1 which in turn needs to invoke cmdLET2.In such a scenario the challenge remains how to pass the parameters to the second cmdlet being invoked and also how exactly to invoke it.

Shown below is the sample code which shows how do we achieve such a scnerio

     PowerShell pShell = PowerShell.Create();
            Runspace runSpace = RunspaceFactory.CreateRunspace();
            runSpace.Open();
            Pipeline pipeline = Runspace.DefaultRunspace.CreateNestedPipeline();
            Command cmd = new Command("Add- cmdLET2");

            CommandParameter cmdPara1 = new CommandParameter("parameter1", value1);
            cmd.Parameters.Add(cmdPara1);

            CommandParameter cmdPara2 = new CommandParameter("parameter2", value2);
            cmd.Parameters.Add(cmdPara2);

            pipeline.Commands.Add(cmd);

            pShell.Commands.AddCommand("import-module").AddParameter("Name", "Add- cmdLET2");
            pipeline.Invoke();


The above code when called from cmdLET1 will invoke cmdLET2 with values passed in the CommandParameter’s

How to debug PowerShell custom Cmdlet project

In order to debug PowerShell go to the following path

Solution explorer à Right Click properties à debug

Here we need to configure the following three values

Start external program : mention the location of the powershell directory here usually it is “C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe”

Next define Command line argument : -noexit -command Add-PSSnapin XXXX.PowerShell (replace  XXXX.PowerShell with the value you have defined in the “Name” property of the installer file )


Finally define the Working Directory : This is location where your project is building and placing the dlls, 

Note : In some cases you may require to copy dll from this location to the the GAC of the server, therefore every time you make a change in your code you may be required to update the dlls in the GAC. You may also need to sign your assembly with a strong name in case the same has to be copied to GAC.