Cmdlets vs Functions

A discussion came up recently in an internal mailing list about the difference between Cmdlets and Functions. What was most interesting was how many hard and fast distinctions and rules came out of the discussion, even though those distinctions don’t really exist.

The key point is that there really isn’t a hard and fast philosophical distinction between cmdlets and functions.

Most differences largely exist because of setup, installation, and supported features. In general, cmdlets (and snapins) are the best way to distribute features, while functions are the easiest way to implement them.

  • It is currently much easier for ISVs and developers to package and deploy cmdlets than it is to package libraries of functions or scripts.
  • It is currently easier to write and package help for cmdlets.
  • Cmdlets are written in a compiled .NET language, while functions (and scripts) are written in the PowerShell language. On the plus side, this makes certain developer tasks (such as P/Invoke calls, working with generics) much easier in a cmdlet. On the minus side, this makes you pay the ‘compilation’ tax — making it slower to implement and evaluate new functionality.
  • In V1,  Cmdlets provide the author a great deal of support for parameter validation, and tentative processing (-WhatIf, -Confirm.) This is an implementation artifact, though, and could go away in the future.
  • [Various technical points] Functions support scoping, different naming guidelines, management through the function drive, etc. See your favourite scripting reference for these details.

So, really, the differences are really a function of water finding its level -- people tend to one or the other based on what we've currently made easiest. Aside from the implementation language, all of these factors are transient, though, and could change at any time.

2 Responses to “Cmdlets vs Functions”

  1. Jim Vierra writes:

    I fell into the same quagmire but was extracted by the realization that functions can be built to easily handle teh "begin", "process" and "end" states of a pipeline. This made it clear that a function can and is intended to be used to build CmdLets.

    A filter is a special case of a function.

    Functions used as CmdLets should be named using "verb/noun" naing standards and functions and filters not designed as CmdLets should probably not use verb/noun.

    Functions are a good way to begin the design of a compiled CmdLet as it is quicker to test different ideas and approaches in some cases.

    You blog continues to be very useful and enlightening.

  2. agostinox writes:

    Since this distinction might trigger an abstract discussion that doesn’t really gives real information, let me provide a real use case in which the two terms are used with a different meaning.

    PS C:\Users\agox> get-command mkdir
    CommandType Name
    ———– —-
    Function mkdir
    PS C:\Users\agox> get-command new-item
    CommandType Name
    ———– —-
    Cmdlet New-Item

    Powershell uses the two terms with a special meaning.
    I think it’s the “compiled” feature to make the difference, but I’m not sure.

Leave a Reply