Particularly with SharePoint 2010, I have become a huge fan of Microsoft PowerShell. In addition to writing complex PowerShell scripts (.ps1 files), I have found it very useful to write my own C#-based PowerShell Cmdlets to use in my scripts.
This basic tutorial illustrates how to create a basic PowerShell Cmdlet with a couple of parameters. In the future, I will be adding addition posts about more indepth topics. However, this tutorial should get you started if you are new to writing PowerShell Cmdlets.
For this tutorial I am using Visual Studio 2010. In addition, you will need the PowerShell SDK installed (comes with the Windows 7 SDK if you have installed that instead).
-
In Visual Studio 2010, create a new Class Library project targeted to .NET Framework 3.5 (Visual C# > Windows > Class Library). OPTIONAL: For consistency, I recommend naming the project with the name of the actions. For instance, if you want to create a “Get-MyPsCmdlet” command, name the project “MyPsCmdlet”.
-
Delete the Class1.cs file included by default.
-
Add a reference to System.Management.Automation.dll (you will need to browse to the assembly at C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0).
-
In the Solution Explorer right-click the project name and select Add > Class.
-
Create a new class named with the command and the verb. For instance, for “Get-MyPsCmdlet” name your class file “MyPsCmdletGet.cs”.
-
Add “System.Management.Automation” in the usings statements and set the basetype of the class to Cmdlet as follows:
[csharp]using System;
using System.Management.Automation;namespace MyPsCmdlet
{
[Cmdlet(VerbsCommon.Get, “MyPsCmdlet”)]
public class MyPsCmdletGet : Cmdlet
{}
}[/csharp] -
Above the class declaration, you will notice “[Cmdlet(VerbsCommon.Get, “MyPsCmdlet”)]”. In these properties you can define the name, verb, default parameter set, etc., of the Cmdlet. Using the “Get” common verb and “MyPsCmdlet” will result in a command of “Get-MyPsCmdlet”. There are a number of common verb sets that you may use. For consistence with help documentation and localization, it is important to use a common verb whenever possible. If a common verb does not fit your needs, you can populate that value with a string of your choice.
Verb Sets:
- VerbsCommon
- VerbsCommunications
- VerbsData
- VerbsDiagnostic
- VerbsLifecycle
- VerbsOther
- VerbsSecurity
-
To add your code to run when the command is executed, simply override the “ProcessRecord()” method:
[csharp]using System;
using System.Management.Automation;namespace MyPsCmdlet
{
[Cmdlet(VerbsCommon.Get, “MyPsCmdlet”)]
public class MyPsCmdletGet : Cmdlet
{
protected override void ProcessRecord()
{
// Your code goes here
}
}
}[/csharp] -
In the Cmdlet you can write text to the console like any other console application with “Console.Write” or “Console.WriteLine”. However, most PowerShell Cmdlets return objects. Here we have a simple object named “MyObject” that we are returning to the console:
[csharp]using System;
using System.Management.Automation;namespace MyPsCmdlet
{
[Cmdlet(VerbsCommon.Get, “MyPsCmdlet”)]
public class MyPsCmdletGet : Cmdlet
{
protected override void ProcessRecord()
{
var myobj = new MyObject()
{
Name = “My Object”,
Created = DateTime.Now
};WriteObject(myobj);
}
}public class MyObject
{
public string Name { get; set; }
public DateTime Created { get; set; }
}
}[/csharp] -
With PowerShell Cmdlets you can add parameters of just about any .NET type. In this instance:
- “public SwitchParameter CreatedTomorrow” is used to define a flag parameter for the Cmdlet. There is no value passed, it simply exists or does not exists. For example: “Get-MyPsCmdlet -CreatedTomorrow”.
- “public MyObject MyObj” is used to create a parameter that requires an object with “MyObject” as the type. For example: “$myobj = Get-MyPsCmdlet”, then “Get-MyPsCmdlet -MyObj $myobj”.
- “public string ObjectName” is used to create a parameter that requires a string. For values with spaces, use quotations around the string.
[csharp]using System;
using System.Management.Automation;namespace MyPsCmdlet
{
[Cmdlet(VerbsCommon.Get, “MyPsCmdlet”)]
public class MyPsCmdletGet : Cmdlet
{
[Parameter(Mandatory = false)]
public SwitchParameter CreatedTomorrow;[Parameter(Mandatory = false)]
public MyObject MyObj;[Parameter(Mandatory = false)]
public string ObjectName;protected override void ProcessRecord()
{
var myobj = new MyObject()
{
Name = “My Object”,
Created = DateTime.Now
};if (CreatedTomorrow.IsPresent)
myobj.Created = DateTime.Now.AddDays(1);if (!string.IsNullOrEmpty(ObjectName))
myobj.Name = ObjectName;if (MyObj != null)
myobj = MyObj;WriteObject(myobj);
}
}public class MyObject
{
public string Name { get; set; }
public DateTime Created { get; set; }
}
}[/csharp] -
Now that we have our Cmdlet writen, we can build and run it. In Visual Studio, build the project.
-
Open PowerShell.
-
Import the assembly using Import-Module:
[powershell]Import-Module C:\Files\Projects\MyPsCmdlet\MyPsCmdlet\bin\Debug\MyPsCmdlet.dll[/powershell]
-
Run the Cmdlet:
[powershell]Get-MyPsCmdlet[/powershell]
That’s it. You now have a fully functional PowerShell Cmdlet. Stay tuned for more advanced PowerShell Cmdlet posts.