@RSS description Specify the OutputType attribute for your cmdlets

Does this site look plain?

This site uses advanced css techniques

Many parts of the .NET ecosystem support [Attribute] markers of many types, and the cmdlet is no exception. We're all familiar with the Cmdlet attribute itself, but one often omitted is OutputType. This optional attribute is a description which types of objects might be written to the output pipeline.

To illustrate, we'll consult our Session State Intro page and create a new cmdlet that will report the internal session state object to the user:

[Cmdlet(VerbsCommon.Get, "MyState")]
[OutputType(typeof(MyState))]
public class Get_MyState : MyCmdlet
{
    protected override void ProcessRecord()
    {
        base.ProcessRecord();

        WriteObject( getState() );
    }
}

The [OutputType] attribute accepts type parameters in the form of literal string type names—[OutputType("MyState")]—or via the typeof() operator—[OutputType(typeof(MyState))]. I prefer the latter because of the stronger type checking, as well as being subject to renaming via refactoring.

Of course, even if you use the typeof method, if the cmdlet name itself includes the class name in the noun part, that has to be updated by hand after refactoring.

Not hugely obvious from the documentation, but this attribute can take multiple types if the cmdlet can write them, though the multiples have to all be the string flavor or the typeof flavor: no mixing and matching.

It's not clear that the order of types within the attribute matter, nor whether they should appear above or below the actual [Cmdlet()] attribute itself.

Helpfully, this attribute can be applied to PowerShell functions as well. Type names can be provided as strings, or with actual type names surrounded with [...]. Example: [OutputType([string])].

What I don't know: while researching this paper, I discovered that ParameterSetName is supported part of this attribute, and that multiple [OutputType()] attributes can be provided, each with a different parameter set.

I haven't yet used this enough to write about it properly.

Why bother?

As noted, none of this is required, or enforced if provided, so why is this here at all? My research suggests three benefits to these annotations:

  1. It's just good documentation; letting the reader know the output type is just being helpful (as long as the types are correct).
  2. It's an aid to Intellisense, including in PowerShell scripting editors that can honor this attribute both from the compiled DLL, as well as functions written in PowerShell itself.
  3. The Get-Help cmdlet can extract and report this metadata.

I have only just started adding these attributes in my projects.


First published: 2019/07/20

The excellent icons on this page were made by Freepik from www.flaticon.com, and are licensed by CC 3.0 BY