Advanced Functions Part 1: Cmdlets From Scripts

Have you ever wished you could write a "real" cmdlet without having to crank up Visual Studio and learn Visual Basic or C#? If so, then PowerShell's "advanced functions," or "script cmdlets," are just what you're looking for.

Don Jones

May 14, 2010

6 Min Read
ITPro Today logo in a gray background | ITPro Today

Have you ever wished you could write a "real" cmdlet without having to crank up Visual Studio and learn Visual Basic or C#? If so, then PowerShell's "advanced functions," or "script cmdlets," are just what you're looking for.


Byt the way, this will be a short series of articles - find them all on my Windows IT Pro home page.


Cmdlets have a couple of distinguishing characteristics. First, they have parameters that can be referred to by name, can accept specific types of input, and that can bind pipeline input. Those parameters can have default values, and they can also be positional, meaning you can omit the parameter name and just provide the input value. In fact, most of what makes a cmdlet special is in the way those parameters work, and in how flexible they are.


The other characteristic is that cmdlets accept pipeline input, and produce pipeline output. A normal, non-advanced function can do that - but not in quite the same neat way that an advanced function can.


Here's a complete advanced function for your consideration:


01.function Get-ComputerDetails {

02.    [CmdletBinding()]

03.    param (

04.        [parameter(Mandatory=$true,ValueFromPipeline=$true)]

05.        [string[]]$computername

06.    )

07.    BEGIN {}

08.    PROCESS {

09.        # get the OS

10.        $os = get-wmiobject win32_operatingsystem -computername $computername

11.         

12.        # create a new object

13.        $obj = new-object psobject

14.         

15.        # add properties - note that our capitalization

16.        # of the property names will be retained

17.        $obj | add-member noteproperty ComputerName $computername

18.        $obj | add-member noteproperty BuildNumber ($os.buildnumber)

19.        $obj | add-member noteproperty SPVersion ($os.servicepackmajorversion)

20.                 

21.        # get the BIOS

22.        $bios = get-wmiobject win32_bios -computername $computername

23.        $obj | add-member noteproperty BIOSSerial ($bios.serialnumber)

24.         

25.        write $obj

26.    }

27.    END {}

28.}


Let's walk through this. It all begins with the function's declaration and its name, Get-ComputerDetails. Next is a special attribute, [CmdletBinding()], that tells the shell this is an advanced function that will be declaring cmdlet-style parameters. After that are the actual parameters, and I've declared one of them in the param() block. That parameter, -computerName, is mandatory. It accepts pipeline input ByValue, and it is of the value string. The "String[]" tells me that it can accept one or more values.


Next is the BEGIN block, which is empty. Normally, whatever's in there would execute first - but since it's empty, we'll move on.


Next up is the PROCESS block. This is going to execute one time for every object piped into the cmdlet, or every object assigned to a pipeline-bound parameter - like -computerName. Notice that the code uses $computerName, not the more obscure $_ placeholder, to access the piped-in data. Also note that the output is being written to the pipeline by using Write-Output.


It all wraps up with an END block, which would normally run last after PROCESS was finished. It's empty, so we're done.


You could run this function in many ways:


Get-ComputerDetails -comp localhost

"server1","server2" | Get-ComputerDetails

Get-Content servers.txt | Get-ComputerDetails


The cmdlet - sorry, the function - has all this flexibility because it's got cmdlet-style parameters. There are a few other neat things you can do with this kind of function. For example, you can set up basic data validation on parameters, provide default values, and more - run help *advanced* in PowerShell for a list of help topics related to these advanced functions.

Sign up for the ITPro Today newsletter
Stay on top of the IT universe with commentary, news analysis, how-to's, and tips delivered to your inbox daily.

You May Also Like